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","sourcesContent":["import { LRUCache } from 'lru-cache'\nimport { posix, win32 } from 'node:path'\n\nimport { fileURLToPath } from 'node:url'\n\nimport {\n  lstatSync,\n  readdir as readdirCB,\n  readdirSync,\n  readlinkSync,\n  realpathSync as rps,\n} from 'fs'\nimport * as actualFS from 'node:fs'\n\nconst realpathSync = rps.native\n// TODO: test perf of fs/promises realpath vs realpathCB,\n// since the promises one uses realpath.native\n\nimport { lstat, readdir, readlink, realpath } from 'node:fs/promises'\n\nimport { Minipass } from 'minipass'\nimport type { Dirent, Stats } from 'node:fs'\n\n/**\n * An object that will be used to override the default `fs`\n * methods.  Any methods that are not overridden will use Node's\n * built-in implementations.\n *\n * - lstatSync\n * - readdir (callback `withFileTypes` Dirent variant, used for\n *   readdirCB and most walks)\n * - readdirSync\n * - readlinkSync\n * - realpathSync\n * - promises: Object containing the following async methods:\n *   - lstat\n *   - readdir (Dirent variant only)\n *   - readlink\n *   - realpath\n */\nexport interface FSOption {\n  lstatSync?: (path: string) => Stats\n  readdir?: (\n    path: string,\n    options: { withFileTypes: true },\n    cb: (er: NodeJS.ErrnoException | null, entries?: Dirent[]) => any,\n  ) => void\n  readdirSync?: (\n    path: string,\n    options: { withFileTypes: true },\n  ) => Dirent[]\n  readlinkSync?: (path: string) => string\n  realpathSync?: (path: string) => string\n  promises?: {\n    lstat?: (path: string) => Promise<Stats>\n    readdir?: (\n      path: string,\n      options: { withFileTypes: true },\n    ) => Promise<Dirent[]>\n    readlink?: (path: string) => Promise<string>\n    realpath?: (path: string) => Promise<string>\n    [k: string]: any\n  }\n  [k: string]: any\n}\n\ninterface FSValue {\n  lstatSync: (path: string) => Stats\n  readdir: (\n    path: string,\n    options: { withFileTypes: true },\n    cb: (er: NodeJS.ErrnoException | null, entries?: Dirent[]) => any,\n  ) => void\n  readdirSync: (path: string, options: { withFileTypes: true }) => Dirent[]\n  readlinkSync: (path: string) => string\n  realpathSync: (path: string) => string\n  promises: {\n    lstat: (path: string) => Promise<Stats>\n    readdir: (\n      path: string,\n      options: { withFileTypes: true },\n    ) => Promise<Dirent[]>\n    readlink: (path: string) => Promise<string>\n    realpath: (path: string) => Promise<string>\n    [k: string]: any\n  }\n  [k: string]: any\n}\n\nconst defaultFS: FSValue = {\n  lstatSync,\n  readdir: readdirCB,\n  readdirSync,\n  readlinkSync,\n  realpathSync,\n  promises: {\n    lstat,\n    readdir,\n    readlink,\n    realpath,\n  },\n}\n\n// if they just gave us require('fs') then use our default\nconst fsFromOption = (fsOption?: FSOption): FSValue =>\n  !fsOption || fsOption === defaultFS || fsOption === actualFS ?\n    defaultFS\n  : {\n      ...defaultFS,\n      ...fsOption,\n      promises: {\n        ...defaultFS.promises,\n        ...(fsOption.promises || {}),\n      },\n    }\n\n// turn something like //?/c:/ into c:\\\nconst uncDriveRegexp = /^\\\\\\\\\\?\\\\([a-z]:)\\\\?$/i\nconst uncToDrive = (rootPath: string): string =>\n  rootPath.replace(/\\//g, '\\\\').replace(uncDriveRegexp, '$1\\\\')\n\n// windows paths are separated by either / or \\\nconst eitherSep = /[\\\\\\/]/\n\nconst UNKNOWN = 0 // may not even exist, for all we know\nconst IFIFO = 0b0001\nconst IFCHR = 0b0010\nconst IFDIR = 0b0100\nconst IFBLK = 0b0110\nconst IFREG = 0b1000\nconst IFLNK = 0b1010\nconst IFSOCK = 0b1100\nconst IFMT = 0b1111\n\nexport type Type =\n  | 'Unknown'\n  | 'FIFO'\n  | 'CharacterDevice'\n  | 'Directory'\n  | 'BlockDevice'\n  | 'File'\n  | 'SymbolicLink'\n  | 'Socket'\n\n// mask to unset low 4 bits\nconst IFMT_UNKNOWN = ~IFMT\n\n// set after successfully calling readdir() and getting entries.\nconst READDIR_CALLED = 0b0000_0001_0000\n// set after a successful lstat()\nconst LSTAT_CALLED = 0b0000_0010_0000\n// set if an entry (or one of its parents) is definitely not a dir\nconst ENOTDIR = 0b0000_0100_0000\n// set if an entry (or one of its parents) does not exist\n// (can also be set on lstat errors like EACCES or ENAMETOOLONG)\nconst ENOENT = 0b0000_1000_0000\n// cannot have child entries -- also verify &IFMT is either IFDIR or IFLNK\n// set if we fail to readlink\nconst ENOREADLINK = 0b0001_0000_0000\n// set if we know realpath() will fail\nconst ENOREALPATH = 0b0010_0000_0000\n\nconst ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH\nconst TYPEMASK = 0b0011_1111_1111\n\nconst entToType = (s: Dirent | Stats) =>\n  s.isFile() ? IFREG\n  : s.isDirectory() ? IFDIR\n  : s.isSymbolicLink() ? IFLNK\n  : s.isCharacterDevice() ? IFCHR\n  : s.isBlockDevice() ? IFBLK\n  : s.isSocket() ? IFSOCK\n  : s.isFIFO() ? IFIFO\n  : UNKNOWN\n\n// normalize unicode path names\nconst normalizeCache = new Map<string, string>()\nconst normalize = (s: string) => {\n  const c = normalizeCache.get(s)\n  if (c) return c\n  const n = s.normalize('NFKD')\n  normalizeCache.set(s, n)\n  return n\n}\n\nconst normalizeNocaseCache = new Map<string, string>()\nconst normalizeNocase = (s: string) => {\n  const c = normalizeNocaseCache.get(s)\n  if (c) return c\n  const n = normalize(s.toLowerCase())\n  normalizeNocaseCache.set(s, n)\n  return n\n}\n\n/**\n * Options that may be provided to the Path constructor\n */\nexport interface PathOpts {\n  fullpath?: string\n  relative?: string\n  relativePosix?: string\n  parent?: PathBase\n  /**\n   * See {@link FSOption}\n   */\n  fs?: FSOption\n}\n\n/**\n * An LRUCache for storing resolved path strings or Path objects.\n * @internal\n */\nexport class ResolveCache extends LRUCache<string, string> {\n  constructor() {\n    super({ max: 256 })\n  }\n}\n\n// In order to prevent blowing out the js heap by allocating hundreds of\n// thousands of Path entries when walking extremely large trees, the \"children\"\n// in this tree are represented by storing an array of Path entries in an\n// LRUCache, indexed by the parent.  At any time, Path.children() may return an\n// empty array, indicating that it doesn't know about any of its children, and\n// thus has to rebuild that cache.  This is fine, it just means that we don't\n// benefit as much from having the cached entries, but huge directory walks\n// don't blow out the stack, and smaller ones are still as fast as possible.\n//\n//It does impose some complexity when building up the readdir data, because we\n//need to pass a reference to the children array that we started with.\n\n/**\n * an LRUCache for storing child entries.\n * @internal\n */\nexport class ChildrenCache extends LRUCache<PathBase, Children> {\n  constructor(maxSize: number = 16 * 1024) {\n    super({\n      maxSize,\n      // parent + children\n      sizeCalculation: a => a.length + 1,\n    })\n  }\n}\n\n/**\n * Array of Path objects, plus a marker indicating the first provisional entry\n *\n * @internal\n */\nexport type Children = PathBase[] & { provisional: number }\n\nconst setAsCwd = Symbol('PathScurry setAsCwd')\n\n/**\n * Path objects are sort of like a super-powered\n * {@link https://nodejs.org/docs/latest/api/fs.html#class-fsdirent fs.Dirent}\n *\n * Each one represents a single filesystem entry on disk, which may or may not\n * exist. It includes methods for reading various types of information via\n * lstat, readlink, and readdir, and caches all information to the greatest\n * degree possible.\n *\n * Note that fs operations that would normally throw will instead return an\n * \"empty\" value. This is in order to prevent excessive overhead from error\n * stack traces.\n */\nexport abstract class PathBase implements Dirent {\n  /**\n   * the basename of this path\n   *\n   * **Important**: *always* test the path name against any test string\n   * usingthe {@link isNamed} method, and not by directly comparing this\n   * string. Otherwise, unicode path strings that the system sees as identical\n   * will not be properly treated as the same path, leading to incorrect\n   * behavior and possible security issues.\n   */\n  name: string\n  /**\n   * the Path entry corresponding to the path root.\n   *\n   * @internal\n   */\n  root: PathBase\n  /**\n   * All roots found within the current PathScurry family\n   *\n   * @internal\n   */\n  roots: { [k: string]: PathBase }\n  /**\n   * a reference to the parent path, or undefined in the case of root entries\n   *\n   * @internal\n   */\n  parent?: PathBase\n  /**\n   * boolean indicating whether paths are compared case-insensitively\n   * @internal\n   */\n  nocase: boolean\n\n  /**\n   * boolean indicating that this path is the current working directory\n   * of the PathScurry collection that contains it.\n   */\n  isCWD: boolean = false\n\n  /**\n   * the string or regexp used to split paths. On posix, it is `'/'`, and on\n   * windows it is a RegExp matching either `'/'` or `'\\\\'`\n   */\n  abstract splitSep: string | RegExp\n  /**\n   * The path separator string to use when joining paths\n   */\n  abstract sep: string\n\n  // potential default fs override\n  #fs: FSValue\n\n  // Stats fields\n  #dev?: number\n  get dev() {\n    return this.#dev\n  }\n  #mode?: number\n  get mode() {\n    return this.#mode\n  }\n  #nlink?: number\n  get nlink() {\n    return this.#nlink\n  }\n  #uid?: number\n  get uid() {\n    return this.#uid\n  }\n  #gid?: number\n  get gid() {\n    return this.#gid\n  }\n  #rdev?: number\n  get rdev() {\n    return this.#rdev\n  }\n  #blksize?: number\n  get blksize() {\n    return this.#blksize\n  }\n  #ino?: number\n  get ino() {\n    return this.#ino\n  }\n  #size?: number\n  get size() {\n    return this.#size\n  }\n  #blocks?: number\n  get blocks() {\n    return this.#blocks\n  }\n  #atimeMs?: number\n  get atimeMs() {\n    return this.#atimeMs\n  }\n  #mtimeMs?: number\n  get mtimeMs() {\n    return this.#mtimeMs\n  }\n  #ctimeMs?: number\n  get ctimeMs() {\n    return this.#ctimeMs\n  }\n  #birthtimeMs?: number\n  get birthtimeMs() {\n    return this.#birthtimeMs\n  }\n  #atime?: Date\n  get atime() {\n    return this.#atime\n  }\n  #mtime?: Date\n  get mtime() {\n    return this.#mtime\n  }\n  #ctime?: Date\n  get ctime() {\n    return this.#ctime\n  }\n  #birthtime?: Date\n  get birthtime() {\n    return this.#birthtime\n  }\n\n  #matchName: string\n  #depth?: number\n  #fullpath?: string\n  #fullpathPosix?: string\n  #relative?: string\n  #relativePosix?: string\n  #type: number\n  #children: ChildrenCache\n  #linkTarget?: PathBase\n  #realpath?: PathBase\n\n  /**\n   * This property is for compatibility with the Dirent class as of\n   * Node v20, where Dirent['parentPath'] refers to the path of the\n   * directory that was passed to readdir. For root entries, it's the path\n   * to the entry itself.\n   */\n  get parentPath(): string {\n    return (this.parent || this).fullpath()\n  }\n\n  /**\n   * Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively,\n   * this property refers to the *parent* path, not the path object itself.\n   */\n  get path(): string {\n    return this.parentPath\n  }\n\n  /**\n   * Do not create new Path objects directly.  They should always be accessed\n   * via the PathScurry class or other methods on the Path class.\n   *\n   * @internal\n   */\n  constructor(\n    name: string,\n    type: number = UNKNOWN,\n    root: PathBase | undefined,\n    roots: { [k: string]: PathBase },\n    nocase: boolean,\n    children: ChildrenCache,\n    opts: PathOpts,\n  ) {\n    this.name = name\n    this.#matchName = nocase ? normalizeNocase(name) : normalize(name)\n    this.#type = type & TYPEMASK\n    this.nocase = nocase\n    this.roots = roots\n    this.root = root || this\n    this.#children = children\n    this.#fullpath = opts.fullpath\n    this.#relative = opts.relative\n    this.#relativePosix = opts.relativePosix\n    this.parent = opts.parent\n    if (this.parent) {\n      this.#fs = this.parent.#fs\n    } else {\n      this.#fs = fsFromOption(opts.fs)\n    }\n  }\n\n  /**\n   * Returns the depth of the Path object from its root.\n   *\n   * For example, a path at `/foo/bar` would have a depth of 2.\n   */\n  depth(): number {\n    if (this.#depth !== undefined) return this.#depth\n    if (!this.parent) return (this.#depth = 0)\n    return (this.#depth = this.parent.depth() + 1)\n  }\n\n  /**\n   * @internal\n   */\n  abstract getRootString(path: string): string\n  /**\n   * @internal\n   */\n  abstract getRoot(rootPath: string): PathBase\n  /**\n   * @internal\n   */\n  abstract newChild(name: string, type?: number, opts?: PathOpts): PathBase\n\n  /**\n   * @internal\n   */\n  childrenCache() {\n    return this.#children\n  }\n\n  /**\n   * Get the Path object referenced by the string path, resolved from this Path\n   */\n  resolve(path?: string): PathBase {\n    if (!path) {\n      return this\n    }\n    const rootPath = this.getRootString(path)\n    const dir = path.substring(rootPath.length)\n    const dirParts = dir.split(this.splitSep)\n    const result: PathBase =\n      rootPath ?\n        this.getRoot(rootPath).#resolveParts(dirParts)\n      : this.#resolveParts(dirParts)\n    return result\n  }\n\n  #resolveParts(dirParts: string[]) {\n    let p: PathBase = this\n    for (const part of dirParts) {\n      p = p.child(part)\n    }\n    return p\n  }\n\n  /**\n   * Returns the cached children Path objects, if still available.  If they\n   * have fallen out of the cache, then returns an empty array, and resets the\n   * READDIR_CALLED bit, so that future calls to readdir() will require an fs\n   * lookup.\n   *\n   * @internal\n   */\n  children(): Children {\n    const cached = this.#children.get(this)\n    if (cached) {\n      return cached\n    }\n    const children: Children = Object.assign([], { provisional: 0 })\n    this.#children.set(this, children)\n    this.#type &= ~READDIR_CALLED\n    return children\n  }\n\n  /**\n   * Resolves a path portion and returns or creates the child Path.\n   *\n   * Returns `this` if pathPart is `''` or `'.'`, or `parent` if pathPart is\n   * `'..'`.\n   *\n   * This should not be called directly.  If `pathPart` contains any path\n   * separators, it will lead to unsafe undefined behavior.\n   *\n   * Use `Path.resolve()` instead.\n   *\n   * @internal\n   */\n  child(pathPart: string, opts?: PathOpts): PathBase {\n    if (pathPart === '' || pathPart === '.') {\n      return this\n    }\n    if (pathPart === '..') {\n      return this.parent || this\n    }\n\n    // find the child\n    const children = this.children()\n    const name =\n      this.nocase ? normalizeNocase(pathPart) : normalize(pathPart)\n    for (const p of children) {\n      if (p.#matchName === name) {\n        return p\n      }\n    }\n\n    // didn't find it, create provisional child, since it might not\n    // actually exist.  If we know the parent isn't a dir, then\n    // in fact it CAN'T exist.\n    const s = this.parent ? this.sep : ''\n    const fullpath =\n      this.#fullpath ? this.#fullpath + s + pathPart : undefined\n    const pchild = this.newChild(pathPart, UNKNOWN, {\n      ...opts,\n      parent: this,\n      fullpath,\n    })\n\n    if (!this.canReaddir()) {\n      pchild.#type |= ENOENT\n    }\n\n    // don't have to update provisional, because if we have real children,\n    // then provisional is set to children.length, otherwise a lower number\n    children.push(pchild)\n    return pchild\n  }\n\n  /**\n   * The relative path from the cwd. If it does not share an ancestor with\n   * the cwd, then this ends up being equivalent to the fullpath()\n   */\n  relative(): string {\n    if (this.isCWD) return ''\n    if (this.#relative !== undefined) {\n      return this.#relative\n    }\n    const name = this.name\n    const p = this.parent\n    if (!p) {\n      return (this.#relative = this.name)\n    }\n    const pv = p.relative()\n    return pv + (!pv || !p.parent ? '' : this.sep) + name\n  }\n\n  /**\n   * The relative path from the cwd, using / as the path separator.\n   * If it does not share an ancestor with\n   * the cwd, then this ends up being equivalent to the fullpathPosix()\n   * On posix systems, this is identical to relative().\n   */\n  relativePosix(): string {\n    if (this.sep === '/') return this.relative()\n    if (this.isCWD) return ''\n    if (this.#relativePosix !== undefined) return this.#relativePosix\n    const name = this.name\n    const p = this.parent\n    if (!p) {\n      return (this.#relativePosix = this.fullpathPosix())\n    }\n    const pv = p.relativePosix()\n    return pv + (!pv || !p.parent ? '' : '/') + name\n  }\n\n  /**\n   * The fully resolved path string for this Path entry\n   */\n  fullpath(): string {\n    if (this.#fullpath !== undefined) {\n      return this.#fullpath\n    }\n    const name = this.name\n    const p = this.parent\n    if (!p) {\n      return (this.#fullpath = this.name)\n    }\n    const pv = p.fullpath()\n    const fp = pv + (!p.parent ? '' : this.sep) + name\n    return (this.#fullpath = fp)\n  }\n\n  /**\n   * On platforms other than windows, this is identical to fullpath.\n   *\n   * On windows, this is overridden to return the forward-slash form of the\n   * full UNC path.\n   */\n  fullpathPosix(): string {\n    if (this.#fullpathPosix !== undefined) return this.#fullpathPosix\n    if (this.sep === '/') return (this.#fullpathPosix = this.fullpath())\n    if (!this.parent) {\n      const p = this.fullpath().replace(/\\\\/g, '/')\n      if (/^[a-z]:\\//i.test(p)) {\n        return (this.#fullpathPosix = `//?/${p}`)\n      } else {\n        return (this.#fullpathPosix = p)\n      }\n    }\n    const p = this.parent\n    const pfpp = p.fullpathPosix()\n    const fpp = pfpp + (!pfpp || !p.parent ? '' : '/') + this.name\n    return (this.#fullpathPosix = fpp)\n  }\n\n  /**\n   * Is the Path of an unknown type?\n   *\n   * Note that we might know *something* about it if there has been a previous\n   * filesystem operation, for example that it does not exist, or is not a\n   * link, or whether it has child entries.\n   */\n  isUnknown(): boolean {\n    return (this.#type & IFMT) === UNKNOWN\n  }\n\n  isType(type: Type): boolean {\n    return this[`is${type}`]()\n  }\n\n  getType(): Type {\n    return (\n      this.isUnknown() ? 'Unknown'\n      : this.isDirectory() ? 'Directory'\n      : this.isFile() ? 'File'\n      : this.isSymbolicLink() ? 'SymbolicLink'\n      : this.isFIFO() ? 'FIFO'\n      : this.isCharacterDevice() ? 'CharacterDevice'\n      : this.isBlockDevice() ? 'BlockDevice'\n      : /* c8 ignore start */ this.isSocket() ? 'Socket'\n      : 'Unknown'\n    )\n    /* c8 ignore stop */\n  }\n\n  /**\n   * Is the Path a regular file?\n   */\n  isFile(): boolean {\n    return (this.#type & IFMT) === IFREG\n  }\n\n  /**\n   * Is the Path a directory?\n   */\n  isDirectory(): boolean {\n    return (this.#type & IFMT) === IFDIR\n  }\n\n  /**\n   * Is the path a character device?\n   */\n  isCharacterDevice(): boolean {\n    return (this.#type & IFMT) === IFCHR\n  }\n\n  /**\n   * Is the path a block device?\n   */\n  isBlockDevice(): boolean {\n    return (this.#type & IFMT) === IFBLK\n  }\n\n  /**\n   * Is the path a FIFO pipe?\n   */\n  isFIFO(): boolean {\n    return (this.#type & IFMT) === IFIFO\n  }\n\n  /**\n   * Is the path a socket?\n   */\n  isSocket(): boolean {\n    return (this.#type & IFMT) === IFSOCK\n  }\n\n  /**\n   * Is the path a symbolic link?\n   */\n  isSymbolicLink(): boolean {\n    return (this.#type & IFLNK) === IFLNK\n  }\n\n  /**\n   * Return the entry if it has been subject of a successful lstat, or\n   * undefined otherwise.\n   *\n   * Does not read the filesystem, so an undefined result *could* simply\n   * mean that we haven't called lstat on it.\n   */\n  lstatCached(): PathBase | undefined {\n    return this.#type & LSTAT_CALLED ? this : undefined\n  }\n\n  /**\n   * Return the cached link target if the entry has been the subject of a\n   * successful readlink, or undefined otherwise.\n   *\n   * Does not read the filesystem, so an undefined result *could* just mean we\n   * don't have any cached data. Only use it if you are very sure that a\n   * readlink() has been called at some point.\n   */\n  readlinkCached(): PathBase | undefined {\n    return this.#linkTarget\n  }\n\n  /**\n   * Returns the cached realpath target if the entry has been the subject\n   * of a successful realpath, or undefined otherwise.\n   *\n   * Does not read the filesystem, so an undefined result *could* just mean we\n   * don't have any cached data. Only use it if you are very sure that a\n   * realpath() has been called at some point.\n   */\n  realpathCached(): PathBase | undefined {\n    return this.#realpath\n  }\n\n  /**\n   * Returns the cached child Path entries array if the entry has been the\n   * subject of a successful readdir(), or [] otherwise.\n   *\n   * Does not read the filesystem, so an empty array *could* just mean we\n   * don't have any cached data. Only use it if you are very sure that a\n   * readdir() has been called recently enough to still be valid.\n   */\n  readdirCached(): PathBase[] {\n    const children = this.children()\n    return children.slice(0, children.provisional)\n  }\n\n  /**\n   * Return true if it's worth trying to readlink.  Ie, we don't (yet) have\n   * any indication that readlink will definitely fail.\n   *\n   * Returns false if the path is known to not be a symlink, if a previous\n   * readlink failed, or if the entry does not exist.\n   */\n  canReadlink(): boolean {\n    if (this.#linkTarget) return true\n    if (!this.parent) return false\n    // cases where it cannot possibly succeed\n    const ifmt = this.#type & IFMT\n    return !(\n      (ifmt !== UNKNOWN && ifmt !== IFLNK) ||\n      this.#type & ENOREADLINK ||\n      this.#type & ENOENT\n    )\n  }\n\n  /**\n   * Return true if readdir has previously been successfully called on this\n   * path, indicating that cachedReaddir() is likely valid.\n   */\n  calledReaddir(): boolean {\n    return !!(this.#type & READDIR_CALLED)\n  }\n\n  /**\n   * Returns true if the path is known to not exist. That is, a previous lstat\n   * or readdir failed to verify its existence when that would have been\n   * expected, or a parent entry was marked either enoent or enotdir.\n   */\n  isENOENT(): boolean {\n    return !!(this.#type & ENOENT)\n  }\n\n  /**\n   * Return true if the path is a match for the given path name.  This handles\n   * case sensitivity and unicode normalization.\n   *\n   * Note: even on case-sensitive systems, it is **not** safe to test the\n   * equality of the `.name` property to determine whether a given pathname\n   * matches, due to unicode normalization mismatches.\n   *\n   * Always use this method instead of testing the `path.name` property\n   * directly.\n   */\n  isNamed(n: string): boolean {\n    return !this.nocase ?\n        this.#matchName === normalize(n)\n      : this.#matchName === normalizeNocase(n)\n  }\n\n  /**\n   * Return the Path object corresponding to the target of a symbolic link.\n   *\n   * If the Path is not a symbolic link, or if the readlink call fails for any\n   * reason, `undefined` is returned.\n   *\n   * Result is cached, and thus may be outdated if the filesystem is mutated.\n   */\n  async readlink(): Promise<PathBase | undefined> {\n    const target = this.#linkTarget\n    if (target) {\n      return target\n    }\n    if (!this.canReadlink()) {\n      return undefined\n    }\n    /* c8 ignore start */\n    // already covered by the canReadlink test, here for ts grumples\n    if (!this.parent) {\n      return undefined\n    }\n    /* c8 ignore stop */\n    try {\n      const read = await this.#fs.promises.readlink(this.fullpath())\n      const linkTarget = (await this.parent.realpath())?.resolve(read)\n      if (linkTarget) {\n        return (this.#linkTarget = linkTarget)\n      }\n    } catch (er) {\n      this.#readlinkFail((er as NodeJS.ErrnoException).code)\n      return undefined\n    }\n  }\n\n  /**\n   * Synchronous {@link PathBase.readlink}\n   */\n  readlinkSync(): PathBase | undefined {\n    const target = this.#linkTarget\n    if (target) {\n      return target\n    }\n    if (!this.canReadlink()) {\n      return undefined\n    }\n    /* c8 ignore start */\n    // already covered by the canReadlink test, here for ts grumples\n    if (!this.parent) {\n      return undefined\n    }\n    /* c8 ignore stop */\n    try {\n      const read = this.#fs.readlinkSync(this.fullpath())\n      const linkTarget = this.parent.realpathSync()?.resolve(read)\n      if (linkTarget) {\n        return (this.#linkTarget = linkTarget)\n      }\n    } catch (er) {\n      this.#readlinkFail((er as NodeJS.ErrnoException).code)\n      return undefined\n    }\n  }\n\n  #readdirSuccess(children: Children) {\n    // succeeded, mark readdir called bit\n    this.#type |= READDIR_CALLED\n    // mark all remaining provisional children as ENOENT\n    for (let p = children.provisional; p < children.length; p++) {\n      const c = children[p]\n      if (c) c.#markENOENT()\n    }\n  }\n\n  #markENOENT() {\n    // mark as UNKNOWN and ENOENT\n    if (this.#type & ENOENT) return\n    this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN\n    this.#markChildrenENOENT()\n  }\n\n  #markChildrenENOENT() {\n    // all children are provisional and do not exist\n    const children = this.children()\n    children.provisional = 0\n    for (const p of children) {\n      p.#markENOENT()\n    }\n  }\n\n  #markENOREALPATH() {\n    this.#type |= ENOREALPATH\n    this.#markENOTDIR()\n  }\n\n  // save the information when we know the entry is not a dir\n  #markENOTDIR() {\n    // entry is not a directory, so any children can't exist.\n    // this *should* be impossible, since any children created\n    // after it's been marked ENOTDIR should be marked ENOENT,\n    // so it won't even get to this point.\n    /* c8 ignore start */\n    if (this.#type & ENOTDIR) return\n    /* c8 ignore stop */\n    let t = this.#type\n    // this could happen if we stat a dir, then delete it,\n    // then try to read it or one of its children.\n    if ((t & IFMT) === IFDIR) t &= IFMT_UNKNOWN\n    this.#type = t | ENOTDIR\n    this.#markChildrenENOENT()\n  }\n\n  #readdirFail(code: string = '') {\n    // markENOTDIR and markENOENT also set provisional=0\n    if (code === 'ENOTDIR' || code === 'EPERM') {\n      this.#markENOTDIR()\n    } else if (code === 'ENOENT') {\n      this.#markENOENT()\n    } else {\n      this.children().provisional = 0\n    }\n  }\n\n  #lstatFail(code: string = '') {\n    // Windows just raises ENOENT in this case, disable for win CI\n    /* c8 ignore start */\n    if (code === 'ENOTDIR') {\n      // already know it has a parent by this point\n      const p = this.parent as PathBase\n      p.#markENOTDIR()\n    } else if (code === 'ENOENT') {\n      /* c8 ignore stop */\n      this.#markENOENT()\n    }\n  }\n\n  #readlinkFail(code: string = '') {\n    let ter = this.#type\n    ter |= ENOREADLINK\n    if (code === 'ENOENT') ter |= ENOENT\n    // windows gets a weird error when you try to readlink a file\n    if (code === 'EINVAL' || code === 'UNKNOWN') {\n      // exists, but not a symlink, we don't know WHAT it is, so remove\n      // all IFMT bits.\n      ter &= IFMT_UNKNOWN\n    }\n    this.#type = ter\n    // windows just gets ENOENT in this case.  We do cover the case,\n    // just disabled because it's impossible on Windows CI\n    /* c8 ignore start */\n    if (code === 'ENOTDIR' && this.parent) {\n      this.parent.#markENOTDIR()\n    }\n    /* c8 ignore stop */\n  }\n\n  #readdirAddChild(e: Dirent, c: Children) {\n    return (\n      this.#readdirMaybePromoteChild(e, c) ||\n      this.#readdirAddNewChild(e, c)\n    )\n  }\n\n  #readdirAddNewChild(e: Dirent, c: Children): PathBase {\n    // alloc new entry at head, so it's never provisional\n    const type = entToType(e)\n    const child = this.newChild(e.name, type, { parent: this })\n    const ifmt = child.#type & IFMT\n    if (ifmt !== IFDIR && ifmt !== IFLNK && ifmt !== UNKNOWN) {\n      child.#type |= ENOTDIR\n    }\n    c.unshift(child)\n    c.provisional++\n    return child\n  }\n\n  #readdirMaybePromoteChild(e: Dirent, c: Children): PathBase | undefined {\n    for (let p = c.provisional; p < c.length; p++) {\n      const pchild = c[p]\n      const name =\n        this.nocase ? normalizeNocase(e.name) : normalize(e.name)\n      if (name !== pchild!.#matchName) {\n        continue\n      }\n\n      return this.#readdirPromoteChild(e, pchild!, p, c)\n    }\n  }\n\n  #readdirPromoteChild(\n    e: Dirent,\n    p: PathBase,\n    index: number,\n    c: Children,\n  ): PathBase {\n    const v = p.name\n    // retain any other flags, but set ifmt from dirent\n    p.#type = (p.#type & IFMT_UNKNOWN) | entToType(e)\n    // case sensitivity fixing when we learn the true name.\n    if (v !== e.name) p.name = e.name\n\n    // just advance provisional index (potentially off the list),\n    // otherwise we have to splice/pop it out and re-insert at head\n    if (index !== c.provisional) {\n      if (index === c.length - 1) c.pop()\n      else c.splice(index, 1)\n      c.unshift(p)\n    }\n    c.provisional++\n    return p\n  }\n\n  /**\n   * Call lstat() on this Path, and update all known information that can be\n   * determined.\n   *\n   * Note that unlike `fs.lstat()`, the returned value does not contain some\n   * information, such as `mode`, `dev`, `nlink`, and `ino`.  If that\n   * information is required, you will need to call `fs.lstat` yourself.\n   *\n   * If the Path refers to a nonexistent file, or if the lstat call fails for\n   * any reason, `undefined` is returned.  Otherwise the updated Path object is\n   * returned.\n   *\n   * Results are cached, and thus may be out of date if the filesystem is\n   * mutated.\n   */\n  async lstat(): Promise<PathBase | undefined> {\n    if ((this.#type & ENOENT) === 0) {\n      try {\n        this.#applyStat(await this.#fs.promises.lstat(this.fullpath()))\n        return this\n      } catch (er) {\n        this.#lstatFail((er as NodeJS.ErrnoException).code)\n      }\n    }\n  }\n\n  /**\n   * synchronous {@link PathBase.lstat}\n   */\n  lstatSync(): PathBase | undefined {\n    if ((this.#type & ENOENT) === 0) {\n      try {\n        this.#applyStat(this.#fs.lstatSync(this.fullpath()))\n        return this\n      } catch (er) {\n        this.#lstatFail((er as NodeJS.ErrnoException).code)\n      }\n    }\n  }\n\n  #applyStat(st: Stats) {\n    const {\n      atime,\n      atimeMs,\n      birthtime,\n      birthtimeMs,\n      blksize,\n      blocks,\n      ctime,\n      ctimeMs,\n      dev,\n      gid,\n      ino,\n      mode,\n      mtime,\n      mtimeMs,\n      nlink,\n      rdev,\n      size,\n      uid,\n    } = st\n    this.#atime = atime\n    this.#atimeMs = atimeMs\n    this.#birthtime = birthtime\n    this.#birthtimeMs = birthtimeMs\n    this.#blksize = blksize\n    this.#blocks = blocks\n    this.#ctime = ctime\n    this.#ctimeMs = ctimeMs\n    this.#dev = dev\n    this.#gid = gid\n    this.#ino = ino\n    this.#mode = mode\n    this.#mtime = mtime\n    this.#mtimeMs = mtimeMs\n    this.#nlink = nlink\n    this.#rdev = rdev\n    this.#size = size\n    this.#uid = uid\n    const ifmt = entToType(st)\n    // retain any other flags, but set the ifmt\n    this.#type = (this.#type & IFMT_UNKNOWN) | ifmt | LSTAT_CALLED\n    if (ifmt !== UNKNOWN && ifmt !== IFDIR && ifmt !== IFLNK) {\n      this.#type |= ENOTDIR\n    }\n  }\n\n  #onReaddirCB: ((\n    er: NodeJS.ErrnoException | null,\n    entries: Path[],\n  ) => any)[] = []\n  #readdirCBInFlight: boolean = false\n  #callOnReaddirCB(children: Path[]) {\n    this.#readdirCBInFlight = false\n    const cbs = this.#onReaddirCB.slice()\n    this.#onReaddirCB.length = 0\n    cbs.forEach(cb => cb(null, children))\n  }\n\n  /**\n   * Standard node-style callback interface to get list of directory entries.\n   *\n   * If the Path cannot or does not contain any children, then an empty array\n   * is returned.\n   *\n   * Results are cached, and thus may be out of date if the filesystem is\n   * mutated.\n   *\n   * @param cb The callback called with (er, entries).  Note that the `er`\n   * param is somewhat extraneous, as all readdir() errors are handled and\n   * simply result in an empty set of entries being returned.\n   * @param allowZalgo Boolean indicating that immediately known results should\n   * *not* be deferred with `queueMicrotask`. Defaults to `false`. Release\n   * zalgo at your peril, the dark pony lord is devious and unforgiving.\n   */\n  readdirCB(\n    cb: (er: NodeJS.ErrnoException | null, entries: PathBase[]) => any,\n    allowZalgo: boolean = false,\n  ): void {\n    if (!this.canReaddir()) {\n      if (allowZalgo) cb(null, [])\n      else queueMicrotask(() => cb(null, []))\n      return\n    }\n\n    const children = this.children()\n    if (this.calledReaddir()) {\n      const c = children.slice(0, children.provisional)\n      if (allowZalgo) cb(null, c)\n      else queueMicrotask(() => cb(null, c))\n      return\n    }\n\n    // don't have to worry about zalgo at this point.\n    this.#onReaddirCB.push(cb)\n    if (this.#readdirCBInFlight) {\n      return\n    }\n    this.#readdirCBInFlight = true\n\n    // else read the directory, fill up children\n    // de-provisionalize any provisional children.\n    const fullpath = this.fullpath()\n    this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => {\n      if (er) {\n        this.#readdirFail((er as NodeJS.ErrnoException).code)\n        children.provisional = 0\n      } else {\n        // if we didn't get an error, we always get entries.\n        //@ts-ignore\n        for (const e of entries) {\n          this.#readdirAddChild(e, children)\n        }\n        this.#readdirSuccess(children)\n      }\n      this.#callOnReaddirCB(children.slice(0, children.provisional))\n      return\n    })\n  }\n\n  #asyncReaddirInFlight?: Promise<void>\n\n  /**\n   * Return an array of known child entries.\n   *\n   * If the Path cannot or does not contain any children, then an empty array\n   * is returned.\n   *\n   * Results are cached, and thus may be out of date if the filesystem is\n   * mutated.\n   */\n  async readdir(): Promise<PathBase[]> {\n    if (!this.canReaddir()) {\n      return []\n    }\n\n    const children = this.children()\n    if (this.calledReaddir()) {\n      return children.slice(0, children.provisional)\n    }\n\n    // else read the directory, fill up children\n    // de-provisionalize any provisional children.\n    const fullpath = this.fullpath()\n    if (this.#asyncReaddirInFlight) {\n      await this.#asyncReaddirInFlight\n    } else {\n      /* c8 ignore start */\n      let resolve: () => void = () => {}\n      /* c8 ignore stop */\n      this.#asyncReaddirInFlight = new Promise<void>(\n        res => (resolve = res),\n      )\n      try {\n        for (const e of await this.#fs.promises.readdir(fullpath, {\n          withFileTypes: true,\n        })) {\n          this.#readdirAddChild(e, children)\n        }\n        this.#readdirSuccess(children)\n      } catch (er) {\n        this.#readdirFail((er as NodeJS.ErrnoException).code)\n        children.provisional = 0\n      }\n      this.#asyncReaddirInFlight = undefined\n      resolve()\n    }\n    return children.slice(0, children.provisional)\n  }\n\n  /**\n   * synchronous {@link PathBase.readdir}\n   */\n  readdirSync(): PathBase[] {\n    if (!this.canReaddir()) {\n      return []\n    }\n\n    const children = this.children()\n    if (this.calledReaddir()) {\n      return children.slice(0, children.provisional)\n    }\n\n    // else read the directory, fill up children\n    // de-provisionalize any provisional children.\n    const fullpath = this.fullpath()\n    try {\n      for (const e of this.#fs.readdirSync(fullpath, {\n        withFileTypes: true,\n      })) {\n        this.#readdirAddChild(e, children)\n      }\n      this.#readdirSuccess(children)\n    } catch (er) {\n      this.#readdirFail((er as NodeJS.ErrnoException).code)\n      children.provisional = 0\n    }\n    return children.slice(0, children.provisional)\n  }\n\n  canReaddir() {\n    if (this.#type & ENOCHILD) return false\n    const ifmt = IFMT & this.#type\n    // we always set ENOTDIR when setting IFMT, so should be impossible\n    /* c8 ignore start */\n    if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) {\n      return false\n    }\n    /* c8 ignore stop */\n    return true\n  }\n\n  shouldWalk(\n    dirs: Set<PathBase | undefined>,\n    walkFilter?: (e: PathBase) => boolean,\n  ): boolean {\n    return (\n      (this.#type & IFDIR) === IFDIR &&\n      !(this.#type & ENOCHILD) &&\n      !dirs.has(this) &&\n      (!walkFilter || walkFilter(this))\n    )\n  }\n\n  /**\n   * Return the Path object corresponding to path as resolved\n   * by realpath(3).\n   *\n   * If the realpath call fails for any reason, `undefined` is returned.\n   *\n   * Result is cached, and thus may be outdated if the filesystem is mutated.\n   * On success, returns a Path object.\n   */\n  async realpath(): Promise<PathBase | undefined> {\n    if (this.#realpath) return this.#realpath\n    if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) return undefined\n    try {\n      const rp = await this.#fs.promises.realpath(this.fullpath())\n      return (this.#realpath = this.resolve(rp))\n    } catch (_) {\n      this.#markENOREALPATH()\n    }\n  }\n\n  /**\n   * Synchronous {@link realpath}\n   */\n  realpathSync(): PathBase | undefined {\n    if (this.#realpath) return this.#realpath\n    if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) return undefined\n    try {\n      const rp = this.#fs.realpathSync(this.fullpath())\n      return (this.#realpath = this.resolve(rp))\n    } catch (_) {\n      this.#markENOREALPATH()\n    }\n  }\n\n  /**\n   * Internal method to mark this Path object as the scurry cwd,\n   * called by {@link PathScurry#chdir}\n   *\n   * @internal\n   */\n  [setAsCwd](oldCwd: PathBase): void {\n    if (oldCwd === this) return\n    oldCwd.isCWD = false\n    this.isCWD = true\n\n    const changed = new Set<PathBase>([])\n    let rp = []\n    let p: PathBase = this\n    while (p && p.parent) {\n      changed.add(p)\n      p.#relative = rp.join(this.sep)\n      p.#relativePosix = rp.join('/')\n      p = p.parent\n      rp.push('..')\n    }\n    // now un-memoize parents of old cwd\n    p = oldCwd\n    while (p && p.parent && !changed.has(p)) {\n      p.#relative = undefined\n      p.#relativePosix = undefined\n      p = p.parent\n    }\n  }\n}\n\n/**\n * Path class used on win32 systems\n *\n * Uses `'\\\\'` as the path separator for returned paths, either `'\\\\'` or `'/'`\n * as the path separator for parsing paths.\n */\nexport class PathWin32 extends PathBase {\n  /**\n   * Separator for generating path strings.\n   */\n  sep: '\\\\' = '\\\\'\n  /**\n   * Separator for parsing path strings.\n   */\n  splitSep: RegExp = eitherSep\n\n  /**\n   * Do not create new Path objects directly.  They should always be accessed\n   * via the PathScurry class or other methods on the Path class.\n   *\n   * @internal\n   */\n  constructor(\n    name: string,\n    type: number = UNKNOWN,\n    root: PathBase | undefined,\n    roots: { [k: string]: PathBase },\n    nocase: boolean,\n    children: ChildrenCache,\n    opts: PathOpts,\n  ) {\n    super(name, type, root, roots, nocase, children, opts)\n  }\n\n  /**\n   * @internal\n   */\n  newChild(name: string, type: number = UNKNOWN, opts: PathOpts = {}) {\n    return new PathWin32(\n      name,\n      type,\n      this.root,\n      this.roots,\n      this.nocase,\n      this.childrenCache(),\n      opts,\n    )\n  }\n\n  /**\n   * @internal\n   */\n  getRootString(path: string): string {\n    return win32.parse(path).root\n  }\n\n  /**\n   * @internal\n   */\n  getRoot(rootPath: string): PathBase {\n    rootPath = uncToDrive(rootPath.toUpperCase())\n    if (rootPath === this.root.name) {\n      return this.root\n    }\n    // ok, not that one, check if it matches another we know about\n    for (const [compare, root] of Object.entries(this.roots)) {\n      if (this.sameRoot(rootPath, compare)) {\n        return (this.roots[rootPath] = root)\n      }\n    }\n    // otherwise, have to create a new one.\n    return (this.roots[rootPath] = new PathScurryWin32(\n      rootPath,\n      this,\n    ).root)\n  }\n\n  /**\n   * @internal\n   */\n  sameRoot(rootPath: string, compare: string = this.root.name): boolean {\n    // windows can (rarely) have case-sensitive filesystem, but\n    // UNC and drive letters are always case-insensitive, and canonically\n    // represented uppercase.\n    rootPath = rootPath\n      .toUpperCase()\n      .replace(/\\//g, '\\\\')\n      .replace(uncDriveRegexp, '$1\\\\')\n    return rootPath === compare\n  }\n}\n\n/**\n * Path class used on all posix systems.\n *\n * Uses `'/'` as the path separator.\n */\nexport class PathPosix extends PathBase {\n  /**\n   * separator for parsing path strings\n   */\n  splitSep: '/' = '/'\n  /**\n   * separator for generating path strings\n   */\n  sep: '/' = '/'\n\n  /**\n   * Do not create new Path objects directly.  They should always be accessed\n   * via the PathScurry class or other methods on the Path class.\n   *\n   * @internal\n   */\n  constructor(\n    name: string,\n    type: number = UNKNOWN,\n    root: PathBase | undefined,\n    roots: { [k: string]: PathBase },\n    nocase: boolean,\n    children: ChildrenCache,\n    opts: PathOpts,\n  ) {\n    super(name, type, root, roots, nocase, children, opts)\n  }\n\n  /**\n   * @internal\n   */\n  getRootString(path: string): string {\n    return path.startsWith('/') ? '/' : ''\n  }\n\n  /**\n   * @internal\n   */\n  getRoot(_rootPath: string): PathBase {\n    return this.root\n  }\n\n  /**\n   * @internal\n   */\n  newChild(name: string, type: number = UNKNOWN, opts: PathOpts = {}) {\n    return new PathPosix(\n      name,\n      type,\n      this.root,\n      this.roots,\n      this.nocase,\n      this.childrenCache(),\n      opts,\n    )\n  }\n}\n\n/**\n * Options that may be provided to the PathScurry constructor\n */\nexport interface PathScurryOpts {\n  /**\n   * perform case-insensitive path matching. Default based on platform\n   * subclass.\n   */\n  nocase?: boolean\n  /**\n   * Number of Path entries to keep in the cache of Path child references.\n   *\n   * Setting this higher than 65536 will dramatically increase the data\n   * consumption and construction time overhead of each PathScurry.\n   *\n   * Setting this value to 256 or lower will significantly reduce the data\n   * consumption and construction time overhead, but may also reduce resolve()\n   * and readdir() performance on large filesystems.\n   *\n   * Default `16384`.\n   */\n  childrenCacheSize?: number\n  /**\n   * An object that overrides the built-in functions from the fs and\n   * fs/promises modules.\n   *\n   * See {@link FSOption}\n   */\n  fs?: FSOption\n}\n\n/**\n * The base class for all PathScurry classes, providing the interface for path\n * resolution and filesystem operations.\n *\n * Typically, you should *not* instantiate this class directly, but rather one\n * of the platform-specific classes, or the exported {@link PathScurry} which\n * defaults to the current platform.\n */\nexport abstract class PathScurryBase {\n  /**\n   * The root Path entry for the current working directory of this Scurry\n   */\n  root: PathBase\n  /**\n   * The string path for the root of this Scurry's current working directory\n   */\n  rootPath: string\n  /**\n   * A collection of all roots encountered, referenced by rootPath\n   */\n  roots: { [k: string]: PathBase }\n  /**\n   * The Path entry corresponding to this PathScurry's current working directory.\n   */\n  cwd: PathBase\n  #resolveCache: ResolveCache\n  #resolvePosixCache: ResolveCache\n  #children: ChildrenCache\n  /**\n   * Perform path comparisons case-insensitively.\n   *\n   * Defaults true on Darwin and Windows systems, false elsewhere.\n   */\n  nocase: boolean\n\n  /**\n   * The path separator used for parsing paths\n   *\n   * `'/'` on Posix systems, either `'/'` or `'\\\\'` on Windows\n   */\n  abstract sep: string | RegExp\n\n  #fs: FSValue\n\n  /**\n   * This class should not be instantiated directly.\n   *\n   * Use PathScurryWin32, PathScurryDarwin, PathScurryPosix, or PathScurry\n   *\n   * @internal\n   */\n  constructor(\n    cwd: URL | string = process.cwd(),\n    pathImpl: typeof win32 | typeof posix,\n    sep: string | RegExp,\n    {\n      nocase,\n      childrenCacheSize = 16 * 1024,\n      fs = defaultFS,\n    }: PathScurryOpts = {},\n  ) {\n    this.#fs = fsFromOption(fs)\n    if (cwd instanceof URL || cwd.startsWith('file://')) {\n      cwd = fileURLToPath(cwd)\n    }\n    // resolve and split root, and then add to the store.\n    // this is the only time we call path.resolve()\n    const cwdPath = pathImpl.resolve(cwd)\n    this.roots = Object.create(null)\n    this.rootPath = this.parseRootPath(cwdPath)\n    this.#resolveCache = new ResolveCache()\n    this.#resolvePosixCache = new ResolveCache()\n    this.#children = new ChildrenCache(childrenCacheSize)\n\n    const split = cwdPath.substring(this.rootPath.length).split(sep)\n    // resolve('/') leaves '', splits to [''], we don't want that.\n    if (split.length === 1 && !split[0]) {\n      split.pop()\n    }\n    /* c8 ignore start */\n    if (nocase === undefined) {\n      throw new TypeError(\n        'must provide nocase setting to PathScurryBase ctor',\n      )\n    }\n    /* c8 ignore stop */\n    this.nocase = nocase\n    this.root = this.newRoot(this.#fs)\n    this.roots[this.rootPath] = this.root\n    let prev: PathBase = this.root\n    let len = split.length - 1\n    const joinSep = pathImpl.sep\n    let abs = this.rootPath\n    let sawFirst = false\n    for (const part of split) {\n      const l = len--\n      prev = prev.child(part, {\n        relative: new Array(l).fill('..').join(joinSep),\n        relativePosix: new Array(l).fill('..').join('/'),\n        fullpath: (abs += (sawFirst ? '' : joinSep) + part),\n      })\n      sawFirst = true\n    }\n    this.cwd = prev\n  }\n\n  /**\n   * Get the depth of a provided path, string, or the cwd\n   */\n  depth(path: Path | string = this.cwd): number {\n    if (typeof path === 'string') {\n      path = this.cwd.resolve(path)\n    }\n    return path.depth()\n  }\n\n  /**\n   * Parse the root portion of a path string\n   *\n   * @internal\n   */\n  abstract parseRootPath(dir: string): string\n  /**\n   * create a new Path to use as root during construction.\n   *\n   * @internal\n   */\n  abstract newRoot(fs: FSValue): PathBase\n  /**\n   * Determine whether a given path string is absolute\n   */\n  abstract isAbsolute(p: string): boolean\n\n  /**\n   * Return the cache of child entries.  Exposed so subclasses can create\n   * child Path objects in a platform-specific way.\n   *\n   * @internal\n   */\n  childrenCache() {\n    return this.#children\n  }\n\n  /**\n   * Resolve one or more path strings to a resolved string\n   *\n   * Same interface as require('path').resolve.\n   *\n   * Much faster than path.resolve() when called multiple times for the same\n   * path, because the resolved Path objects are cached.  Much slower\n   * otherwise.\n   */\n  resolve(...paths: string[]): string {\n    // first figure out the minimum number of paths we have to test\n    // we always start at cwd, but any absolutes will bump the start\n    let r = ''\n    for (let i = paths.length - 1; i >= 0; i--) {\n      const p = paths[i]\n      if (!p || p === '.') continue\n      r = r ? `${p}/${r}` : p\n      if (this.isAbsolute(p)) {\n        break\n      }\n    }\n    const cached = this.#resolveCache.get(r)\n    if (cached !== undefined) {\n      return cached\n    }\n    const result = this.cwd.resolve(r).fullpath()\n    this.#resolveCache.set(r, result)\n    return result\n  }\n\n  /**\n   * Resolve one or more path strings to a resolved string, returning\n   * the posix path.  Identical to .resolve() on posix systems, but on\n   * windows will return a forward-slash separated UNC path.\n   *\n   * Same interface as require('path').resolve.\n   *\n   * Much faster than path.resolve() when called multiple times for the same\n   * path, because the resolved Path objects are cached.  Much slower\n   * otherwise.\n   */\n  resolvePosix(...paths: string[]): string {\n    // first figure out the minimum number of paths we have to test\n    // we always start at cwd, but any absolutes will bump the start\n    let r = ''\n    for (let i = paths.length - 1; i >= 0; i--) {\n      const p = paths[i]\n      if (!p || p === '.') continue\n      r = r ? `${p}/${r}` : p\n      if (this.isAbsolute(p)) {\n        break\n      }\n    }\n    const cached = this.#resolvePosixCache.get(r)\n    if (cached !== undefined) {\n      return cached\n    }\n    const result = this.cwd.resolve(r).fullpathPosix()\n    this.#resolvePosixCache.set(r, result)\n    return result\n  }\n\n  /**\n   * find the relative path from the cwd to the supplied path string or entry\n   */\n  relative(entry: PathBase | string = this.cwd): string {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    }\n    return entry.relative()\n  }\n\n  /**\n   * find the relative path from the cwd to the supplied path string or\n   * entry, using / as the path delimiter, even on Windows.\n   */\n  relativePosix(entry: PathBase | string = this.cwd): string {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    }\n    return entry.relativePosix()\n  }\n\n  /**\n   * Return the basename for the provided string or Path object\n   */\n  basename(entry: PathBase | string = this.cwd): string {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    }\n    return entry.name\n  }\n\n  /**\n   * Return the dirname for the provided string or Path object\n   */\n  dirname(entry: PathBase | string = this.cwd): string {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    }\n    return (entry.parent || entry).fullpath()\n  }\n\n  /**\n   * Return an array of known child entries.\n   *\n   * First argument may be either a string, or a Path object.\n   *\n   * If the Path cannot or does not contain any children, then an empty array\n   * is returned.\n   *\n   * Results are cached, and thus may be out of date if the filesystem is\n   * mutated.\n   *\n   * Unlike `fs.readdir()`, the `withFileTypes` option defaults to `true`. Set\n   * `{ withFileTypes: false }` to return strings.\n   */\n\n  readdir(): Promise<PathBase[]>\n  readdir(opts: { withFileTypes: true }): Promise<PathBase[]>\n  readdir(opts: { withFileTypes: false }): Promise<string[]>\n  readdir(opts: { withFileTypes: boolean }): Promise<PathBase[] | string[]>\n  readdir(entry: PathBase | string): Promise<PathBase[]>\n  readdir(\n    entry: PathBase | string,\n    opts: { withFileTypes: true },\n  ): Promise<PathBase[]>\n  readdir(\n    entry: PathBase | string,\n    opts: { withFileTypes: false },\n  ): Promise<string[]>\n  readdir(\n    entry: PathBase | string,\n    opts: { withFileTypes: boolean },\n  ): Promise<PathBase[] | string[]>\n  async readdir(\n    entry: PathBase | string | { withFileTypes: boolean } = this.cwd,\n    opts: { withFileTypes: boolean } = {\n      withFileTypes: true,\n    },\n  ): Promise<PathBase[] | string[]> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const { withFileTypes } = opts\n    if (!entry.canReaddir()) {\n      return []\n    } else {\n      const p = await entry.readdir()\n      return withFileTypes ? p : p.map(e => e.name)\n    }\n  }\n\n  /**\n   * synchronous {@link PathScurryBase.readdir}\n   */\n  readdirSync(): PathBase[]\n  readdirSync(opts: { withFileTypes: true }): PathBase[]\n  readdirSync(opts: { withFileTypes: false }): string[]\n  readdirSync(opts: { withFileTypes: boolean }): PathBase[] | string[]\n  readdirSync(entry: PathBase | string): PathBase[]\n  readdirSync(\n    entry: PathBase | string,\n    opts: { withFileTypes: true },\n  ): PathBase[]\n  readdirSync(\n    entry: PathBase | string,\n    opts: { withFileTypes: false },\n  ): string[]\n  readdirSync(\n    entry: PathBase | string,\n    opts: { withFileTypes: boolean },\n  ): PathBase[] | string[]\n  readdirSync(\n    entry: PathBase | string | { withFileTypes: boolean } = this.cwd,\n    opts: { withFileTypes: boolean } = {\n      withFileTypes: true,\n    },\n  ): PathBase[] | string[] {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const { withFileTypes = true } = opts\n    if (!entry.canReaddir()) {\n      return []\n    } else if (withFileTypes) {\n      return entry.readdirSync()\n    } else {\n      return entry.readdirSync().map(e => e.name)\n    }\n  }\n\n  /**\n   * Call lstat() on the string or Path object, and update all known\n   * information that can be determined.\n   *\n   * Note that unlike `fs.lstat()`, the returned value does not contain some\n   * information, such as `mode`, `dev`, `nlink`, and `ino`.  If that\n   * information is required, you will need to call `fs.lstat` yourself.\n   *\n   * If the Path refers to a nonexistent file, or if the lstat call fails for\n   * any reason, `undefined` is returned.  Otherwise the updated Path object is\n   * returned.\n   *\n   * Results are cached, and thus may be out of date if the filesystem is\n   * mutated.\n   */\n  async lstat(\n    entry: string | PathBase = this.cwd,\n  ): Promise<PathBase | undefined> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    }\n    return entry.lstat()\n  }\n\n  /**\n   * synchronous {@link PathScurryBase.lstat}\n   */\n  lstatSync(entry: string | PathBase = this.cwd): PathBase | undefined {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    }\n    return entry.lstatSync()\n  }\n\n  /**\n   * Return the Path object or string path corresponding to the target of a\n   * symbolic link.\n   *\n   * If the path is not a symbolic link, or if the readlink call fails for any\n   * reason, `undefined` is returned.\n   *\n   * Result is cached, and thus may be outdated if the filesystem is mutated.\n   *\n   * `{withFileTypes}` option defaults to `false`.\n   *\n   * On success, returns a Path object if `withFileTypes` option is true,\n   * otherwise a string.\n   */\n  readlink(): Promise<string | undefined>\n  readlink(opt: { withFileTypes: false }): Promise<string | undefined>\n  readlink(opt: { withFileTypes: true }): Promise<PathBase | undefined>\n  readlink(opt: {\n    withFileTypes: boolean\n  }): Promise<PathBase | string | undefined>\n  readlink(\n    entry: string | PathBase,\n    opt?: { withFileTypes: false },\n  ): Promise<string | undefined>\n  readlink(\n    entry: string | PathBase,\n    opt: { withFileTypes: true },\n  ): Promise<PathBase | undefined>\n  readlink(\n    entry: string | PathBase,\n    opt: { withFileTypes: boolean },\n  ): Promise<string | PathBase | undefined>\n  async readlink(\n    entry: string | PathBase | { withFileTypes: boolean } = this.cwd,\n    { withFileTypes }: { withFileTypes: boolean } = {\n      withFileTypes: false,\n    },\n  ): Promise<string | PathBase | undefined> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      withFileTypes = entry.withFileTypes\n      entry = this.cwd\n    }\n    const e = await entry.readlink()\n    return withFileTypes ? e : e?.fullpath()\n  }\n\n  /**\n   * synchronous {@link PathScurryBase.readlink}\n   */\n  readlinkSync(): string | undefined\n  readlinkSync(opt: { withFileTypes: false }): string | undefined\n  readlinkSync(opt: { withFileTypes: true }): PathBase | undefined\n  readlinkSync(opt: {\n    withFileTypes: boolean\n  }): PathBase | string | undefined\n  readlinkSync(\n    entry: string | PathBase,\n    opt?: { withFileTypes: false },\n  ): string | undefined\n  readlinkSync(\n    entry: string | PathBase,\n    opt: { withFileTypes: true },\n  ): PathBase | undefined\n  readlinkSync(\n    entry: string | PathBase,\n    opt: { withFileTypes: boolean },\n  ): string | PathBase | undefined\n  readlinkSync(\n    entry: string | PathBase | { withFileTypes: boolean } = this.cwd,\n    { withFileTypes }: { withFileTypes: boolean } = {\n      withFileTypes: false,\n    },\n  ): string | PathBase | undefined {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      withFileTypes = entry.withFileTypes\n      entry = this.cwd\n    }\n    const e = entry.readlinkSync()\n    return withFileTypes ? e : e?.fullpath()\n  }\n\n  /**\n   * Return the Path object or string path corresponding to path as resolved\n   * by realpath(3).\n   *\n   * If the realpath call fails for any reason, `undefined` is returned.\n   *\n   * Result is cached, and thus may be outdated if the filesystem is mutated.\n   *\n   * `{withFileTypes}` option defaults to `false`.\n   *\n   * On success, returns a Path object if `withFileTypes` option is true,\n   * otherwise a string.\n   */\n  realpath(): Promise<string | undefined>\n  realpath(opt: { withFileTypes: false }): Promise<string | undefined>\n  realpath(opt: { withFileTypes: true }): Promise<PathBase | undefined>\n  realpath(opt: {\n    withFileTypes: boolean\n  }): Promise<PathBase | string | undefined>\n  realpath(\n    entry: string | PathBase,\n    opt?: { withFileTypes: false },\n  ): Promise<string | undefined>\n  realpath(\n    entry: string | PathBase,\n    opt: { withFileTypes: true },\n  ): Promise<PathBase | undefined>\n  realpath(\n    entry: string | PathBase,\n    opt: { withFileTypes: boolean },\n  ): Promise<string | PathBase | undefined>\n  async realpath(\n    entry: string | PathBase | { withFileTypes: boolean } = this.cwd,\n    { withFileTypes }: { withFileTypes: boolean } = {\n      withFileTypes: false,\n    },\n  ): Promise<string | PathBase | undefined> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      withFileTypes = entry.withFileTypes\n      entry = this.cwd\n    }\n    const e = await entry.realpath()\n    return withFileTypes ? e : e?.fullpath()\n  }\n\n  realpathSync(): string | undefined\n  realpathSync(opt: { withFileTypes: false }): string | undefined\n  realpathSync(opt: { withFileTypes: true }): PathBase | undefined\n  realpathSync(opt: {\n    withFileTypes: boolean\n  }): PathBase | string | undefined\n  realpathSync(\n    entry: string | PathBase,\n    opt?: { withFileTypes: false },\n  ): string | undefined\n  realpathSync(\n    entry: string | PathBase,\n    opt: { withFileTypes: true },\n  ): PathBase | undefined\n  realpathSync(\n    entry: string | PathBase,\n    opt: { withFileTypes: boolean },\n  ): string | PathBase | undefined\n  realpathSync(\n    entry: string | PathBase | { withFileTypes: boolean } = this.cwd,\n    { withFileTypes }: { withFileTypes: boolean } = {\n      withFileTypes: false,\n    },\n  ): string | PathBase | undefined {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      withFileTypes = entry.withFileTypes\n      entry = this.cwd\n    }\n    const e = entry.realpathSync()\n    return withFileTypes ? e : e?.fullpath()\n  }\n\n  /**\n   * Asynchronously walk the directory tree, returning an array of\n   * all path strings or Path objects found.\n   *\n   * Note that this will be extremely memory-hungry on large filesystems.\n   * In such cases, it may be better to use the stream or async iterator\n   * walk implementation.\n   */\n  walk(): Promise<PathBase[]>\n  walk(\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): Promise<PathBase[]>\n  walk(opts: WalkOptionsWithFileTypesFalse): Promise<string[]>\n  walk(opts: WalkOptions): Promise<string[] | PathBase[]>\n  walk(entry: string | PathBase): Promise<PathBase[]>\n  walk(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): Promise<PathBase[]>\n  walk(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesFalse,\n  ): Promise<string[]>\n  walk(\n    entry: string | PathBase,\n    opts: WalkOptions,\n  ): Promise<PathBase[] | string[]>\n  async walk(\n    entry: string | PathBase | WalkOptions = this.cwd,\n    opts: WalkOptions = {},\n  ): Promise<PathBase[] | string[]> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const {\n      withFileTypes = true,\n      follow = false,\n      filter,\n      walkFilter,\n    } = opts\n    const results: (string | PathBase)[] = []\n    if (!filter || filter(entry)) {\n      results.push(withFileTypes ? entry : entry.fullpath())\n    }\n    const dirs = new Set<PathBase>()\n    const walk = (\n      dir: PathBase,\n      cb: (er?: NodeJS.ErrnoException) => void,\n    ) => {\n      dirs.add(dir)\n      dir.readdirCB((er, entries) => {\n        /* c8 ignore start */\n        if (er) {\n          return cb(er)\n        }\n        /* c8 ignore stop */\n        let len = entries.length\n        if (!len) return cb()\n        const next = () => {\n          if (--len === 0) {\n            cb()\n          }\n        }\n        for (const e of entries) {\n          if (!filter || filter(e)) {\n            results.push(withFileTypes ? e : e.fullpath())\n          }\n          if (follow && e.isSymbolicLink()) {\n            e.realpath()\n              .then(r => (r?.isUnknown() ? r.lstat() : r))\n              .then(r =>\n                r?.shouldWalk(dirs, walkFilter) ? walk(r, next) : next(),\n              )\n          } else {\n            if (e.shouldWalk(dirs, walkFilter)) {\n              walk(e, next)\n            } else {\n              next()\n            }\n          }\n        }\n      }, true) // zalgooooooo\n    }\n\n    const start = entry\n    return new Promise<PathBase[] | string[]>((res, rej) => {\n      walk(start, er => {\n        /* c8 ignore start */\n        if (er) return rej(er)\n        /* c8 ignore stop */\n        res(results as PathBase[] | string[])\n      })\n    })\n  }\n\n  /**\n   * Synchronously walk the directory tree, returning an array of\n   * all path strings or Path objects found.\n   *\n   * Note that this will be extremely memory-hungry on large filesystems.\n   * In such cases, it may be better to use the stream or async iterator\n   * walk implementation.\n   */\n  walkSync(): PathBase[]\n  walkSync(\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): PathBase[]\n  walkSync(opts: WalkOptionsWithFileTypesFalse): string[]\n  walkSync(opts: WalkOptions): string[] | PathBase[]\n  walkSync(entry: string | PathBase): PathBase[]\n  walkSync(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesUnset | WalkOptionsWithFileTypesTrue,\n  ): PathBase[]\n  walkSync(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesFalse,\n  ): string[]\n  walkSync(\n    entry: string | PathBase,\n    opts: WalkOptions,\n  ): PathBase[] | string[]\n  walkSync(\n    entry: string | PathBase | WalkOptions = this.cwd,\n    opts: WalkOptions = {},\n  ): PathBase[] | string[] {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const {\n      withFileTypes = true,\n      follow = false,\n      filter,\n      walkFilter,\n    } = opts\n    const results: (string | PathBase)[] = []\n    if (!filter || filter(entry)) {\n      results.push(withFileTypes ? entry : entry.fullpath())\n    }\n    const dirs = new Set<PathBase>([entry])\n    for (const dir of dirs) {\n      const entries = dir.readdirSync()\n      for (const e of entries) {\n        if (!filter || filter(e)) {\n          results.push(withFileTypes ? e : e.fullpath())\n        }\n        let r: PathBase | undefined = e\n        if (e.isSymbolicLink()) {\n          if (!(follow && (r = e.realpathSync()))) continue\n          if (r.isUnknown()) r.lstatSync()\n        }\n        if (r.shouldWalk(dirs, walkFilter)) {\n          dirs.add(r)\n        }\n      }\n    }\n    return results as string[] | PathBase[]\n  }\n\n  /**\n   * Support for `for await`\n   *\n   * Alias for {@link PathScurryBase.iterate}\n   *\n   * Note: As of Node 19, this is very slow, compared to other methods of\n   * walking.  Consider using {@link PathScurryBase.stream} if memory overhead\n   * and backpressure are concerns, or {@link PathScurryBase.walk} if not.\n   */\n  [Symbol.asyncIterator]() {\n    return this.iterate()\n  }\n\n  /**\n   * Async generator form of {@link PathScurryBase.walk}\n   *\n   * Note: As of Node 19, this is very slow, compared to other methods of\n   * walking, especially if most/all of the directory tree has been previously\n   * walked.  Consider using {@link PathScurryBase.stream} if memory overhead\n   * and backpressure are concerns, or {@link PathScurryBase.walk} if not.\n   */\n  iterate(): AsyncGenerator<PathBase, void, void>\n  iterate(\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): AsyncGenerator<PathBase, void, void>\n  iterate(\n    opts: WalkOptionsWithFileTypesFalse,\n  ): AsyncGenerator<string, void, void>\n  iterate(opts: WalkOptions): AsyncGenerator<string | PathBase, void, void>\n  iterate(entry: string | PathBase): AsyncGenerator<PathBase, void, void>\n  iterate(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): AsyncGenerator<PathBase, void, void>\n  iterate(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesFalse,\n  ): AsyncGenerator<string, void, void>\n  iterate(\n    entry: string | PathBase,\n    opts: WalkOptions,\n  ): AsyncGenerator<PathBase | string, void, void>\n  iterate(\n    entry: string | PathBase | WalkOptions = this.cwd,\n    options: WalkOptions = {},\n  ): AsyncGenerator<PathBase | string, void, void> {\n    // iterating async over the stream is significantly more performant,\n    // especially in the warm-cache scenario, because it buffers up directory\n    // entries in the background instead of waiting for a yield for each one.\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      options = entry\n      entry = this.cwd\n    }\n    return this.stream(entry, options)[Symbol.asyncIterator]()\n  }\n\n  /**\n   * Iterating over a PathScurry performs a synchronous walk.\n   *\n   * Alias for {@link PathScurryBase.iterateSync}\n   */\n  [Symbol.iterator]() {\n    return this.iterateSync()\n  }\n\n  iterateSync(): Generator<PathBase, void, void>\n  iterateSync(\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): Generator<PathBase, void, void>\n  iterateSync(\n    opts: WalkOptionsWithFileTypesFalse,\n  ): Generator<string, void, void>\n  iterateSync(opts: WalkOptions): Generator<string | PathBase, void, void>\n  iterateSync(entry: string | PathBase): Generator<PathBase, void, void>\n  iterateSync(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): Generator<PathBase, void, void>\n  iterateSync(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesFalse,\n  ): Generator<string, void, void>\n  iterateSync(\n    entry: string | PathBase,\n    opts: WalkOptions,\n  ): Generator<PathBase | string, void, void>\n  *iterateSync(\n    entry: string | PathBase | WalkOptions = this.cwd,\n    opts: WalkOptions = {},\n  ): Generator<PathBase | string, void, void> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const {\n      withFileTypes = true,\n      follow = false,\n      filter,\n      walkFilter,\n    } = opts\n    if (!filter || filter(entry)) {\n      yield withFileTypes ? entry : entry.fullpath()\n    }\n    const dirs = new Set<PathBase>([entry])\n    for (const dir of dirs) {\n      const entries = dir.readdirSync()\n      for (const e of entries) {\n        if (!filter || filter(e)) {\n          yield withFileTypes ? e : e.fullpath()\n        }\n        let r: PathBase | undefined = e\n        if (e.isSymbolicLink()) {\n          if (!(follow && (r = e.realpathSync()))) continue\n          if (r.isUnknown()) r.lstatSync()\n        }\n        if (r.shouldWalk(dirs, walkFilter)) {\n          dirs.add(r)\n        }\n      }\n    }\n  }\n\n  /**\n   * Stream form of {@link PathScurryBase.walk}\n   *\n   * Returns a Minipass stream that emits {@link PathBase} objects by default,\n   * or strings if `{ withFileTypes: false }` is set in the options.\n   */\n  stream(): Minipass<PathBase>\n  stream(\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): Minipass<PathBase>\n  stream(opts: WalkOptionsWithFileTypesFalse): Minipass<string>\n  stream(opts: WalkOptions): Minipass<string | PathBase>\n  stream(entry: string | PathBase): Minipass<PathBase>\n  stream(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesUnset | WalkOptionsWithFileTypesTrue,\n  ): Minipass<PathBase>\n  stream(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesFalse,\n  ): Minipass<string>\n  stream(\n    entry: string | PathBase,\n    opts: WalkOptions,\n  ): Minipass<string> | Minipass<PathBase>\n  stream(\n    entry: string | PathBase | WalkOptions = this.cwd,\n    opts: WalkOptions = {},\n  ): Minipass<string> | Minipass<PathBase> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const {\n      withFileTypes = true,\n      follow = false,\n      filter,\n      walkFilter,\n    } = opts\n    const results = new Minipass<string | PathBase>({ objectMode: true })\n    if (!filter || filter(entry)) {\n      results.write(withFileTypes ? entry : entry.fullpath())\n    }\n    const dirs = new Set<PathBase>()\n    const queue: PathBase[] = [entry]\n    let processing = 0\n    const process = () => {\n      let paused = false\n      while (!paused) {\n        const dir = queue.shift()\n        if (!dir) {\n          if (processing === 0) results.end()\n          return\n        }\n\n        processing++\n        dirs.add(dir)\n\n        const onReaddir = (\n          er: null | NodeJS.ErrnoException,\n          entries: PathBase[],\n          didRealpaths: boolean = false,\n        ) => {\n          /* c8 ignore start */\n          if (er) return results.emit('error', er)\n          /* c8 ignore stop */\n          if (follow && !didRealpaths) {\n            const promises: Promise<PathBase | undefined>[] = []\n            for (const e of entries) {\n              if (e.isSymbolicLink()) {\n                promises.push(\n                  e\n                    .realpath()\n                    .then((r: PathBase | undefined) =>\n                      r?.isUnknown() ? r.lstat() : r,\n                    ),\n                )\n              }\n            }\n            if (promises.length) {\n              Promise.all(promises).then(() =>\n                onReaddir(null, entries, true),\n              )\n              return\n            }\n          }\n\n          for (const e of entries) {\n            if (e && (!filter || filter(e))) {\n              if (!results.write(withFileTypes ? e : e.fullpath())) {\n                paused = true\n              }\n            }\n          }\n\n          processing--\n          for (const e of entries) {\n            const r = e.realpathCached() || e\n            if (r.shouldWalk(dirs, walkFilter)) {\n              queue.push(r)\n            }\n          }\n          if (paused && !results.flowing) {\n            results.once('drain', process)\n          } else if (!sync) {\n            process()\n          }\n        }\n\n        // zalgo containment\n        let sync = true\n        dir.readdirCB(onReaddir, true)\n        sync = false\n      }\n    }\n    process()\n    return results as Minipass<string> | Minipass<PathBase>\n  }\n\n  /**\n   * Synchronous form of {@link PathScurryBase.stream}\n   *\n   * Returns a Minipass stream that emits {@link PathBase} objects by default,\n   * or strings if `{ withFileTypes: false }` is set in the options.\n   *\n   * Will complete the walk in a single tick if the stream is consumed fully.\n   * Otherwise, will pause as needed for stream backpressure.\n   */\n  streamSync(): Minipass<PathBase>\n  streamSync(\n    opts: WalkOptionsWithFileTypesTrue | WalkOptionsWithFileTypesUnset,\n  ): Minipass<PathBase>\n  streamSync(opts: WalkOptionsWithFileTypesFalse): Minipass<string>\n  streamSync(opts: WalkOptions): Minipass<string | PathBase>\n  streamSync(entry: string | PathBase): Minipass<PathBase>\n  streamSync(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesUnset | WalkOptionsWithFileTypesTrue,\n  ): Minipass<PathBase>\n  streamSync(\n    entry: string | PathBase,\n    opts: WalkOptionsWithFileTypesFalse,\n  ): Minipass<string>\n  streamSync(\n    entry: string | PathBase,\n    opts: WalkOptions,\n  ): Minipass<string> | Minipass<PathBase>\n  streamSync(\n    entry: string | PathBase | WalkOptions = this.cwd,\n    opts: WalkOptions = {},\n  ): Minipass<string> | Minipass<PathBase> {\n    if (typeof entry === 'string') {\n      entry = this.cwd.resolve(entry)\n    } else if (!(entry instanceof PathBase)) {\n      opts = entry\n      entry = this.cwd\n    }\n    const {\n      withFileTypes = true,\n      follow = false,\n      filter,\n      walkFilter,\n    } = opts\n    const results = new Minipass<string | PathBase>({ objectMode: true })\n    const dirs = new Set<PathBase>()\n    if (!filter || filter(entry)) {\n      results.write(withFileTypes ? entry : entry.fullpath())\n    }\n    const queue: PathBase[] = [entry]\n    let processing = 0\n    const process = () => {\n      let paused = false\n      while (!paused) {\n        const dir = queue.shift()\n        if (!dir) {\n          if (processing === 0) results.end()\n          return\n        }\n        processing++\n        dirs.add(dir)\n\n        const entries = dir.readdirSync()\n        for (const e of entries) {\n          if (!filter || filter(e)) {\n            if (!results.write(withFileTypes ? e : e.fullpath())) {\n              paused = true\n            }\n          }\n        }\n        processing--\n        for (const e of entries) {\n          let r: PathBase | undefined = e\n          if (e.isSymbolicLink()) {\n            if (!(follow && (r = e.realpathSync()))) continue\n            if (r.isUnknown()) r.lstatSync()\n          }\n          if (r.shouldWalk(dirs, walkFilter)) {\n            queue.push(r)\n          }\n        }\n      }\n      if (paused && !results.flowing) results.once('drain', process)\n    }\n    process()\n    return results as Minipass<string> | Minipass<PathBase>\n  }\n\n  chdir(path: string | Path = this.cwd) {\n    const oldCwd = this.cwd\n    this.cwd = typeof path === 'string' ? this.cwd.resolve(path) : path\n    this.cwd[setAsCwd](oldCwd)\n  }\n}\n\n/**\n * Options provided to all walk methods.\n */\nexport interface WalkOptions {\n  /**\n   * Return results as {@link PathBase} objects rather than strings.\n   * When set to false, results are fully resolved paths, as returned by\n   * {@link PathBase.fullpath}.\n   * @default true\n   */\n  withFileTypes?: boolean\n\n  /**\n   *  Attempt to read directory entries from symbolic links. Otherwise, only\n   *  actual directories are traversed. Regardless of this setting, a given\n   *  target path will only ever be walked once, meaning that a symbolic link\n   *  to a previously traversed directory will never be followed.\n   *\n   *  Setting this imposes a slight performance penalty, because `readlink`\n   *  must be called on all symbolic links encountered, in order to avoid\n   *  infinite cycles.\n   * @default false\n   */\n  follow?: boolean\n\n  /**\n   * Only return entries where the provided function returns true.\n   *\n   * This will not prevent directories from being traversed, even if they do\n   * not pass the filter, though it will prevent directories themselves from\n   * being included in the result set.  See {@link walkFilter}\n   *\n   * Asynchronous functions are not supported here.\n   *\n   * By default, if no filter is provided, all entries and traversed\n   * directories are included.\n   */\n  filter?: (entry: PathBase) => boolean\n\n  /**\n   * Only traverse directories (and in the case of {@link follow} being set to\n   * true, symbolic links to directories) if the provided function returns\n   * true.\n   *\n   * This will not prevent directories from being included in the result set,\n   * even if they do not pass the supplied filter function.  See {@link filter}\n   * to do that.\n   *\n   * Asynchronous functions are not supported here.\n   */\n  walkFilter?: (entry: PathBase) => boolean\n}\n\nexport type WalkOptionsWithFileTypesUnset = WalkOptions & {\n  withFileTypes?: undefined\n}\nexport type WalkOptionsWithFileTypesTrue = WalkOptions & {\n  withFileTypes: true\n}\nexport type WalkOptionsWithFileTypesFalse = WalkOptions & {\n  withFileTypes: false\n}\n\n/**\n * Windows implementation of {@link PathScurryBase}\n *\n * Defaults to case insensitve, uses `'\\\\'` to generate path strings.  Uses\n * {@link PathWin32} for Path objects.\n */\nexport class PathScurryWin32 extends PathScurryBase {\n  /**\n   * separator for generating path strings\n   */\n  sep: '\\\\' = '\\\\'\n\n  constructor(\n    cwd: URL | string = process.cwd(),\n    opts: PathScurryOpts = {},\n  ) {\n    const { nocase = true } = opts\n    super(cwd, win32, '\\\\', { ...opts, nocase })\n    this.nocase = nocase\n    for (let p: PathBase | undefined = this.cwd; p; p = p.parent) {\n      p.nocase = this.nocase\n    }\n  }\n\n  /**\n   * @internal\n   */\n  parseRootPath(dir: string): string {\n    // if the path starts with a single separator, it's not a UNC, and we'll\n    // just get separator as the root, and driveFromUNC will return \\\n    // In that case, mount \\ on the root from the cwd.\n    return win32.parse(dir).root.toUpperCase()\n  }\n\n  /**\n   * @internal\n   */\n  newRoot(fs: FSValue) {\n    return new PathWin32(\n      this.rootPath,\n      IFDIR,\n      undefined,\n      this.roots,\n      this.nocase,\n      this.childrenCache(),\n      { fs },\n    )\n  }\n\n  /**\n   * Return true if the provided path string is an absolute path\n   */\n  isAbsolute(p: string): boolean {\n    return (\n      p.startsWith('/') || p.startsWith('\\\\') || /^[a-z]:(\\/|\\\\)/i.test(p)\n    )\n  }\n}\n\n/**\n * {@link PathScurryBase} implementation for all posix systems other than Darwin.\n *\n * Defaults to case-sensitive matching, uses `'/'` to generate path strings.\n *\n * Uses {@link PathPosix} for Path objects.\n */\nexport class PathScurryPosix extends PathScurryBase {\n  /**\n   * separator for generating path strings\n   */\n  sep: '/' = '/'\n  constructor(\n    cwd: URL | string = process.cwd(),\n    opts: PathScurryOpts = {},\n  ) {\n    const { nocase = false } = opts\n    super(cwd, posix, '/', { ...opts, nocase })\n    this.nocase = nocase\n  }\n\n  /**\n   * @internal\n   */\n  parseRootPath(_dir: string): string {\n    return '/'\n  }\n\n  /**\n   * @internal\n   */\n  newRoot(fs: FSValue) {\n    return new PathPosix(\n      this.rootPath,\n      IFDIR,\n      undefined,\n      this.roots,\n      this.nocase,\n      this.childrenCache(),\n      { fs },\n    )\n  }\n\n  /**\n   * Return true if the provided path string is an absolute path\n   */\n  isAbsolute(p: string): boolean {\n    return p.startsWith('/')\n  }\n}\n\n/**\n * {@link PathScurryBase} implementation for Darwin (macOS) systems.\n *\n * Defaults to case-insensitive matching, uses `'/'` for generating path\n * strings.\n *\n * Uses {@link PathPosix} for Path objects.\n */\nexport class PathScurryDarwin extends PathScurryPosix {\n  constructor(\n    cwd: URL | string = process.cwd(),\n    opts: PathScurryOpts = {},\n  ) {\n    const { nocase = true } = opts\n    super(cwd, { ...opts, nocase })\n  }\n}\n\n/**\n * Default {@link PathBase} implementation for the current platform.\n *\n * {@link PathWin32} on Windows systems, {@link PathPosix} on all others.\n */\nexport const Path = process.platform === 'win32' ? PathWin32 : PathPosix\nexport type Path = PathBase | InstanceType<typeof Path>\n\n/**\n * Default {@link PathScurryBase} implementation for the current platform.\n *\n * {@link PathScurryWin32} on Windows systems, {@link PathScurryDarwin} on\n * Darwin (macOS) systems, {@link PathScurryPosix} on all others.\n */\nexport const PathScurry:\n  | typeof PathScurryWin32\n  | typeof PathScurryDarwin\n  | typeof PathScurryPosix =\n  process.platform === 'win32' ? PathScurryWin32\n  : process.platform === 'darwin' ? PathScurryDarwin\n  : PathScurryPosix\nexport type PathScurry = PathScurryBase | InstanceType<typeof PathScurry>\n"]}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @module LRUCache\n */\n\n// module-private names and types\ntype Perf = { now: () => number }\nconst perf: Perf =\n  typeof performance === 'object' &&\n  performance &&\n  typeof performance.now === 'function'\n    ? performance\n    : Date\n\nconst warned = new Set<string>()\n\n// either a function or a class\ntype ForC = ((...a: any[]) => any) | { new (...a: any[]): any }\n\n/* c8 ignore start */\nconst PROCESS = (\n  typeof process === 'object' && !!process ? process : {}\n) as { [k: string]: any }\n/* c8 ignore start */\n\nconst emitWarning = (\n  msg: string,\n  type: string,\n  code: string,\n  fn: ForC\n) => {\n  typeof PROCESS.emitWarning === 'function'\n    ? PROCESS.emitWarning(msg, type, code, fn)\n    : console.error(`[${code}] ${type}: ${msg}`)\n}\n\nlet AC = globalThis.AbortController\nlet AS = globalThis.AbortSignal\n\n/* c8 ignore start */\nif (typeof AC === 'undefined') {\n  //@ts-ignore\n  AS = class AbortSignal {\n    onabort?: (...a: any[]) => any\n    _onabort: ((...a: any[]) => any)[] = []\n    reason?: any\n    aborted: boolean = false\n    addEventListener(_: string, fn: (...a: any[]) => any) {\n      this._onabort.push(fn)\n    }\n  }\n  //@ts-ignore\n  AC = class AbortController {\n    constructor() {\n      warnACPolyfill()\n    }\n    signal = new AS()\n    abort(reason: any) {\n      if (this.signal.aborted) return\n      //@ts-ignore\n      this.signal.reason = reason\n      //@ts-ignore\n      this.signal.aborted = true\n      //@ts-ignore\n      for (const fn of this.signal._onabort) {\n        fn(reason)\n      }\n      this.signal.onabort?.(reason)\n    }\n  }\n  let printACPolyfillWarning =\n    PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1'\n  const warnACPolyfill = () => {\n    if (!printACPolyfillWarning) return\n    printACPolyfillWarning = false\n    emitWarning(\n      'AbortController is not defined. If using lru-cache in ' +\n        'node 14, load an AbortController polyfill from the ' +\n        '`node-abort-controller` package. A minimal polyfill is ' +\n        'provided for use by LRUCache.fetch(), but it should not be ' +\n        'relied upon in other contexts (eg, passing it to other APIs that ' +\n        'use AbortController/AbortSignal might have undesirable effects). ' +\n        'You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.',\n      'NO_ABORT_CONTROLLER',\n      'ENOTSUP',\n      warnACPolyfill\n    )\n  }\n}\n/* c8 ignore stop */\n\nconst shouldWarn = (code: string) => !warned.has(code)\n\nconst TYPE = Symbol('type')\nexport type PosInt = number & { [TYPE]: 'Positive Integer' }\nexport type Index = number & { [TYPE]: 'LRUCache Index' }\n\nconst isPosInt = (n: any): n is PosInt =>\n  n && n === Math.floor(n) && n > 0 && isFinite(n)\n\nexport type UintArray = Uint8Array | Uint16Array | Uint32Array\nexport type NumberArray = UintArray | number[]\n\n/* c8 ignore start */\n// This is a little bit ridiculous, tbh.\n// The maximum array length is 2^32-1 or thereabouts on most JS impls.\n// And well before that point, you're caching the entire world, I mean,\n// that's ~32GB of just integers for the next/prev links, plus whatever\n// else to hold that many keys and values.  Just filling the memory with\n// zeroes at init time is brutal when you get that big.\n// But why not be complete?\n// Maybe in the future, these limits will have expanded.\nconst getUintArray = (max: number) =>\n  !isPosInt(max)\n    ? null\n    : max <= Math.pow(2, 8)\n    ? Uint8Array\n    : max <= Math.pow(2, 16)\n    ? Uint16Array\n    : max <= Math.pow(2, 32)\n    ? Uint32Array\n    : max <= Number.MAX_SAFE_INTEGER\n    ? ZeroArray\n    : null\n/* c8 ignore stop */\n\nclass ZeroArray extends Array<number> {\n  constructor(size: number) {\n    super(size)\n    this.fill(0)\n  }\n}\nexport type { ZeroArray }\nexport type { Stack }\n\nexport type StackLike = Stack | Index[]\nclass Stack {\n  heap: NumberArray\n  length: number\n  // private constructor\n  static #constructing: boolean = false\n  static create(max: number): StackLike {\n    const HeapCls = getUintArray(max)\n    if (!HeapCls) return []\n    Stack.#constructing = true\n    const s = new Stack(max, HeapCls)\n    Stack.#constructing = false\n    return s\n  }\n  constructor(\n    max: number,\n    HeapCls: { new (n: number): NumberArray }\n  ) {\n    /* c8 ignore start */\n    if (!Stack.#constructing) {\n      throw new TypeError('instantiate Stack using Stack.create(n)')\n    }\n    /* c8 ignore stop */\n    this.heap = new HeapCls(max)\n    this.length = 0\n  }\n  push(n: Index) {\n    this.heap[this.length++] = n\n  }\n  pop(): Index {\n    return this.heap[--this.length] as Index\n  }\n}\n\n/**\n * Promise representing an in-progress {@link LRUCache#fetch} call\n */\nexport type BackgroundFetch<V> = Promise<V | undefined> & {\n  __returned: BackgroundFetch<V> | undefined\n  __abortController: AbortController\n  __staleWhileFetching: V | undefined\n}\n\nexport type DisposeTask<K, V> = [\n  value: V,\n  key: K,\n  reason: LRUCache.DisposeReason\n]\n\nexport namespace LRUCache {\n  /**\n   * An integer greater than 0, reflecting the calculated size of items\n   */\n  export type Size = number\n\n  /**\n   * Integer greater than 0, representing some number of milliseconds, or the\n   * time at which a TTL started counting from.\n   */\n  export type Milliseconds = number\n\n  /**\n   * An integer greater than 0, reflecting a number of items\n   */\n  export type Count = number\n\n  /**\n   * The reason why an item was removed from the cache, passed\n   * to the {@link Disposer} methods.\n   *\n   * - `evict`: The item was evicted because it is the least recently used,\n   *   and the cache is full.\n   * - `set`: A new value was set, overwriting the old value being disposed.\n   * - `delete`: The item was explicitly deleted, either by calling\n   *   {@link LRUCache#delete}, {@link LRUCache#clear}, or\n   *   {@link LRUCache#set} with an undefined value.\n   * - `expire`: The item was removed due to exceeding its TTL.\n   * - `fetch`: A {@link OptionsBase#fetchMethod} operation returned\n   *   `undefined` or was aborted, causing the item to be deleted.\n   */\n  export type DisposeReason =\n    | 'evict'\n    | 'set'\n    | 'delete'\n    | 'expire'\n    | 'fetch'\n  /**\n   * A method called upon item removal, passed as the\n   * {@link OptionsBase.dispose} and/or\n   * {@link OptionsBase.disposeAfter} options.\n   */\n  export type Disposer<K, V> = (\n    value: V,\n    key: K,\n    reason: DisposeReason\n  ) => void\n\n  /**\n   * A function that returns the effective calculated size\n   * of an entry in the cache.\n   */\n  export type SizeCalculator<K, V> = (value: V, key: K) => Size\n\n  /**\n   * Options provided to the\n   * {@link OptionsBase.fetchMethod} function.\n   */\n  export interface FetcherOptions<K, V, FC = unknown> {\n    signal: AbortSignal\n    options: FetcherFetchOptions<K, V, FC>\n    /**\n     * Object provided in the {@link FetchOptions.context} option to\n     * {@link LRUCache#fetch}\n     */\n    context: FC\n  }\n\n  /**\n   * Occasionally, it may be useful to track the internal behavior of the\n   * cache, particularly for logging, debugging, or for behavior within the\n   * `fetchMethod`. To do this, you can pass a `status` object to the\n   * {@link LRUCache#fetch}, {@link LRUCache#get}, {@link LRUCache#set},\n   * {@link LRUCache#memo}, and {@link LRUCache#has} methods.\n   *\n   * The `status` option should be a plain JavaScript object. The following\n   * fields will be set on it appropriately, depending on the situation.\n   */\n  export interface Status<V> {\n    /**\n     * The status of a set() operation.\n     *\n     * - add: the item was not found in the cache, and was added\n     * - update: the item was in the cache, with the same value provided\n     * - replace: the item was in the cache, and replaced\n     * - miss: the item was not added to the cache for some reason\n     */\n    set?: 'add' | 'update' | 'replace' | 'miss'\n\n    /**\n     * the ttl stored for the item, or undefined if ttls are not used.\n     */\n    ttl?: Milliseconds\n\n    /**\n     * the start time for the item, or undefined if ttls are not used.\n     */\n    start?: Milliseconds\n\n    /**\n     * The timestamp used for TTL calculation\n     */\n    now?: Milliseconds\n\n    /**\n     * the remaining ttl for the item, or undefined if ttls are not used.\n     */\n    remainingTTL?: Milliseconds\n\n    /**\n     * The calculated size for the item, if sizes are used.\n     */\n    entrySize?: Size\n\n    /**\n     * The total calculated size of the cache, if sizes are used.\n     */\n    totalCalculatedSize?: Size\n\n    /**\n     * A flag indicating that the item was not stored, due to exceeding the\n     * {@link OptionsBase.maxEntrySize}\n     */\n    maxEntrySizeExceeded?: true\n\n    /**\n     * The old value, specified in the case of `set:'update'` or\n     * `set:'replace'`\n     */\n    oldValue?: V\n\n    /**\n     * The results of a {@link LRUCache#has} operation\n     *\n     * - hit: the item was found in the cache\n     * - stale: the item was found in the cache, but is stale\n     * - miss: the item was not found in the cache\n     */\n    has?: 'hit' | 'stale' | 'miss'\n\n    /**\n     * The status of a {@link LRUCache#fetch} operation.\n     * Note that this can change as the underlying fetch() moves through\n     * various states.\n     *\n     * - inflight: there is another fetch() for this key which is in process\n     * - get: there is no {@link OptionsBase.fetchMethod}, so\n     *   {@link LRUCache#get} was called.\n     * - miss: the item is not in cache, and will be fetched.\n     * - hit: the item is in the cache, and was resolved immediately.\n     * - stale: the item is in the cache, but stale.\n     * - refresh: the item is in the cache, and not stale, but\n     *   {@link FetchOptions.forceRefresh} was specified.\n     */\n    fetch?: 'get' | 'inflight' | 'miss' | 'hit' | 'stale' | 'refresh'\n\n    /**\n     * The {@link OptionsBase.fetchMethod} was called\n     */\n    fetchDispatched?: true\n\n    /**\n     * The cached value was updated after a successful call to\n     * {@link OptionsBase.fetchMethod}\n     */\n    fetchUpdated?: true\n\n    /**\n     * The reason for a fetch() rejection.  Either the error raised by the\n     * {@link OptionsBase.fetchMethod}, or the reason for an\n     * AbortSignal.\n     */\n    fetchError?: Error\n\n    /**\n     * The fetch received an abort signal\n     */\n    fetchAborted?: true\n\n    /**\n     * The abort signal received was ignored, and the fetch was allowed to\n     * continue.\n     */\n    fetchAbortIgnored?: true\n\n    /**\n     * The fetchMethod promise resolved successfully\n     */\n    fetchResolved?: true\n\n    /**\n     * The fetchMethod promise was rejected\n     */\n    fetchRejected?: true\n\n    /**\n     * The status of a {@link LRUCache#get} operation.\n     *\n     * - fetching: The item is currently being fetched.  If a previous value\n     *   is present and allowed, that will be returned.\n     * - stale: The item is in the cache, and is stale.\n     * - hit: the item is in the cache\n     * - miss: the item is not in the cache\n     */\n    get?: 'stale' | 'hit' | 'miss'\n\n    /**\n     * A fetch or get operation returned a stale value.\n     */\n    returnedStale?: true\n  }\n\n  /**\n   * options which override the options set in the LRUCache constructor\n   * when calling {@link LRUCache#fetch}.\n   *\n   * This is the union of {@link GetOptions} and {@link SetOptions}, plus\n   * {@link OptionsBase.noDeleteOnFetchRejection},\n   * {@link OptionsBase.allowStaleOnFetchRejection},\n   * {@link FetchOptions.forceRefresh}, and\n   * {@link FetcherOptions.context}\n   *\n   * Any of these may be modified in the {@link OptionsBase.fetchMethod}\n   * function, but the {@link GetOptions} fields will of course have no\n   * effect, as the {@link LRUCache#get} call already happened by the time\n   * the fetchMethod is called.\n   */\n  export interface FetcherFetchOptions<K, V, FC = unknown>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      | 'allowStale'\n      | 'updateAgeOnGet'\n      | 'noDeleteOnStaleGet'\n      | 'sizeCalculation'\n      | 'ttl'\n      | 'noDisposeOnSet'\n      | 'noUpdateTTL'\n      | 'noDeleteOnFetchRejection'\n      | 'allowStaleOnFetchRejection'\n      | 'ignoreFetchAbort'\n      | 'allowStaleOnFetchAbort'\n    > {\n    status?: Status<V>\n    size?: Size\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#fetch} method.\n   */\n  export interface FetchOptions<K, V, FC>\n    extends FetcherFetchOptions<K, V, FC> {\n    /**\n     * Set to true to force a re-load of the existing data, even if it\n     * is not yet stale.\n     */\n    forceRefresh?: boolean\n    /**\n     * Context provided to the {@link OptionsBase.fetchMethod} as\n     * the {@link FetcherOptions.context} param.\n     *\n     * If the FC type is specified as unknown (the default),\n     * undefined or void, then this is optional.  Otherwise, it will\n     * be required.\n     */\n    context?: FC\n    signal?: AbortSignal\n    status?: Status<V>\n  }\n  /**\n   * Options provided to {@link LRUCache#fetch} when the FC type is something\n   * other than `unknown`, `undefined`, or `void`\n   */\n  export interface FetchOptionsWithContext<K, V, FC>\n    extends FetchOptions<K, V, FC> {\n    context: FC\n  }\n  /**\n   * Options provided to {@link LRUCache#fetch} when the FC type is\n   * `undefined` or `void`\n   */\n  export interface FetchOptionsNoContext<K, V>\n    extends FetchOptions<K, V, undefined> {\n    context?: undefined\n  }\n\n  export interface MemoOptions<K, V, FC = unknown>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      | 'allowStale'\n      | 'updateAgeOnGet'\n      | 'noDeleteOnStaleGet'\n      | 'sizeCalculation'\n      | 'ttl'\n      | 'noDisposeOnSet'\n      | 'noUpdateTTL'\n      | 'noDeleteOnFetchRejection'\n      | 'allowStaleOnFetchRejection'\n      | 'ignoreFetchAbort'\n      | 'allowStaleOnFetchAbort'\n    > {\n    /**\n     * Set to true to force a re-load of the existing data, even if it\n     * is not yet stale.\n     */\n    forceRefresh?: boolean\n    /**\n     * Context provided to the {@link OptionsBase.memoMethod} as\n     * the {@link MemoizerOptions.context} param.\n     *\n     * If the FC type is specified as unknown (the default),\n     * undefined or void, then this is optional.  Otherwise, it will\n     * be required.\n     */\n    context?: FC\n    status?: Status<V>\n  }\n  /**\n   * Options provided to {@link LRUCache#memo} when the FC type is something\n   * other than `unknown`, `undefined`, or `void`\n   */\n  export interface MemoOptionsWithContext<K, V, FC>\n    extends MemoOptions<K, V, FC> {\n    context: FC\n  }\n  /**\n   * Options provided to {@link LRUCache#memo} when the FC type is\n   * `undefined` or `void`\n   */\n  export interface MemoOptionsNoContext<K, V>\n    extends MemoOptions<K, V, undefined> {\n    context?: undefined\n  }\n\n  /**\n   * Options provided to the\n   * {@link OptionsBase.memoMethod} function.\n   */\n  export interface MemoizerOptions<K, V, FC = unknown> {\n    options: MemoizerMemoOptions<K, V, FC>\n    /**\n     * Object provided in the {@link MemoOptions.context} option to\n     * {@link LRUCache#memo}\n     */\n    context: FC\n  }\n\n  /**\n   * options which override the options set in the LRUCache constructor\n   * when calling {@link LRUCache#memo}.\n   *\n   * This is the union of {@link GetOptions} and {@link SetOptions}, plus\n   * {@link MemoOptions.forceRefresh}, and\n   * {@link MemoerOptions.context}\n   *\n   * Any of these may be modified in the {@link OptionsBase.memoMethod}\n   * function, but the {@link GetOptions} fields will of course have no\n   * effect, as the {@link LRUCache#get} call already happened by the time\n   * the memoMethod is called.\n   */\n  export interface MemoizerMemoOptions<K, V, FC = unknown>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      | 'allowStale'\n      | 'updateAgeOnGet'\n      | 'noDeleteOnStaleGet'\n      | 'sizeCalculation'\n      | 'ttl'\n      | 'noDisposeOnSet'\n      | 'noUpdateTTL'\n    > {\n    status?: Status<V>\n    size?: Size\n    start?: Milliseconds\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#has} method.\n   */\n  export interface HasOptions<K, V, FC>\n    extends Pick<OptionsBase<K, V, FC>, 'updateAgeOnHas'> {\n    status?: Status<V>\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#get} method.\n   */\n  export interface GetOptions<K, V, FC>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet'\n    > {\n    status?: Status<V>\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#peek} method.\n   */\n  export interface PeekOptions<K, V, FC>\n    extends Pick<OptionsBase<K, V, FC>, 'allowStale'> {}\n\n  /**\n   * Options that may be passed to the {@link LRUCache#set} method.\n   */\n  export interface SetOptions<K, V, FC>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL'\n    > {\n    /**\n     * If size tracking is enabled, then setting an explicit size\n     * in the {@link LRUCache#set} call will prevent calling the\n     * {@link OptionsBase.sizeCalculation} function.\n     */\n    size?: Size\n    /**\n     * If TTL tracking is enabled, then setting an explicit start\n     * time in the {@link LRUCache#set} call will override the\n     * default time from `performance.now()` or `Date.now()`.\n     *\n     * Note that it must be a valid value for whichever time-tracking\n     * method is in use.\n     */\n    start?: Milliseconds\n    status?: Status<V>\n  }\n\n  /**\n   * The type signature for the {@link OptionsBase.fetchMethod} option.\n   */\n  export type Fetcher<K, V, FC = unknown> = (\n    key: K,\n    staleValue: V | undefined,\n    options: FetcherOptions<K, V, FC>\n  ) => Promise<V | undefined | void> | V | undefined | void\n\n  /**\n   * the type signature for the {@link OptionsBase.memoMethod} option.\n   */\n  export type Memoizer<K, V, FC = unknown> = (\n    key: K,\n    staleValue: V | undefined,\n    options: MemoizerOptions<K, V, FC>\n  ) => V\n\n  /**\n   * Options which may be passed to the {@link LRUCache} constructor.\n   *\n   * Most of these may be overridden in the various options that use\n   * them.\n   *\n   * Despite all being technically optional, the constructor requires that\n   * a cache is at minimum limited by one or more of {@link OptionsBase.max},\n   * {@link OptionsBase.ttl}, or {@link OptionsBase.maxSize}.\n   *\n   * If {@link OptionsBase.ttl} is used alone, then it is strongly advised\n   * (and in fact required by the type definitions here) that the cache\n   * also set {@link OptionsBase.ttlAutopurge}, to prevent potentially\n   * unbounded storage.\n   *\n   * All options are also available on the {@link LRUCache} instance, making\n   * it safe to pass an LRUCache instance as the options argumemnt to\n   * make another empty cache of the same type.\n   *\n   * Some options are marked as read-only, because changing them after\n   * instantiation is not safe. Changing any of the other options will of\n   * course only have an effect on subsequent method calls.\n   */\n  export interface OptionsBase<K, V, FC> {\n    /**\n     * The maximum number of items to store in the cache before evicting\n     * old entries. This is read-only on the {@link LRUCache} instance,\n     * and may not be overridden.\n     *\n     * If set, then storage space will be pre-allocated at construction\n     * time, and the cache will perform significantly faster.\n     *\n     * Note that significantly fewer items may be stored, if\n     * {@link OptionsBase.maxSize} and/or {@link OptionsBase.ttl} are also\n     * set.\n     *\n     * **It is strongly recommended to set a `max` to prevent unbounded growth\n     * of the cache.**\n     */\n    max?: Count\n\n    /**\n     * Max time in milliseconds for items to live in cache before they are\n     * considered stale.  Note that stale items are NOT preemptively removed by\n     * default, and MAY live in the cache, contributing to its LRU max, long\n     * after they have expired, unless {@link OptionsBase.ttlAutopurge} is\n     * set.\n     *\n     * If set to `0` (the default value), then that means \"do not track\n     * TTL\", not \"expire immediately\".\n     *\n     * Also, as this cache is optimized for LRU/MRU operations, some of\n     * the staleness/TTL checks will reduce performance, as they will incur\n     * overhead by deleting items.\n     *\n     * This is not primarily a TTL cache, and does not make strong TTL\n     * guarantees. There is no pre-emptive pruning of expired items, but you\n     * _may_ set a TTL on the cache, and it will treat expired items as missing\n     * when they are fetched, and delete them.\n     *\n     * Optional, but must be a non-negative integer in ms if specified.\n     *\n     * This may be overridden by passing an options object to `cache.set()`.\n     *\n     * At least one of `max`, `maxSize`, or `TTL` is required. This must be a\n     * positive integer if set.\n     *\n     * Even if ttl tracking is enabled, **it is strongly recommended to set a\n     * `max` to prevent unbounded growth of the cache.**\n     *\n     * If ttl tracking is enabled, and `max` and `maxSize` are not set,\n     * and `ttlAutopurge` is not set, then a warning will be emitted\n     * cautioning about the potential for unbounded memory consumption.\n     * (The TypeScript definitions will also discourage this.)\n     */\n    ttl?: Milliseconds\n\n    /**\n     * Minimum amount of time in ms in which to check for staleness.\n     * Defaults to 1, which means that the current time is checked\n     * at most once per millisecond.\n     *\n     * Set to 0 to check the current time every time staleness is tested.\n     * (This reduces performance, and is theoretically unnecessary.)\n     *\n     * Setting this to a higher value will improve performance somewhat\n     * while using ttl tracking, albeit at the expense of keeping stale\n     * items around a bit longer than their TTLs would indicate.\n     *\n     * @default 1\n     */\n    ttlResolution?: Milliseconds\n\n    /**\n     * Preemptively remove stale items from the cache.\n     *\n     * Note that this may *significantly* degrade performance, especially if\n     * the cache is storing a large number of items. It is almost always best\n     * to just leave the stale items in the cache, and let them fall out as new\n     * items are added.\n     *\n     * Note that this means that {@link OptionsBase.allowStale} is a bit\n     * pointless, as stale items will be deleted almost as soon as they\n     * expire.\n     *\n     * Use with caution!\n     */\n    ttlAutopurge?: boolean\n\n    /**\n     * When using time-expiring entries with `ttl`, setting this to `true` will\n     * make each item's age reset to 0 whenever it is retrieved from cache with\n     * {@link LRUCache#get}, causing it to not expire. (It can still fall out\n     * of cache based on recency of use, of course.)\n     *\n     * Has no effect if {@link OptionsBase.ttl} is not set.\n     *\n     * This may be overridden by passing an options object to `cache.get()`.\n     */\n    updateAgeOnGet?: boolean\n\n    /**\n     * When using time-expiring entries with `ttl`, setting this to `true` will\n     * make each item's age reset to 0 whenever its presence in the cache is\n     * checked with {@link LRUCache#has}, causing it to not expire. (It can\n     * still fall out of cache based on recency of use, of course.)\n     *\n     * Has no effect if {@link OptionsBase.ttl} is not set.\n     */\n    updateAgeOnHas?: boolean\n\n    /**\n     * Allow {@link LRUCache#get} and {@link LRUCache#fetch} calls to return\n     * stale data, if available.\n     *\n     * By default, if you set `ttl`, stale items will only be deleted from the\n     * cache when you `get(key)`. That is, it's not preemptively pruning items,\n     * unless {@link OptionsBase.ttlAutopurge} is set.\n     *\n     * If you set `allowStale:true`, it'll return the stale value *as well as*\n     * deleting it. If you don't set this, then it'll return `undefined` when\n     * you try to get a stale entry.\n     *\n     * Note that when a stale entry is fetched, _even if it is returned due to\n     * `allowStale` being set_, it is removed from the cache immediately. You\n     * can suppress this behavior by setting\n     * {@link OptionsBase.noDeleteOnStaleGet}, either in the constructor, or in\n     * the options provided to {@link LRUCache#get}.\n     *\n     * This may be overridden by passing an options object to `cache.get()`.\n     * The `cache.has()` method will always return `false` for stale items.\n     *\n     * Only relevant if a ttl is set.\n     */\n    allowStale?: boolean\n\n    /**\n     * Function that is called on items when they are dropped from the\n     * cache, as `dispose(value, key, reason)`.\n     *\n     * This can be handy if you want to close file descriptors or do\n     * other cleanup tasks when items are no longer stored in the cache.\n     *\n     * **NOTE**: It is called _before_ the item has been fully removed\n     * from the cache, so if you want to put it right back in, you need\n     * to wait until the next tick. If you try to add it back in during\n     * the `dispose()` function call, it will break things in subtle and\n     * weird ways.\n     *\n     * Unlike several other options, this may _not_ be overridden by\n     * passing an option to `set()`, for performance reasons.\n     *\n     * The `reason` will be one of the following strings, corresponding\n     * to the reason for the item's deletion:\n     *\n     * - `evict` Item was evicted to make space for a new addition\n     * - `set` Item was overwritten by a new value\n     * - `expire` Item expired its TTL\n     * - `fetch` Item was deleted due to a failed or aborted fetch, or a\n     *   fetchMethod returning `undefined.\n     * - `delete` Item was removed by explicit `cache.delete(key)`,\n     *   `cache.clear()`, or `cache.set(key, undefined)`.\n     */\n    dispose?: Disposer<K, V>\n\n    /**\n     * The same as {@link OptionsBase.dispose}, but called *after* the entry\n     * is completely removed and the cache is once again in a clean state.\n     *\n     * It is safe to add an item right back into the cache at this point.\n     * However, note that it is *very* easy to inadvertently create infinite\n     * recursion this way.\n     */\n    disposeAfter?: Disposer<K, V>\n\n    /**\n     * Set to true to suppress calling the\n     * {@link OptionsBase.dispose} function if the entry key is\n     * still accessible within the cache.\n     *\n     * This may be overridden by passing an options object to\n     * {@link LRUCache#set}.\n     *\n     * Only relevant if `dispose` or `disposeAfter` are set.\n     */\n    noDisposeOnSet?: boolean\n\n    /**\n     * Boolean flag to tell the cache to not update the TTL when setting a new\n     * value for an existing key (ie, when updating a value rather than\n     * inserting a new value).  Note that the TTL value is _always_ set (if\n     * provided) when adding a new entry into the cache.\n     *\n     * Has no effect if a {@link OptionsBase.ttl} is not set.\n     *\n     * May be passed as an option to {@link LRUCache#set}.\n     */\n    noUpdateTTL?: boolean\n\n    /**\n     * Set to a positive integer to track the sizes of items added to the\n     * cache, and automatically evict items in order to stay below this size.\n     * Note that this may result in fewer than `max` items being stored.\n     *\n     * Attempting to add an item to the cache whose calculated size is greater\n     * that this amount will be a no-op. The item will not be cached, and no\n     * other items will be evicted.\n     *\n     * Optional, must be a positive integer if provided.\n     *\n     * Sets `maxEntrySize` to the same value, unless a different value is\n     * provided for `maxEntrySize`.\n     *\n     * At least one of `max`, `maxSize`, or `TTL` is required. This must be a\n     * positive integer if set.\n     *\n     * Even if size tracking is enabled, **it is strongly recommended to set a\n     * `max` to prevent unbounded growth of the cache.**\n     *\n     * Note also that size tracking can negatively impact performance,\n     * though for most cases, only minimally.\n     */\n    maxSize?: Size\n\n    /**\n     * The maximum allowed size for any single item in the cache.\n     *\n     * If a larger item is passed to {@link LRUCache#set} or returned by a\n     * {@link OptionsBase.fetchMethod} or {@link OptionsBase.memoMethod}, then\n     * it will not be stored in the cache.\n     *\n     * Attempting to add an item whose calculated size is greater than\n     * this amount will not cache the item or evict any old items, but\n     * WILL delete an existing value if one is already present.\n     *\n     * Optional, must be a positive integer if provided. Defaults to\n     * the value of `maxSize` if provided.\n     */\n    maxEntrySize?: Size\n\n    /**\n     * A function that returns a number indicating the item's size.\n     *\n     * Requires {@link OptionsBase.maxSize} to be set.\n     *\n     * If not provided, and {@link OptionsBase.maxSize} or\n     * {@link OptionsBase.maxEntrySize} are set, then all\n     * {@link LRUCache#set} calls **must** provide an explicit\n     * {@link SetOptions.size} or sizeCalculation param.\n     */\n    sizeCalculation?: SizeCalculator<K, V>\n\n    /**\n     * Method that provides the implementation for {@link LRUCache#fetch}\n     *\n     * ```ts\n     * fetchMethod(key, staleValue, { signal, options, context })\n     * ```\n     *\n     * If `fetchMethod` is not provided, then `cache.fetch(key)` is equivalent\n     * to `Promise.resolve(cache.get(key))`.\n     *\n     * If at any time, `signal.aborted` is set to `true`, or if the\n     * `signal.onabort` method is called, or if it emits an `'abort'` event\n     * which you can listen to with `addEventListener`, then that means that\n     * the fetch should be abandoned. This may be passed along to async\n     * functions aware of AbortController/AbortSignal behavior.\n     *\n     * The `fetchMethod` should **only** return `undefined` or a Promise\n     * resolving to `undefined` if the AbortController signaled an `abort`\n     * event. In all other cases, it should return or resolve to a value\n     * suitable for adding to the cache.\n     *\n     * The `options` object is a union of the options that may be provided to\n     * `set()` and `get()`. If they are modified, then that will result in\n     * modifying the settings to `cache.set()` when the value is resolved, and\n     * in the case of\n     * {@link OptionsBase.noDeleteOnFetchRejection} and\n     * {@link OptionsBase.allowStaleOnFetchRejection}, the handling of\n     * `fetchMethod` failures.\n     *\n     * For example, a DNS cache may update the TTL based on the value returned\n     * from a remote DNS server by changing `options.ttl` in the `fetchMethod`.\n     */\n    fetchMethod?: Fetcher<K, V, FC>\n\n    /**\n     * Method that provides the implementation for {@link LRUCache#memo}\n     */\n    memoMethod?: Memoizer<K, V, FC>\n\n    /**\n     * Set to true to suppress the deletion of stale data when a\n     * {@link OptionsBase.fetchMethod} returns a rejected promise.\n     */\n    noDeleteOnFetchRejection?: boolean\n\n    /**\n     * Do not delete stale items when they are retrieved with\n     * {@link LRUCache#get}.\n     *\n     * Note that the `get` return value will still be `undefined`\n     * unless {@link OptionsBase.allowStale} is true.\n     *\n     * When using time-expiring entries with `ttl`, by default stale\n     * items will be removed from the cache when the key is accessed\n     * with `cache.get()`.\n     *\n     * Setting this option will cause stale items to remain in the cache, until\n     * they are explicitly deleted with `cache.delete(key)`, or retrieved with\n     * `noDeleteOnStaleGet` set to `false`.\n     *\n     * This may be overridden by passing an options object to `cache.get()`.\n     *\n     * Only relevant if a ttl is used.\n     */\n    noDeleteOnStaleGet?: boolean\n\n    /**\n     * Set to true to allow returning stale data when a\n     * {@link OptionsBase.fetchMethod} throws an error or returns a rejected\n     * promise.\n     *\n     * This differs from using {@link OptionsBase.allowStale} in that stale\n     * data will ONLY be returned in the case that the {@link LRUCache#fetch}\n     * fails, not any other times.\n     *\n     * If a `fetchMethod` fails, and there is no stale value available, the\n     * `fetch()` will resolve to `undefined`. Ie, all `fetchMethod` errors are\n     * suppressed.\n     *\n     * Implies `noDeleteOnFetchRejection`.\n     *\n     * This may be set in calls to `fetch()`, or defaulted on the constructor,\n     * or overridden by modifying the options object in the `fetchMethod`.\n     */\n    allowStaleOnFetchRejection?: boolean\n\n    /**\n     * Set to true to return a stale value from the cache when the\n     * `AbortSignal` passed to the {@link OptionsBase.fetchMethod} dispatches\n     * an `'abort'` event, whether user-triggered, or due to internal cache\n     * behavior.\n     *\n     * Unless {@link OptionsBase.ignoreFetchAbort} is also set, the underlying\n     * {@link OptionsBase.fetchMethod} will still be considered canceled, and\n     * any value it returns will be ignored and not cached.\n     *\n     * Caveat: since fetches are aborted when a new value is explicitly\n     * set in the cache, this can lead to fetch returning a stale value,\n     * since that was the fallback value _at the moment the `fetch()` was\n     * initiated_, even though the new updated value is now present in\n     * the cache.\n     *\n     * For example:\n     *\n     * ```ts\n     * const cache = new LRUCache<string, any>({\n     *   ttl: 100,\n     *   fetchMethod: async (url, oldValue, { signal }) =>  {\n     *     const res = await fetch(url, { signal })\n     *     return await res.json()\n     *   }\n     * })\n     * cache.set('https://example.com/', { some: 'data' })\n     * // 100ms go by...\n     * const result = cache.fetch('https://example.com/')\n     * cache.set('https://example.com/', { other: 'thing' })\n     * console.log(await result) // { some: 'data' }\n     * console.log(cache.get('https://example.com/')) // { other: 'thing' }\n     * ```\n     */\n    allowStaleOnFetchAbort?: boolean\n\n    /**\n     * Set to true to ignore the `abort` event emitted by the `AbortSignal`\n     * object passed to {@link OptionsBase.fetchMethod}, and still cache the\n     * resulting resolution value, as long as it is not `undefined`.\n     *\n     * When used on its own, this means aborted {@link LRUCache#fetch} calls\n     * are not immediately resolved or rejected when they are aborted, and\n     * instead take the full time to await.\n     *\n     * When used with {@link OptionsBase.allowStaleOnFetchAbort}, aborted\n     * {@link LRUCache#fetch} calls will resolve immediately to their stale\n     * cached value or `undefined`, and will continue to process and eventually\n     * update the cache when they resolve, as long as the resulting value is\n     * not `undefined`, thus supporting a \"return stale on timeout while\n     * refreshing\" mechanism by passing `AbortSignal.timeout(n)` as the signal.\n     *\n     * For example:\n     *\n     * ```ts\n     * const c = new LRUCache({\n     *   ttl: 100,\n     *   ignoreFetchAbort: true,\n     *   allowStaleOnFetchAbort: true,\n     *   fetchMethod: async (key, oldValue, { signal }) => {\n     *     // note: do NOT pass the signal to fetch()!\n     *     // let's say this fetch can take a long time.\n     *     const res = await fetch(`https://slow-backend-server/${key}`)\n     *     return await res.json()\n     *   },\n     * })\n     *\n     * // this will return the stale value after 100ms, while still\n     * // updating in the background for next time.\n     * const val = await c.fetch('key', { signal: AbortSignal.timeout(100) })\n     * ```\n     *\n     * **Note**: regardless of this setting, an `abort` event _is still\n     * emitted on the `AbortSignal` object_, so may result in invalid results\n     * when passed to other underlying APIs that use AbortSignals.\n     *\n     * This may be overridden in the {@link OptionsBase.fetchMethod} or the\n     * call to {@link LRUCache#fetch}.\n     */\n    ignoreFetchAbort?: boolean\n  }\n\n  export interface OptionsMaxLimit<K, V, FC>\n    extends OptionsBase<K, V, FC> {\n    max: Count\n  }\n  export interface OptionsTTLLimit<K, V, FC>\n    extends OptionsBase<K, V, FC> {\n    ttl: Milliseconds\n    ttlAutopurge: boolean\n  }\n  export interface OptionsSizeLimit<K, V, FC>\n    extends OptionsBase<K, V, FC> {\n    maxSize: Size\n  }\n\n  /**\n   * The valid safe options for the {@link LRUCache} constructor\n   */\n  export type Options<K, V, FC> =\n    | OptionsMaxLimit<K, V, FC>\n    | OptionsSizeLimit<K, V, FC>\n    | OptionsTTLLimit<K, V, FC>\n\n  /**\n   * Entry objects used by {@link LRUCache#load} and {@link LRUCache#dump},\n   * and returned by {@link LRUCache#info}.\n   */\n  export interface Entry<V> {\n    value: V\n    ttl?: Milliseconds\n    size?: Size\n    start?: Milliseconds\n  }\n}\n\n/**\n * Default export, the thing you're using this module to get.\n *\n * The `K` and `V` types define the key and value types, respectively. The\n * optional `FC` type defines the type of the `context` object passed to\n * `cache.fetch()` and `cache.memo()`.\n *\n * Keys and values **must not** be `null` or `undefined`.\n *\n * All properties from the options object (with the exception of `max`,\n * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are\n * added as normal public members. (The listed options are read-only getters.)\n *\n * Changing any of these will alter the defaults for subsequent method calls.\n */\nexport class LRUCache<K extends {}, V extends {}, FC = unknown>\n  implements Map<K, V>\n{\n  // options that cannot be changed without disaster\n  readonly #max: LRUCache.Count\n  readonly #maxSize: LRUCache.Size\n  readonly #dispose?: LRUCache.Disposer<K, V>\n  readonly #disposeAfter?: LRUCache.Disposer<K, V>\n  readonly #fetchMethod?: LRUCache.Fetcher<K, V, FC>\n  readonly #memoMethod?: LRUCache.Memoizer<K, V, FC>\n\n  /**\n   * {@link LRUCache.OptionsBase.ttl}\n   */\n  ttl: LRUCache.Milliseconds\n\n  /**\n   * {@link LRUCache.OptionsBase.ttlResolution}\n   */\n  ttlResolution: LRUCache.Milliseconds\n  /**\n   * {@link LRUCache.OptionsBase.ttlAutopurge}\n   */\n  ttlAutopurge: boolean\n  /**\n   * {@link LRUCache.OptionsBase.updateAgeOnGet}\n   */\n  updateAgeOnGet: boolean\n  /**\n   * {@link LRUCache.OptionsBase.updateAgeOnHas}\n   */\n  updateAgeOnHas: boolean\n  /**\n   * {@link LRUCache.OptionsBase.allowStale}\n   */\n  allowStale: boolean\n\n  /**\n   * {@link LRUCache.OptionsBase.noDisposeOnSet}\n   */\n  noDisposeOnSet: boolean\n  /**\n   * {@link LRUCache.OptionsBase.noUpdateTTL}\n   */\n  noUpdateTTL: boolean\n  /**\n   * {@link LRUCache.OptionsBase.maxEntrySize}\n   */\n  maxEntrySize: LRUCache.Size\n  /**\n   * {@link LRUCache.OptionsBase.sizeCalculation}\n   */\n  sizeCalculation?: LRUCache.SizeCalculator<K, V>\n  /**\n   * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}\n   */\n  noDeleteOnFetchRejection: boolean\n  /**\n   * {@link LRUCache.OptionsBase.noDeleteOnStaleGet}\n   */\n  noDeleteOnStaleGet: boolean\n  /**\n   * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}\n   */\n  allowStaleOnFetchAbort: boolean\n  /**\n   * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}\n   */\n  allowStaleOnFetchRejection: boolean\n  /**\n   * {@link LRUCache.OptionsBase.ignoreFetchAbort}\n   */\n  ignoreFetchAbort: boolean\n\n  // computed properties\n  #size: LRUCache.Count\n  #calculatedSize: LRUCache.Size\n  #keyMap: Map<K, Index>\n  #keyList: (K | undefined)[]\n  #valList: (V | BackgroundFetch<V> | undefined)[]\n  #next: NumberArray\n  #prev: NumberArray\n  #head: Index\n  #tail: Index\n  #free: StackLike\n  #disposed?: DisposeTask<K, V>[]\n  #sizes?: ZeroArray\n  #starts?: ZeroArray\n  #ttls?: ZeroArray\n\n  #hasDispose: boolean\n  #hasFetchMethod: boolean\n  #hasDisposeAfter: boolean\n\n  /**\n   * Do not call this method unless you need to inspect the\n   * inner workings of the cache.  If anything returned by this\n   * object is modified in any way, strange breakage may occur.\n   *\n   * These fields are private for a reason!\n   *\n   * @internal\n   */\n  static unsafeExposeInternals<\n    K extends {},\n    V extends {},\n    FC extends unknown = unknown\n  >(c: LRUCache<K, V, FC>) {\n    return {\n      // properties\n      starts: c.#starts,\n      ttls: c.#ttls,\n      sizes: c.#sizes,\n      keyMap: c.#keyMap as Map<K, number>,\n      keyList: c.#keyList,\n      valList: c.#valList,\n      next: c.#next,\n      prev: c.#prev,\n      get head() {\n        return c.#head\n      },\n      get tail() {\n        return c.#tail\n      },\n      free: c.#free,\n      // methods\n      isBackgroundFetch: (p: any) => c.#isBackgroundFetch(p),\n      backgroundFetch: (\n        k: K,\n        index: number | undefined,\n        options: LRUCache.FetchOptions<K, V, FC>,\n        context: any\n      ): BackgroundFetch<V> =>\n        c.#backgroundFetch(\n          k,\n          index as Index | undefined,\n          options,\n          context\n        ),\n      moveToTail: (index: number): void =>\n        c.#moveToTail(index as Index),\n      indexes: (options?: { allowStale: boolean }) =>\n        c.#indexes(options),\n      rindexes: (options?: { allowStale: boolean }) =>\n        c.#rindexes(options),\n      isStale: (index: number | undefined) =>\n        c.#isStale(index as Index),\n    }\n  }\n\n  // Protected read-only members\n\n  /**\n   * {@link LRUCache.OptionsBase.max} (read-only)\n   */\n  get max(): LRUCache.Count {\n    return this.#max\n  }\n  /**\n   * {@link LRUCache.OptionsBase.maxSize} (read-only)\n   */\n  get maxSize(): LRUCache.Count {\n    return this.#maxSize\n  }\n  /**\n   * The total computed size of items in the cache (read-only)\n   */\n  get calculatedSize(): LRUCache.Size {\n    return this.#calculatedSize\n  }\n  /**\n   * The number of items stored in the cache (read-only)\n   */\n  get size(): LRUCache.Count {\n    return this.#size\n  }\n  /**\n   * {@link LRUCache.OptionsBase.fetchMethod} (read-only)\n   */\n  get fetchMethod(): LRUCache.Fetcher<K, V, FC> | undefined {\n    return this.#fetchMethod\n  }\n  get memoMethod(): LRUCache.Memoizer<K, V, FC> | undefined {\n    return this.#memoMethod\n  }\n  /**\n   * {@link LRUCache.OptionsBase.dispose} (read-only)\n   */\n  get dispose() {\n    return this.#dispose\n  }\n  /**\n   * {@link LRUCache.OptionsBase.disposeAfter} (read-only)\n   */\n  get disposeAfter() {\n    return this.#disposeAfter\n  }\n\n  constructor(\n    options: LRUCache.Options<K, V, FC> | LRUCache<K, V, FC>\n  ) {\n    const {\n      max = 0,\n      ttl,\n      ttlResolution = 1,\n      ttlAutopurge,\n      updateAgeOnGet,\n      updateAgeOnHas,\n      allowStale,\n      dispose,\n      disposeAfter,\n      noDisposeOnSet,\n      noUpdateTTL,\n      maxSize = 0,\n      maxEntrySize = 0,\n      sizeCalculation,\n      fetchMethod,\n      memoMethod,\n      noDeleteOnFetchRejection,\n      noDeleteOnStaleGet,\n      allowStaleOnFetchRejection,\n      allowStaleOnFetchAbort,\n      ignoreFetchAbort,\n    } = options\n\n    if (max !== 0 && !isPosInt(max)) {\n      throw new TypeError('max option must be a nonnegative integer')\n    }\n\n    const UintArray = max ? getUintArray(max) : Array\n    if (!UintArray) {\n      throw new Error('invalid max value: ' + max)\n    }\n\n    this.#max = max\n    this.#maxSize = maxSize\n    this.maxEntrySize = maxEntrySize || this.#maxSize\n    this.sizeCalculation = sizeCalculation\n    if (this.sizeCalculation) {\n      if (!this.#maxSize && !this.maxEntrySize) {\n        throw new TypeError(\n          'cannot set sizeCalculation without setting maxSize or maxEntrySize'\n        )\n      }\n      if (typeof this.sizeCalculation !== 'function') {\n        throw new TypeError('sizeCalculation set to non-function')\n      }\n    }\n\n    if (\n      memoMethod !== undefined &&\n      typeof memoMethod !== 'function'\n    ) {\n      throw new TypeError('memoMethod must be a function if defined')\n    }\n    this.#memoMethod = memoMethod\n\n    if (\n      fetchMethod !== undefined &&\n      typeof fetchMethod !== 'function'\n    ) {\n      throw new TypeError(\n        'fetchMethod must be a function if specified'\n      )\n    }\n    this.#fetchMethod = fetchMethod\n    this.#hasFetchMethod = !!fetchMethod\n\n    this.#keyMap = new Map()\n    this.#keyList = new Array(max).fill(undefined)\n    this.#valList = new Array(max).fill(undefined)\n    this.#next = new UintArray(max)\n    this.#prev = new UintArray(max)\n    this.#head = 0 as Index\n    this.#tail = 0 as Index\n    this.#free = Stack.create(max)\n    this.#size = 0\n    this.#calculatedSize = 0\n\n    if (typeof dispose === 'function') {\n      this.#dispose = dispose\n    }\n    if (typeof disposeAfter === 'function') {\n      this.#disposeAfter = disposeAfter\n      this.#disposed = []\n    } else {\n      this.#disposeAfter = undefined\n      this.#disposed = undefined\n    }\n    this.#hasDispose = !!this.#dispose\n    this.#hasDisposeAfter = !!this.#disposeAfter\n\n    this.noDisposeOnSet = !!noDisposeOnSet\n    this.noUpdateTTL = !!noUpdateTTL\n    this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection\n    this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection\n    this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort\n    this.ignoreFetchAbort = !!ignoreFetchAbort\n\n    // NB: maxEntrySize is set to maxSize if it's set\n    if (this.maxEntrySize !== 0) {\n      if (this.#maxSize !== 0) {\n        if (!isPosInt(this.#maxSize)) {\n          throw new TypeError(\n            'maxSize must be a positive integer if specified'\n          )\n        }\n      }\n      if (!isPosInt(this.maxEntrySize)) {\n        throw new TypeError(\n          'maxEntrySize must be a positive integer if specified'\n        )\n      }\n      this.#initializeSizeTracking()\n    }\n\n    this.allowStale = !!allowStale\n    this.noDeleteOnStaleGet = !!noDeleteOnStaleGet\n    this.updateAgeOnGet = !!updateAgeOnGet\n    this.updateAgeOnHas = !!updateAgeOnHas\n    this.ttlResolution =\n      isPosInt(ttlResolution) || ttlResolution === 0\n        ? ttlResolution\n        : 1\n    this.ttlAutopurge = !!ttlAutopurge\n    this.ttl = ttl || 0\n    if (this.ttl) {\n      if (!isPosInt(this.ttl)) {\n        throw new TypeError(\n          'ttl must be a positive integer if specified'\n        )\n      }\n      this.#initializeTTLTracking()\n    }\n\n    // do not allow completely unbounded caches\n    if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) {\n      throw new TypeError(\n        'At least one of max, maxSize, or ttl is required'\n      )\n    }\n    if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {\n      const code = 'LRU_CACHE_UNBOUNDED'\n      if (shouldWarn(code)) {\n        warned.add(code)\n        const msg =\n          'TTL caching without ttlAutopurge, max, or maxSize can ' +\n          'result in unbounded memory consumption.'\n        emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache)\n      }\n    }\n  }\n\n  /**\n   * Return the number of ms left in the item's TTL. If item is not in cache,\n   * returns `0`. Returns `Infinity` if item is in cache without a defined TTL.\n   */\n  getRemainingTTL(key: K) {\n    return this.#keyMap.has(key) ? Infinity : 0\n  }\n\n  #initializeTTLTracking() {\n    const ttls = new ZeroArray(this.#max)\n    const starts = new ZeroArray(this.#max)\n    this.#ttls = ttls\n    this.#starts = starts\n\n    this.#setItemTTL = (index, ttl, start = perf.now()) => {\n      starts[index] = ttl !== 0 ? start : 0\n      ttls[index] = ttl\n      if (ttl !== 0 && this.ttlAutopurge) {\n        const t = setTimeout(() => {\n          if (this.#isStale(index)) {\n            this.#delete(this.#keyList[index] as K, 'expire')\n          }\n        }, ttl + 1)\n        // unref() not supported on all platforms\n        /* c8 ignore start */\n        if (t.unref) {\n          t.unref()\n        }\n        /* c8 ignore stop */\n      }\n    }\n\n    this.#updateItemAge = index => {\n      starts[index] = ttls[index] !== 0 ? perf.now() : 0\n    }\n\n    this.#statusTTL = (status, index) => {\n      if (ttls[index]) {\n        const ttl = ttls[index]\n        const start = starts[index]\n        /* c8 ignore next */\n        if (!ttl || !start) return\n        status.ttl = ttl\n        status.start = start\n        status.now = cachedNow || getNow()\n        const age = status.now - start\n        status.remainingTTL = ttl - age\n      }\n    }\n\n    // debounce calls to perf.now() to 1s so we're not hitting\n    // that costly call repeatedly.\n    let cachedNow = 0\n    const getNow = () => {\n      const n = perf.now()\n      if (this.ttlResolution > 0) {\n        cachedNow = n\n        const t = setTimeout(\n          () => (cachedNow = 0),\n          this.ttlResolution\n        )\n        // not available on all platforms\n        /* c8 ignore start */\n        if (t.unref) {\n          t.unref()\n        }\n        /* c8 ignore stop */\n      }\n      return n\n    }\n\n    this.getRemainingTTL = key => {\n      const index = this.#keyMap.get(key)\n      if (index === undefined) {\n        return 0\n      }\n      const ttl = ttls[index]\n      const start = starts[index]\n      if (!ttl || !start) {\n        return Infinity\n      }\n      const age = (cachedNow || getNow()) - start\n      return ttl - age\n    }\n\n    this.#isStale = index => {\n      const s = starts[index]\n      const t = ttls[index]\n      return !!t && !!s && (cachedNow || getNow()) - s > t\n    }\n  }\n\n  // conditionally set private methods related to TTL\n  #updateItemAge: (index: Index) => void = () => {}\n  #statusTTL: (status: LRUCache.Status<V>, index: Index) => void =\n    () => {}\n  #setItemTTL: (\n    index: Index,\n    ttl: LRUCache.Milliseconds,\n    start?: LRUCache.Milliseconds\n    // ignore because we never call this if we're not already in TTL mode\n    /* c8 ignore start */\n  ) => void = () => {}\n  /* c8 ignore stop */\n\n  #isStale: (index: Index) => boolean = () => false\n\n  #initializeSizeTracking() {\n    const sizes = new ZeroArray(this.#max)\n    this.#calculatedSize = 0\n    this.#sizes = sizes\n    this.#removeItemSize = index => {\n      this.#calculatedSize -= sizes[index] as number\n      sizes[index] = 0\n    }\n    this.#requireSize = (k, v, size, sizeCalculation) => {\n      // provisionally accept background fetches.\n      // actual value size will be checked when they return.\n      if (this.#isBackgroundFetch(v)) {\n        return 0\n      }\n      if (!isPosInt(size)) {\n        if (sizeCalculation) {\n          if (typeof sizeCalculation !== 'function') {\n            throw new TypeError('sizeCalculation must be a function')\n          }\n          size = sizeCalculation(v, k)\n          if (!isPosInt(size)) {\n            throw new TypeError(\n              'sizeCalculation return invalid (expect positive integer)'\n            )\n          }\n        } else {\n          throw new TypeError(\n            'invalid size value (must be positive integer). ' +\n              'When maxSize or maxEntrySize is used, sizeCalculation ' +\n              'or size must be set.'\n          )\n        }\n      }\n      return size\n    }\n    this.#addItemSize = (\n      index: Index,\n      size: LRUCache.Size,\n      status?: LRUCache.Status<V>\n    ) => {\n      sizes[index] = size\n      if (this.#maxSize) {\n        const maxSize = this.#maxSize - (sizes[index] as number)\n        while (this.#calculatedSize > maxSize) {\n          this.#evict(true)\n        }\n      }\n      this.#calculatedSize += sizes[index] as number\n      if (status) {\n        status.entrySize = size\n        status.totalCalculatedSize = this.#calculatedSize\n      }\n    }\n  }\n\n  #removeItemSize: (index: Index) => void = _i => {}\n  #addItemSize: (\n    index: Index,\n    size: LRUCache.Size,\n    status?: LRUCache.Status<V>\n  ) => void = (_i, _s, _st) => {}\n  #requireSize: (\n    k: K,\n    v: V | BackgroundFetch<V>,\n    size?: LRUCache.Size,\n    sizeCalculation?: LRUCache.SizeCalculator<K, V>\n  ) => LRUCache.Size = (\n    _k: K,\n    _v: V | BackgroundFetch<V>,\n    size?: LRUCache.Size,\n    sizeCalculation?: LRUCache.SizeCalculator<K, V>\n  ) => {\n    if (size || sizeCalculation) {\n      throw new TypeError(\n        'cannot set size without setting maxSize or maxEntrySize on cache'\n      )\n    }\n    return 0\n  };\n\n  *#indexes({ allowStale = this.allowStale } = {}) {\n    if (this.#size) {\n      for (let i = this.#tail; true; ) {\n        if (!this.#isValidIndex(i)) {\n          break\n        }\n        if (allowStale || !this.#isStale(i)) {\n          yield i\n        }\n        if (i === this.#head) {\n          break\n        } else {\n          i = this.#prev[i] as Index\n        }\n      }\n    }\n  }\n\n  *#rindexes({ allowStale = this.allowStale } = {}) {\n    if (this.#size) {\n      for (let i = this.#head; true; ) {\n        if (!this.#isValidIndex(i)) {\n          break\n        }\n        if (allowStale || !this.#isStale(i)) {\n          yield i\n        }\n        if (i === this.#tail) {\n          break\n        } else {\n          i = this.#next[i] as Index\n        }\n      }\n    }\n  }\n\n  #isValidIndex(index: Index) {\n    return (\n      index !== undefined &&\n      this.#keyMap.get(this.#keyList[index] as K) === index\n    )\n  }\n\n  /**\n   * Return a generator yielding `[key, value]` pairs,\n   * in order from most recently used to least recently used.\n   */\n  *entries() {\n    for (const i of this.#indexes()) {\n      if (\n        this.#valList[i] !== undefined &&\n        this.#keyList[i] !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield [this.#keyList[i], this.#valList[i]] as [K, V]\n      }\n    }\n  }\n\n  /**\n   * Inverse order version of {@link LRUCache.entries}\n   *\n   * Return a generator yielding `[key, value]` pairs,\n   * in order from least recently used to most recently used.\n   */\n  *rentries() {\n    for (const i of this.#rindexes()) {\n      if (\n        this.#valList[i] !== undefined &&\n        this.#keyList[i] !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield [this.#keyList[i], this.#valList[i]]\n      }\n    }\n  }\n\n  /**\n   * Return a generator yielding the keys in the cache,\n   * in order from most recently used to least recently used.\n   */\n  *keys() {\n    for (const i of this.#indexes()) {\n      const k = this.#keyList[i]\n      if (\n        k !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield k\n      }\n    }\n  }\n\n  /**\n   * Inverse order version of {@link LRUCache.keys}\n   *\n   * Return a generator yielding the keys in the cache,\n   * in order from least recently used to most recently used.\n   */\n  *rkeys() {\n    for (const i of this.#rindexes()) {\n      const k = this.#keyList[i]\n      if (\n        k !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield k\n      }\n    }\n  }\n\n  /**\n   * Return a generator yielding the values in the cache,\n   * in order from most recently used to least recently used.\n   */\n  *values() {\n    for (const i of this.#indexes()) {\n      const v = this.#valList[i]\n      if (\n        v !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield this.#valList[i] as V\n      }\n    }\n  }\n\n  /**\n   * Inverse order version of {@link LRUCache.values}\n   *\n   * Return a generator yielding the values in the cache,\n   * in order from least recently used to most recently used.\n   */\n  *rvalues() {\n    for (const i of this.#rindexes()) {\n      const v = this.#valList[i]\n      if (\n        v !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield this.#valList[i]\n      }\n    }\n  }\n\n  /**\n   * Iterating over the cache itself yields the same results as\n   * {@link LRUCache.entries}\n   */\n  [Symbol.iterator]() {\n    return this.entries()\n  }\n\n  /**\n   * A String value that is used in the creation of the default string\n   * description of an object. Called by the built-in method\n   * `Object.prototype.toString`.\n   */\n  [Symbol.toStringTag] = 'LRUCache'\n\n  /**\n   * Find a value for which the supplied fn method returns a truthy value,\n   * similar to `Array.find()`. fn is called as `fn(value, key, cache)`.\n   */\n  find(\n    fn: (v: V, k: K, self: LRUCache<K, V, FC>) => boolean,\n    getOptions: LRUCache.GetOptions<K, V, FC> = {}\n  ) {\n    for (const i of this.#indexes()) {\n      const v = this.#valList[i]\n      const value = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined) continue\n      if (fn(value, this.#keyList[i] as K, this)) {\n        return this.get(this.#keyList[i] as K, getOptions)\n      }\n    }\n  }\n\n  /**\n   * Call the supplied function on each item in the cache, in order from most\n   * recently used to least recently used.\n   *\n   * `fn` is called as `fn(value, key, cache)`.\n   *\n   * If `thisp` is provided, function will be called in the `this`-context of\n   * the provided object, or the cache if no `thisp` object is provided.\n   *\n   * Does not update age or recenty of use, or iterate over stale values.\n   */\n  forEach(\n    fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any,\n    thisp: any = this\n  ) {\n    for (const i of this.#indexes()) {\n      const v = this.#valList[i]\n      const value = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined) continue\n      fn.call(thisp, value, this.#keyList[i] as K, this)\n    }\n  }\n\n  /**\n   * The same as {@link LRUCache.forEach} but items are iterated over in\n   * reverse order.  (ie, less recently used items are iterated over first.)\n   */\n  rforEach(\n    fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any,\n    thisp: any = this\n  ) {\n    for (const i of this.#rindexes()) {\n      const v = this.#valList[i]\n      const value = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined) continue\n      fn.call(thisp, value, this.#keyList[i] as K, this)\n    }\n  }\n\n  /**\n   * Delete any stale entries. Returns true if anything was removed,\n   * false otherwise.\n   */\n  purgeStale() {\n    let deleted = false\n    for (const i of this.#rindexes({ allowStale: true })) {\n      if (this.#isStale(i)) {\n        this.#delete(this.#keyList[i] as K, 'expire')\n        deleted = true\n      }\n    }\n    return deleted\n  }\n\n  /**\n   * Get the extended info about a given entry, to get its value, size, and\n   * TTL info simultaneously. Returns `undefined` if the key is not present.\n   *\n   * Unlike {@link LRUCache#dump}, which is designed to be portable and survive\n   * serialization, the `start` value is always the current timestamp, and the\n   * `ttl` is a calculated remaining time to live (negative if expired).\n   *\n   * Always returns stale values, if their info is found in the cache, so be\n   * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})\n   * if relevant.\n   */\n  info(key: K): LRUCache.Entry<V> | undefined {\n    const i = this.#keyMap.get(key)\n    if (i === undefined) return undefined\n    const v = this.#valList[i]\n    const value: V | undefined = this.#isBackgroundFetch(v)\n      ? v.__staleWhileFetching\n      : v\n    if (value === undefined) return undefined\n    const entry: LRUCache.Entry<V> = { value }\n    if (this.#ttls && this.#starts) {\n      const ttl = this.#ttls[i]\n      const start = this.#starts[i]\n      if (ttl && start) {\n        const remain = ttl - (perf.now() - start)\n        entry.ttl = remain\n        entry.start = Date.now()\n      }\n    }\n    if (this.#sizes) {\n      entry.size = this.#sizes[i]\n    }\n    return entry\n  }\n\n  /**\n   * Return an array of [key, {@link LRUCache.Entry}] tuples which can be\n   * passed to {@link LRLUCache#load}.\n   *\n   * The `start` fields are calculated relative to a portable `Date.now()`\n   * timestamp, even if `performance.now()` is available.\n   *\n   * Stale entries are always included in the `dump`, even if\n   * {@link LRUCache.OptionsBase.allowStale} is false.\n   *\n   * Note: this returns an actual array, not a generator, so it can be more\n   * easily passed around.\n   */\n  dump() {\n    const arr: [K, LRUCache.Entry<V>][] = []\n    for (const i of this.#indexes({ allowStale: true })) {\n      const key = this.#keyList[i]\n      const v = this.#valList[i]\n      const value: V | undefined = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined || key === undefined) continue\n      const entry: LRUCache.Entry<V> = { value }\n      if (this.#ttls && this.#starts) {\n        entry.ttl = this.#ttls[i]\n        // always dump the start relative to a portable timestamp\n        // it's ok for this to be a bit slow, it's a rare operation.\n        const age = perf.now() - (this.#starts[i] as number)\n        entry.start = Math.floor(Date.now() - age)\n      }\n      if (this.#sizes) {\n        entry.size = this.#sizes[i]\n      }\n      arr.unshift([key, entry])\n    }\n    return arr\n  }\n\n  /**\n   * Reset the cache and load in the items in entries in the order listed.\n   *\n   * The shape of the resulting cache may be different if the same options are\n   * not used in both caches.\n   *\n   * The `start` fields are assumed to be calculated relative to a portable\n   * `Date.now()` timestamp, even if `performance.now()` is available.\n   */\n  load(arr: [K, LRUCache.Entry<V>][]) {\n    this.clear()\n    for (const [key, entry] of arr) {\n      if (entry.start) {\n        // entry.start is a portable timestamp, but we may be using\n        // node's performance.now(), so calculate the offset, so that\n        // we get the intended remaining TTL, no matter how long it's\n        // been on ice.\n        //\n        // it's ok for this to be a bit slow, it's a rare operation.\n        const age = Date.now() - entry.start\n        entry.start = perf.now() - age\n      }\n      this.set(key, entry.value, entry)\n    }\n  }\n\n  /**\n   * Add a value to the cache.\n   *\n   * Note: if `undefined` is specified as a value, this is an alias for\n   * {@link LRUCache#delete}\n   *\n   * Fields on the {@link LRUCache.SetOptions} options param will override\n   * their corresponding values in the constructor options for the scope\n   * of this single `set()` operation.\n   *\n   * If `start` is provided, then that will set the effective start\n   * time for the TTL calculation. Note that this must be a previous\n   * value of `performance.now()` if supported, or a previous value of\n   * `Date.now()` if not.\n   *\n   * Options object may also include `size`, which will prevent\n   * calling the `sizeCalculation` function and just use the specified\n   * number if it is a positive integer, and `noDisposeOnSet` which\n   * will prevent calling a `dispose` function in the case of\n   * overwrites.\n   *\n   * If the `size` (or return value of `sizeCalculation`) for a given\n   * entry is greater than `maxEntrySize`, then the item will not be\n   * added to the cache.\n   *\n   * Will update the recency of the entry.\n   *\n   * If the value is `undefined`, then this is an alias for\n   * `cache.delete(key)`. `undefined` is never stored in the cache.\n   */\n  set(\n    k: K,\n    v: V | BackgroundFetch<V> | undefined,\n    setOptions: LRUCache.SetOptions<K, V, FC> = {}\n  ) {\n    if (v === undefined) {\n      this.delete(k)\n      return this\n    }\n    const {\n      ttl = this.ttl,\n      start,\n      noDisposeOnSet = this.noDisposeOnSet,\n      sizeCalculation = this.sizeCalculation,\n      status,\n    } = setOptions\n    let { noUpdateTTL = this.noUpdateTTL } = setOptions\n\n    const size = this.#requireSize(\n      k,\n      v,\n      setOptions.size || 0,\n      sizeCalculation\n    )\n    // if the item doesn't fit, don't do anything\n    // NB: maxEntrySize set to maxSize by default\n    if (this.maxEntrySize && size > this.maxEntrySize) {\n      if (status) {\n        status.set = 'miss'\n        status.maxEntrySizeExceeded = true\n      }\n      // have to delete, in case something is there already.\n      this.#delete(k, 'set')\n      return this\n    }\n    let index = this.#size === 0 ? undefined : this.#keyMap.get(k)\n    if (index === undefined) {\n      // addition\n      index = (\n        this.#size === 0\n          ? this.#tail\n          : this.#free.length !== 0\n          ? this.#free.pop()\n          : this.#size === this.#max\n          ? this.#evict(false)\n          : this.#size\n      ) as Index\n      this.#keyList[index] = k\n      this.#valList[index] = v\n      this.#keyMap.set(k, index)\n      this.#next[this.#tail] = index\n      this.#prev[index] = this.#tail\n      this.#tail = index\n      this.#size++\n      this.#addItemSize(index, size, status)\n      if (status) status.set = 'add'\n      noUpdateTTL = false\n    } else {\n      // update\n      this.#moveToTail(index)\n      const oldVal = this.#valList[index] as V | BackgroundFetch<V>\n      if (v !== oldVal) {\n        if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {\n          oldVal.__abortController.abort(new Error('replaced'))\n          const { __staleWhileFetching: s } = oldVal\n          if (s !== undefined && !noDisposeOnSet) {\n            if (this.#hasDispose) {\n              this.#dispose?.(s as V, k, 'set')\n            }\n            if (this.#hasDisposeAfter) {\n              this.#disposed?.push([s as V, k, 'set'])\n            }\n          }\n        } else if (!noDisposeOnSet) {\n          if (this.#hasDispose) {\n            this.#dispose?.(oldVal as V, k, 'set')\n          }\n          if (this.#hasDisposeAfter) {\n            this.#disposed?.push([oldVal as V, k, 'set'])\n          }\n        }\n        this.#removeItemSize(index)\n        this.#addItemSize(index, size, status)\n        this.#valList[index] = v\n        if (status) {\n          status.set = 'replace'\n          const oldValue =\n            oldVal && this.#isBackgroundFetch(oldVal)\n              ? oldVal.__staleWhileFetching\n              : oldVal\n          if (oldValue !== undefined) status.oldValue = oldValue\n        }\n      } else if (status) {\n        status.set = 'update'\n      }\n    }\n    if (ttl !== 0 && !this.#ttls) {\n      this.#initializeTTLTracking()\n    }\n    if (this.#ttls) {\n      if (!noUpdateTTL) {\n        this.#setItemTTL(index, ttl, start)\n      }\n      if (status) this.#statusTTL(status, index)\n    }\n    if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {\n      const dt = this.#disposed\n      let task: DisposeTask<K, V> | undefined\n      while ((task = dt?.shift())) {\n        this.#disposeAfter?.(...task)\n      }\n    }\n    return this\n  }\n\n  /**\n   * Evict the least recently used item, returning its value or\n   * `undefined` if cache is empty.\n   */\n  pop(): V | undefined {\n    try {\n      while (this.#size) {\n        const val = this.#valList[this.#head]\n        this.#evict(true)\n        if (this.#isBackgroundFetch(val)) {\n          if (val.__staleWhileFetching) {\n            return val.__staleWhileFetching\n          }\n        } else if (val !== undefined) {\n          return val\n        }\n      }\n    } finally {\n      if (this.#hasDisposeAfter && this.#disposed) {\n        const dt = this.#disposed\n        let task: DisposeTask<K, V> | undefined\n        while ((task = dt?.shift())) {\n          this.#disposeAfter?.(...task)\n        }\n      }\n    }\n  }\n\n  #evict(free: boolean) {\n    const head = this.#head\n    const k = this.#keyList[head] as K\n    const v = this.#valList[head] as V\n    if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) {\n      v.__abortController.abort(new Error('evicted'))\n    } else if (this.#hasDispose || this.#hasDisposeAfter) {\n      if (this.#hasDispose) {\n        this.#dispose?.(v, k, 'evict')\n      }\n      if (this.#hasDisposeAfter) {\n        this.#disposed?.push([v, k, 'evict'])\n      }\n    }\n    this.#removeItemSize(head)\n    // if we aren't about to use the index, then null these out\n    if (free) {\n      this.#keyList[head] = undefined\n      this.#valList[head] = undefined\n      this.#free.push(head)\n    }\n    if (this.#size === 1) {\n      this.#head = this.#tail = 0 as Index\n      this.#free.length = 0\n    } else {\n      this.#head = this.#next[head] as Index\n    }\n    this.#keyMap.delete(k)\n    this.#size--\n    return head\n  }\n\n  /**\n   * Check if a key is in the cache, without updating the recency of use.\n   * Will return false if the item is stale, even though it is technically\n   * in the cache.\n   *\n   * Check if a key is in the cache, without updating the recency of\n   * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set\n   * to `true` in either the options or the constructor.\n   *\n   * Will return `false` if the item is stale, even though it is technically in\n   * the cache. The difference can be determined (if it matters) by using a\n   * `status` argument, and inspecting the `has` field.\n   *\n   * Will not update item age unless\n   * {@link LRUCache.OptionsBase.updateAgeOnHas} is set.\n   */\n  has(k: K, hasOptions: LRUCache.HasOptions<K, V, FC> = {}) {\n    const { updateAgeOnHas = this.updateAgeOnHas, status } =\n      hasOptions\n    const index = this.#keyMap.get(k)\n    if (index !== undefined) {\n      const v = this.#valList[index]\n      if (\n        this.#isBackgroundFetch(v) &&\n        v.__staleWhileFetching === undefined\n      ) {\n        return false\n      }\n      if (!this.#isStale(index)) {\n        if (updateAgeOnHas) {\n          this.#updateItemAge(index)\n        }\n        if (status) {\n          status.has = 'hit'\n          this.#statusTTL(status, index)\n        }\n        return true\n      } else if (status) {\n        status.has = 'stale'\n        this.#statusTTL(status, index)\n      }\n    } else if (status) {\n      status.has = 'miss'\n    }\n    return false\n  }\n\n  /**\n   * Like {@link LRUCache#get} but doesn't update recency or delete stale\n   * items.\n   *\n   * Returns `undefined` if the item is stale, unless\n   * {@link LRUCache.OptionsBase.allowStale} is set.\n   */\n  peek(k: K, peekOptions: LRUCache.PeekOptions<K, V, FC> = {}) {\n    const { allowStale = this.allowStale } = peekOptions\n    const index = this.#keyMap.get(k)\n    if (\n      index === undefined ||\n      (!allowStale && this.#isStale(index))\n    ) {\n      return\n    }\n    const v = this.#valList[index]\n    // either stale and allowed, or forcing a refresh of non-stale value\n    return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v\n  }\n\n  #backgroundFetch(\n    k: K,\n    index: Index | undefined,\n    options: LRUCache.FetchOptions<K, V, FC>,\n    context: any\n  ): BackgroundFetch<V> {\n    const v = index === undefined ? undefined : this.#valList[index]\n    if (this.#isBackgroundFetch(v)) {\n      return v\n    }\n\n    const ac = new AC()\n    const { signal } = options\n    // when/if our AC signals, then stop listening to theirs.\n    signal?.addEventListener('abort', () => ac.abort(signal.reason), {\n      signal: ac.signal,\n    })\n\n    const fetchOpts = {\n      signal: ac.signal,\n      options,\n      context,\n    }\n\n    const cb = (\n      v: V | undefined,\n      updateCache = false\n    ): V | undefined => {\n      const { aborted } = ac.signal\n      const ignoreAbort = options.ignoreFetchAbort && v !== undefined\n      if (options.status) {\n        if (aborted && !updateCache) {\n          options.status.fetchAborted = true\n          options.status.fetchError = ac.signal.reason\n          if (ignoreAbort) options.status.fetchAbortIgnored = true\n        } else {\n          options.status.fetchResolved = true\n        }\n      }\n      if (aborted && !ignoreAbort && !updateCache) {\n        return fetchFail(ac.signal.reason)\n      }\n      // either we didn't abort, and are still here, or we did, and ignored\n      const bf = p as BackgroundFetch<V>\n      if (this.#valList[index as Index] === p) {\n        if (v === undefined) {\n          if (bf.__staleWhileFetching) {\n            this.#valList[index as Index] = bf.__staleWhileFetching\n          } else {\n            this.#delete(k, 'fetch')\n          }\n        } else {\n          if (options.status) options.status.fetchUpdated = true\n          this.set(k, v, fetchOpts.options)\n        }\n      }\n      return v\n    }\n\n    const eb = (er: any) => {\n      if (options.status) {\n        options.status.fetchRejected = true\n        options.status.fetchError = er\n      }\n      return fetchFail(er)\n    }\n\n    const fetchFail = (er: any): V | undefined => {\n      const { aborted } = ac.signal\n      const allowStaleAborted =\n        aborted && options.allowStaleOnFetchAbort\n      const allowStale =\n        allowStaleAborted || options.allowStaleOnFetchRejection\n      const noDelete = allowStale || options.noDeleteOnFetchRejection\n      const bf = p as BackgroundFetch<V>\n      if (this.#valList[index as Index] === p) {\n        // if we allow stale on fetch rejections, then we need to ensure that\n        // the stale value is not removed from the cache when the fetch fails.\n        const del = !noDelete || bf.__staleWhileFetching === undefined\n        if (del) {\n          this.#delete(k, 'fetch')\n        } else if (!allowStaleAborted) {\n          // still replace the *promise* with the stale value,\n          // since we are done with the promise at this point.\n          // leave it untouched if we're still waiting for an\n          // aborted background fetch that hasn't yet returned.\n          this.#valList[index as Index] = bf.__staleWhileFetching\n        }\n      }\n      if (allowStale) {\n        if (options.status && bf.__staleWhileFetching !== undefined) {\n          options.status.returnedStale = true\n        }\n        return bf.__staleWhileFetching\n      } else if (bf.__returned === bf) {\n        throw er\n      }\n    }\n\n    const pcall = (\n      res: (v: V | undefined) => void,\n      rej: (e: any) => void\n    ) => {\n      const fmp = this.#fetchMethod?.(k, v, fetchOpts)\n      if (fmp && fmp instanceof Promise) {\n        fmp.then(v => res(v === undefined ? undefined : v), rej)\n      }\n      // ignored, we go until we finish, regardless.\n      // defer check until we are actually aborting,\n      // so fetchMethod can override.\n      ac.signal.addEventListener('abort', () => {\n        if (\n          !options.ignoreFetchAbort ||\n          options.allowStaleOnFetchAbort\n        ) {\n          res(undefined)\n          // when it eventually resolves, update the cache.\n          if (options.allowStaleOnFetchAbort) {\n            res = v => cb(v, true)\n          }\n        }\n      })\n    }\n\n    if (options.status) options.status.fetchDispatched = true\n    const p = new Promise(pcall).then(cb, eb)\n    const bf: BackgroundFetch<V> = Object.assign(p, {\n      __abortController: ac,\n      __staleWhileFetching: v,\n      __returned: undefined,\n    })\n\n    if (index === undefined) {\n      // internal, don't expose status.\n      this.set(k, bf, { ...fetchOpts.options, status: undefined })\n      index = this.#keyMap.get(k)\n    } else {\n      this.#valList[index] = bf\n    }\n    return bf\n  }\n\n  #isBackgroundFetch(p: any): p is BackgroundFetch<V> {\n    if (!this.#hasFetchMethod) return false\n    const b = p as BackgroundFetch<V>\n    return (\n      !!b &&\n      b instanceof Promise &&\n      b.hasOwnProperty('__staleWhileFetching') &&\n      b.__abortController instanceof AC\n    )\n  }\n\n  /**\n   * Make an asynchronous cached fetch using the\n   * {@link LRUCache.OptionsBase.fetchMethod} function.\n   *\n   * If the value is in the cache and not stale, then the returned\n   * Promise resolves to the value.\n   *\n   * If not in the cache, or beyond its TTL staleness, then\n   * `fetchMethod(key, staleValue, { options, signal, context })` is\n   * called, and the value returned will be added to the cache once\n   * resolved.\n   *\n   * If called with `allowStale`, and an asynchronous fetch is\n   * currently in progress to reload a stale value, then the former\n   * stale value will be returned.\n   *\n   * If called with `forceRefresh`, then the cached item will be\n   * re-fetched, even if it is not stale. However, if `allowStale` is also\n   * set, then the old value will still be returned. This is useful\n   * in cases where you want to force a reload of a cached value. If\n   * a background fetch is already in progress, then `forceRefresh`\n   * has no effect.\n   *\n   * If multiple fetches for the same key are issued, then they will all be\n   * coalesced into a single call to fetchMethod.\n   *\n   * Note that this means that handling options such as\n   * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort},\n   * {@link LRUCache.FetchOptions.signal},\n   * and {@link LRUCache.OptionsBase.allowStaleOnFetchRejection} will be\n   * determined by the FIRST fetch() call for a given key.\n   *\n   * This is a known (fixable) shortcoming which will be addresed on when\n   * someone complains about it, as the fix would involve added complexity and\n   * may not be worth the costs for this edge case.\n   *\n   * If {@link LRUCache.OptionsBase.fetchMethod} is not specified, then this is\n   * effectively an alias for `Promise.resolve(cache.get(key))`.\n   *\n   * When the fetch method resolves to a value, if the fetch has not\n   * been aborted due to deletion, eviction, or being overwritten,\n   * then it is added to the cache using the options provided.\n   *\n   * If the key is evicted or deleted before the `fetchMethod`\n   * resolves, then the AbortSignal passed to the `fetchMethod` will\n   * receive an `abort` event, and the promise returned by `fetch()`\n   * will reject with the reason for the abort.\n   *\n   * If a `signal` is passed to the `fetch()` call, then aborting the\n   * signal will abort the fetch and cause the `fetch()` promise to\n   * reject with the reason provided.\n   *\n   * **Setting `context`**\n   *\n   * If an `FC` type is set to a type other than `unknown`, `void`, or\n   * `undefined` in the {@link LRUCache} constructor, then all\n   * calls to `cache.fetch()` _must_ provide a `context` option. If\n   * set to `undefined` or `void`, then calls to fetch _must not_\n   * provide a `context` option.\n   *\n   * The `context` param allows you to provide arbitrary data that\n   * might be relevant in the course of fetching the data. It is only\n   * relevant for the course of a single `fetch()` operation, and\n   * discarded afterwards.\n   *\n   * **Note: `fetch()` calls are inflight-unique**\n   *\n   * If you call `fetch()` multiple times with the same key value,\n   * then every call after the first will resolve on the same\n   * promise<sup>1</sup>,\n   * _even if they have different settings that would otherwise change\n   * the behavior of the fetch_, such as `noDeleteOnFetchRejection`\n   * or `ignoreFetchAbort`.\n   *\n   * In most cases, this is not a problem (in fact, only fetching\n   * something once is what you probably want, if you're caching in\n   * the first place). If you are changing the fetch() options\n   * dramatically between runs, there's a good chance that you might\n   * be trying to fit divergent semantics into a single object, and\n   * would be better off with multiple cache instances.\n   *\n   * **1**: Ie, they're not the \"same Promise\", but they resolve at\n   * the same time, because they're both waiting on the same\n   * underlying fetchMethod response.\n   */\n\n  fetch(\n    k: K,\n    fetchOptions: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : LRUCache.FetchOptionsWithContext<K, V, FC>\n  ): Promise<undefined | V>\n\n  // this overload not allowed if context is required\n  fetch(\n    k: unknown extends FC\n      ? K\n      : FC extends undefined | void\n      ? K\n      : never,\n    fetchOptions?: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : never\n  ): Promise<undefined | V>\n\n  async fetch(\n    k: K,\n    fetchOptions: LRUCache.FetchOptions<K, V, FC> = {}\n  ): Promise<undefined | V> {\n    const {\n      // get options\n      allowStale = this.allowStale,\n      updateAgeOnGet = this.updateAgeOnGet,\n      noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n      // set options\n      ttl = this.ttl,\n      noDisposeOnSet = this.noDisposeOnSet,\n      size = 0,\n      sizeCalculation = this.sizeCalculation,\n      noUpdateTTL = this.noUpdateTTL,\n      // fetch exclusive options\n      noDeleteOnFetchRejection = this.noDeleteOnFetchRejection,\n      allowStaleOnFetchRejection = this.allowStaleOnFetchRejection,\n      ignoreFetchAbort = this.ignoreFetchAbort,\n      allowStaleOnFetchAbort = this.allowStaleOnFetchAbort,\n      context,\n      forceRefresh = false,\n      status,\n      signal,\n    } = fetchOptions\n\n    if (!this.#hasFetchMethod) {\n      if (status) status.fetch = 'get'\n      return this.get(k, {\n        allowStale,\n        updateAgeOnGet,\n        noDeleteOnStaleGet,\n        status,\n      })\n    }\n\n    const options = {\n      allowStale,\n      updateAgeOnGet,\n      noDeleteOnStaleGet,\n      ttl,\n      noDisposeOnSet,\n      size,\n      sizeCalculation,\n      noUpdateTTL,\n      noDeleteOnFetchRejection,\n      allowStaleOnFetchRejection,\n      allowStaleOnFetchAbort,\n      ignoreFetchAbort,\n      status,\n      signal,\n    }\n\n    let index = this.#keyMap.get(k)\n    if (index === undefined) {\n      if (status) status.fetch = 'miss'\n      const p = this.#backgroundFetch(k, index, options, context)\n      return (p.__returned = p)\n    } else {\n      // in cache, maybe already fetching\n      const v = this.#valList[index]\n      if (this.#isBackgroundFetch(v)) {\n        const stale =\n          allowStale && v.__staleWhileFetching !== undefined\n        if (status) {\n          status.fetch = 'inflight'\n          if (stale) status.returnedStale = true\n        }\n        return stale ? v.__staleWhileFetching : (v.__returned = v)\n      }\n\n      // if we force a refresh, that means do NOT serve the cached value,\n      // unless we are already in the process of refreshing the cache.\n      const isStale = this.#isStale(index)\n      if (!forceRefresh && !isStale) {\n        if (status) status.fetch = 'hit'\n        this.#moveToTail(index)\n        if (updateAgeOnGet) {\n          this.#updateItemAge(index)\n        }\n        if (status) this.#statusTTL(status, index)\n        return v\n      }\n\n      // ok, it is stale or a forced refresh, and not already fetching.\n      // refresh the cache.\n      const p = this.#backgroundFetch(k, index, options, context)\n      const hasStale = p.__staleWhileFetching !== undefined\n      const staleVal = hasStale && allowStale\n      if (status) {\n        status.fetch = isStale ? 'stale' : 'refresh'\n        if (staleVal && isStale) status.returnedStale = true\n      }\n      return staleVal ? p.__staleWhileFetching : (p.__returned = p)\n    }\n  }\n\n  /**\n   * In some cases, `cache.fetch()` may resolve to `undefined`, either because\n   * a {@link LRUCache.OptionsBase#fetchMethod} was not provided (turning\n   * `cache.fetch(k)` into just an async wrapper around `cache.get(k)`) or\n   * because `ignoreFetchAbort` was specified (either to the constructor or\n   * in the {@link LRUCache.FetchOptions}). Also, the\n   * {@link OptionsBase.fetchMethod} may return `undefined` or `void`, making\n   * the test even more complicated.\n   *\n   * Because inferring the cases where `undefined` might be returned are so\n   * cumbersome, but testing for `undefined` can also be annoying, this method\n   * can be used, which will reject if `this.fetch()` resolves to undefined.\n   */\n  forceFetch(\n    k: K,\n    fetchOptions: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : LRUCache.FetchOptionsWithContext<K, V, FC>\n  ): Promise<V>\n  // this overload not allowed if context is required\n  forceFetch(\n    k: unknown extends FC\n      ? K\n      : FC extends undefined | void\n      ? K\n      : never,\n    fetchOptions?: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : never\n  ): Promise<V>\n  async forceFetch(\n    k: K,\n    fetchOptions: LRUCache.FetchOptions<K, V, FC> = {}\n  ): Promise<V> {\n    const v = await this.fetch(\n      k,\n      fetchOptions as unknown extends FC\n        ? LRUCache.FetchOptions<K, V, FC>\n        : FC extends undefined | void\n        ? LRUCache.FetchOptionsNoContext<K, V>\n        : LRUCache.FetchOptionsWithContext<K, V, FC>\n    )\n    if (v === undefined) throw new Error('fetch() returned undefined')\n    return v\n  }\n\n  /**\n   * If the key is found in the cache, then this is equivalent to\n   * {@link LRUCache#get}. If not, in the cache, then calculate the value using\n   * the {@link LRUCache.OptionsBase.memoMethod}, and add it to the cache.\n   *\n   * If an `FC` type is set to a type other than `unknown`, `void`, or\n   * `undefined` in the LRUCache constructor, then all calls to `cache.memo()`\n   * _must_ provide a `context` option. If set to `undefined` or `void`, then\n   * calls to memo _must not_ provide a `context` option.\n   *\n   * The `context` param allows you to provide arbitrary data that might be\n   * relevant in the course of fetching the data. It is only relevant for the\n   * course of a single `memo()` operation, and discarded afterwards.\n   */\n  memo(\n    k: K,\n    memoOptions: unknown extends FC\n      ? LRUCache.MemoOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.MemoOptionsNoContext<K, V>\n      : LRUCache.MemoOptionsWithContext<K, V, FC>\n  ): V\n  // this overload not allowed if context is required\n  memo(\n    k: unknown extends FC\n      ? K\n      : FC extends undefined | void\n      ? K\n      : never,\n    memoOptions?: unknown extends FC\n      ? LRUCache.MemoOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.MemoOptionsNoContext<K, V>\n      : never\n  ): V\n  memo(k: K, memoOptions: LRUCache.MemoOptions<K, V, FC> = {}) {\n    const memoMethod = this.#memoMethod\n    if (!memoMethod) {\n      throw new Error('no memoMethod provided to constructor')\n    }\n    const { context, forceRefresh, ...options } = memoOptions\n    const v = this.get(k, options)\n    if (!forceRefresh && v !== undefined) return v\n    const vv = memoMethod(k, v, {\n      options,\n      context,\n    } as LRUCache.MemoizerOptions<K, V, FC>)\n    this.set(k, vv, options)\n    return vv\n  }\n\n  /**\n   * Return a value from the cache. Will update the recency of the cache\n   * entry found.\n   *\n   * If the key is not found, get() will return `undefined`.\n   */\n  get(k: K, getOptions: LRUCache.GetOptions<K, V, FC> = {}) {\n    const {\n      allowStale = this.allowStale,\n      updateAgeOnGet = this.updateAgeOnGet,\n      noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n      status,\n    } = getOptions\n    const index = this.#keyMap.get(k)\n    if (index !== undefined) {\n      const value = this.#valList[index]\n      const fetching = this.#isBackgroundFetch(value)\n      if (status) this.#statusTTL(status, index)\n      if (this.#isStale(index)) {\n        if (status) status.get = 'stale'\n        // delete only if not an in-flight background fetch\n        if (!fetching) {\n          if (!noDeleteOnStaleGet) {\n            this.#delete(k, 'expire')\n          }\n          if (status && allowStale) status.returnedStale = true\n          return allowStale ? value : undefined\n        } else {\n          if (\n            status &&\n            allowStale &&\n            value.__staleWhileFetching !== undefined\n          ) {\n            status.returnedStale = true\n          }\n          return allowStale ? value.__staleWhileFetching : undefined\n        }\n      } else {\n        if (status) status.get = 'hit'\n        // if we're currently fetching it, we don't actually have it yet\n        // it's not stale, which means this isn't a staleWhileRefetching.\n        // If it's not stale, and fetching, AND has a __staleWhileFetching\n        // value, then that means the user fetched with {forceRefresh:true},\n        // so it's safe to return that value.\n        if (fetching) {\n          return value.__staleWhileFetching\n        }\n        this.#moveToTail(index)\n        if (updateAgeOnGet) {\n          this.#updateItemAge(index)\n        }\n        return value\n      }\n    } else if (status) {\n      status.get = 'miss'\n    }\n  }\n\n  #connect(p: Index, n: Index) {\n    this.#prev[n] = p\n    this.#next[p] = n\n  }\n\n  #moveToTail(index: Index): void {\n    // if tail already, nothing to do\n    // if head, move head to next[index]\n    // else\n    //   move next[prev[index]] to next[index] (head has no prev)\n    //   move prev[next[index]] to prev[index]\n    // prev[index] = tail\n    // next[tail] = index\n    // tail = index\n    if (index !== this.#tail) {\n      if (index === this.#head) {\n        this.#head = this.#next[index] as Index\n      } else {\n        this.#connect(\n          this.#prev[index] as Index,\n          this.#next[index] as Index\n        )\n      }\n      this.#connect(this.#tail, index)\n      this.#tail = index\n    }\n  }\n\n  /**\n   * Deletes a key out of the cache.\n   *\n   * Returns true if the key was deleted, false otherwise.\n   */\n  delete(k: K) {\n    return this.#delete(k, 'delete')\n  }\n\n  #delete(k: K, reason: LRUCache.DisposeReason) {\n    let deleted = false\n    if (this.#size !== 0) {\n      const index = this.#keyMap.get(k)\n      if (index !== undefined) {\n        deleted = true\n        if (this.#size === 1) {\n          this.#clear(reason)\n        } else {\n          this.#removeItemSize(index)\n          const v = this.#valList[index]\n          if (this.#isBackgroundFetch(v)) {\n            v.__abortController.abort(new Error('deleted'))\n          } else if (this.#hasDispose || this.#hasDisposeAfter) {\n            if (this.#hasDispose) {\n              this.#dispose?.(v as V, k, reason)\n            }\n            if (this.#hasDisposeAfter) {\n              this.#disposed?.push([v as V, k, reason])\n            }\n          }\n          this.#keyMap.delete(k)\n          this.#keyList[index] = undefined\n          this.#valList[index] = undefined\n          if (index === this.#tail) {\n            this.#tail = this.#prev[index] as Index\n          } else if (index === this.#head) {\n            this.#head = this.#next[index] as Index\n          } else {\n            const pi = this.#prev[index] as number\n            this.#next[pi] = this.#next[index] as number\n            const ni = this.#next[index] as number\n            this.#prev[ni] = this.#prev[index] as number\n          }\n          this.#size--\n          this.#free.push(index)\n        }\n      }\n    }\n    if (this.#hasDisposeAfter && this.#disposed?.length) {\n      const dt = this.#disposed\n      let task: DisposeTask<K, V> | undefined\n      while ((task = dt?.shift())) {\n        this.#disposeAfter?.(...task)\n      }\n    }\n    return deleted\n  }\n\n  /**\n   * Clear the cache entirely, throwing away all values.\n   */\n  clear() {\n    return this.#clear('delete')\n  }\n  #clear(reason: LRUCache.DisposeReason) {\n    for (const index of this.#rindexes({ allowStale: true })) {\n      const v = this.#valList[index]\n      if (this.#isBackgroundFetch(v)) {\n        v.__abortController.abort(new Error('deleted'))\n      } else {\n        const k = this.#keyList[index]\n        if (this.#hasDispose) {\n          this.#dispose?.(v as V, k as K, reason)\n        }\n        if (this.#hasDisposeAfter) {\n          this.#disposed?.push([v as V, k as K, reason])\n        }\n      }\n    }\n\n    this.#keyMap.clear()\n    this.#valList.fill(undefined)\n    this.#keyList.fill(undefined)\n    if (this.#ttls && this.#starts) {\n      this.#ttls.fill(0)\n      this.#starts.fill(0)\n    }\n    if (this.#sizes) {\n      this.#sizes.fill(0)\n    }\n    this.#head = 0 as Index\n    this.#tail = 0 as Index\n    this.#free.length = 0\n    this.#calculatedSize = 0\n    this.#size = 0\n    if (this.#hasDisposeAfter && this.#disposed) {\n      const dt = this.#disposed\n      let task: DisposeTask<K, V> | undefined\n      while ((task = dt?.shift())) {\n        this.#disposeAfter?.(...task)\n      }\n    }\n  }\n}\n"]}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | 'allowStale'\n      | 'updateAgeOnGet'\n      | 'noDeleteOnStaleGet'\n      | 'sizeCalculation'\n      | 'ttl'\n      | 'noDisposeOnSet'\n      | 'noUpdateTTL'\n      | 'noDeleteOnFetchRejection'\n      | 'allowStaleOnFetchRejection'\n      | 'ignoreFetchAbort'\n      | 'allowStaleOnFetchAbort'\n    > {\n    status?: Status<V>\n    size?: Size\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#fetch} method.\n   */\n  export interface FetchOptions<K, V, FC>\n    extends FetcherFetchOptions<K, V, FC> {\n    /**\n     * Set to true to force a re-load of the existing data, even if it\n     * is not yet stale.\n     */\n    forceRefresh?: boolean\n    /**\n     * Context provided to the {@link OptionsBase.fetchMethod} as\n     * the {@link FetcherOptions.context} param.\n     *\n     * If the FC type is specified as unknown (the default),\n     * undefined or void, then this is optional.  Otherwise, it will\n     * be required.\n     */\n    context?: FC\n    signal?: AbortSignal\n    status?: Status<V>\n  }\n  /**\n   * Options provided to {@link LRUCache#fetch} when the FC type is something\n   * other than `unknown`, `undefined`, or `void`\n   */\n  export interface FetchOptionsWithContext<K, V, FC>\n    extends FetchOptions<K, V, FC> {\n    context: FC\n  }\n  /**\n   * Options provided to {@link LRUCache#fetch} when the FC type is\n   * `undefined` or `void`\n   */\n  export interface FetchOptionsNoContext<K, V>\n    extends FetchOptions<K, V, undefined> {\n    context?: undefined\n  }\n\n  export interface MemoOptions<K, V, FC = unknown>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      | 'allowStale'\n      | 'updateAgeOnGet'\n      | 'noDeleteOnStaleGet'\n      | 'sizeCalculation'\n      | 'ttl'\n      | 'noDisposeOnSet'\n      | 'noUpdateTTL'\n      | 'noDeleteOnFetchRejection'\n      | 'allowStaleOnFetchRejection'\n      | 'ignoreFetchAbort'\n      | 'allowStaleOnFetchAbort'\n    > {\n    /**\n     * Set to true to force a re-load of the existing data, even if it\n     * is not yet stale.\n     */\n    forceRefresh?: boolean\n    /**\n     * Context provided to the {@link OptionsBase.memoMethod} as\n     * the {@link MemoizerOptions.context} param.\n     *\n     * If the FC type is specified as unknown (the default),\n     * undefined or void, then this is optional.  Otherwise, it will\n     * be required.\n     */\n    context?: FC\n    status?: Status<V>\n  }\n  /**\n   * Options provided to {@link LRUCache#memo} when the FC type is something\n   * other than `unknown`, `undefined`, or `void`\n   */\n  export interface MemoOptionsWithContext<K, V, FC>\n    extends MemoOptions<K, V, FC> {\n    context: FC\n  }\n  /**\n   * Options provided to {@link LRUCache#memo} when the FC type is\n   * `undefined` or `void`\n   */\n  export interface MemoOptionsNoContext<K, V>\n    extends MemoOptions<K, V, undefined> {\n    context?: undefined\n  }\n\n  /**\n   * Options provided to the\n   * {@link OptionsBase.memoMethod} function.\n   */\n  export interface MemoizerOptions<K, V, FC = unknown> {\n    options: MemoizerMemoOptions<K, V, FC>\n    /**\n     * Object provided in the {@link MemoOptions.context} option to\n     * {@link LRUCache#memo}\n     */\n    context: FC\n  }\n\n  /**\n   * options which override the options set in the LRUCache constructor\n   * when calling {@link LRUCache#memo}.\n   *\n   * This is the union of {@link GetOptions} and {@link SetOptions}, plus\n   * {@link MemoOptions.forceRefresh}, and\n   * {@link MemoerOptions.context}\n   *\n   * Any of these may be modified in the {@link OptionsBase.memoMethod}\n   * function, but the {@link GetOptions} fields will of course have no\n   * effect, as the {@link LRUCache#get} call already happened by the time\n   * the memoMethod is called.\n   */\n  export interface MemoizerMemoOptions<K, V, FC = unknown>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      | 'allowStale'\n      | 'updateAgeOnGet'\n      | 'noDeleteOnStaleGet'\n      | 'sizeCalculation'\n      | 'ttl'\n      | 'noDisposeOnSet'\n      | 'noUpdateTTL'\n    > {\n    status?: Status<V>\n    size?: Size\n    start?: Milliseconds\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#has} method.\n   */\n  export interface HasOptions<K, V, FC>\n    extends Pick<OptionsBase<K, V, FC>, 'updateAgeOnHas'> {\n    status?: Status<V>\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#get} method.\n   */\n  export interface GetOptions<K, V, FC>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      'allowStale' | 'updateAgeOnGet' | 'noDeleteOnStaleGet'\n    > {\n    status?: Status<V>\n  }\n\n  /**\n   * Options that may be passed to the {@link LRUCache#peek} method.\n   */\n  export interface PeekOptions<K, V, FC>\n    extends Pick<OptionsBase<K, V, FC>, 'allowStale'> {}\n\n  /**\n   * Options that may be passed to the {@link LRUCache#set} method.\n   */\n  export interface SetOptions<K, V, FC>\n    extends Pick<\n      OptionsBase<K, V, FC>,\n      'sizeCalculation' | 'ttl' | 'noDisposeOnSet' | 'noUpdateTTL'\n    > {\n    /**\n     * If size tracking is enabled, then setting an explicit size\n     * in the {@link LRUCache#set} call will prevent calling the\n     * {@link OptionsBase.sizeCalculation} function.\n     */\n    size?: Size\n    /**\n     * If TTL tracking is enabled, then setting an explicit start\n     * time in the {@link LRUCache#set} call will override the\n     * default time from `performance.now()` or `Date.now()`.\n     *\n     * Note that it must be a valid value for whichever time-tracking\n     * method is in use.\n     */\n    start?: Milliseconds\n    status?: Status<V>\n  }\n\n  /**\n   * The type signature for the {@link OptionsBase.fetchMethod} option.\n   */\n  export type Fetcher<K, V, FC = unknown> = (\n    key: K,\n    staleValue: V | undefined,\n    options: FetcherOptions<K, V, FC>\n  ) => Promise<V | undefined | void> | V | undefined | void\n\n  /**\n   * the type signature for the {@link OptionsBase.memoMethod} option.\n   */\n  export type Memoizer<K, V, FC = unknown> = (\n    key: K,\n    staleValue: V | undefined,\n    options: MemoizerOptions<K, V, FC>\n  ) => V\n\n  /**\n   * Options which may be passed to the {@link LRUCache} constructor.\n   *\n   * Most of these may be overridden in the various options that use\n   * them.\n   *\n   * Despite all being technically optional, the constructor requires that\n   * a cache is at minimum limited by one or more of {@link OptionsBase.max},\n   * {@link OptionsBase.ttl}, or {@link OptionsBase.maxSize}.\n   *\n   * If {@link OptionsBase.ttl} is used alone, then it is strongly advised\n   * (and in fact required by the type definitions here) that the cache\n   * also set {@link OptionsBase.ttlAutopurge}, to prevent potentially\n   * unbounded storage.\n   *\n   * All options are also available on the {@link LRUCache} instance, making\n   * it safe to pass an LRUCache instance as the options argumemnt to\n   * make another empty cache of the same type.\n   *\n   * Some options are marked as read-only, because changing them after\n   * instantiation is not safe. Changing any of the other options will of\n   * course only have an effect on subsequent method calls.\n   */\n  export interface OptionsBase<K, V, FC> {\n    /**\n     * The maximum number of items to store in the cache before evicting\n     * old entries. This is read-only on the {@link LRUCache} instance,\n     * and may not be overridden.\n     *\n     * If set, then storage space will be pre-allocated at construction\n     * time, and the cache will perform significantly faster.\n     *\n     * Note that significantly fewer items may be stored, if\n     * {@link OptionsBase.maxSize} and/or {@link OptionsBase.ttl} are also\n     * set.\n     *\n     * **It is strongly recommended to set a `max` to prevent unbounded growth\n     * of the cache.**\n     */\n    max?: Count\n\n    /**\n     * Max time in milliseconds for items to live in cache before they are\n     * considered stale.  Note that stale items are NOT preemptively removed by\n     * default, and MAY live in the cache, contributing to its LRU max, long\n     * after they have expired, unless {@link OptionsBase.ttlAutopurge} is\n     * set.\n     *\n     * If set to `0` (the default value), then that means \"do not track\n     * TTL\", not \"expire immediately\".\n     *\n     * Also, as this cache is optimized for LRU/MRU operations, some of\n     * the staleness/TTL checks will reduce performance, as they will incur\n     * overhead by deleting items.\n     *\n     * This is not primarily a TTL cache, and does not make strong TTL\n     * guarantees. There is no pre-emptive pruning of expired items, but you\n     * _may_ set a TTL on the cache, and it will treat expired items as missing\n     * when they are fetched, and delete them.\n     *\n     * Optional, but must be a non-negative integer in ms if specified.\n     *\n     * This may be overridden by passing an options object to `cache.set()`.\n     *\n     * At least one of `max`, `maxSize`, or `TTL` is required. This must be a\n     * positive integer if set.\n     *\n     * Even if ttl tracking is enabled, **it is strongly recommended to set a\n     * `max` to prevent unbounded growth of the cache.**\n     *\n     * If ttl tracking is enabled, and `max` and `maxSize` are not set,\n     * and `ttlAutopurge` is not set, then a warning will be emitted\n     * cautioning about the potential for unbounded memory consumption.\n     * (The TypeScript definitions will also discourage this.)\n     */\n    ttl?: Milliseconds\n\n    /**\n     * Minimum amount of time in ms in which to check for staleness.\n     * Defaults to 1, which means that the current time is checked\n     * at most once per millisecond.\n     *\n     * Set to 0 to check the current time every time staleness is tested.\n     * (This reduces performance, and is theoretically unnecessary.)\n     *\n     * Setting this to a higher value will improve performance somewhat\n     * while using ttl tracking, albeit at the expense of keeping stale\n     * items around a bit longer than their TTLs would indicate.\n     *\n     * @default 1\n     */\n    ttlResolution?: Milliseconds\n\n    /**\n     * Preemptively remove stale items from the cache.\n     *\n     * Note that this may *significantly* degrade performance, especially if\n     * the cache is storing a large number of items. It is almost always best\n     * to just leave the stale items in the cache, and let them fall out as new\n     * items are added.\n     *\n     * Note that this means that {@link OptionsBase.allowStale} is a bit\n     * pointless, as stale items will be deleted almost as soon as they\n     * expire.\n     *\n     * Use with caution!\n     */\n    ttlAutopurge?: boolean\n\n    /**\n     * When using time-expiring entries with `ttl`, setting this to `true` will\n     * make each item's age reset to 0 whenever it is retrieved from cache with\n     * {@link LRUCache#get}, causing it to not expire. (It can still fall out\n     * of cache based on recency of use, of course.)\n     *\n     * Has no effect if {@link OptionsBase.ttl} is not set.\n     *\n     * This may be overridden by passing an options object to `cache.get()`.\n     */\n    updateAgeOnGet?: boolean\n\n    /**\n     * When using time-expiring entries with `ttl`, setting this to `true` will\n     * make each item's age reset to 0 whenever its presence in the cache is\n     * checked with {@link LRUCache#has}, causing it to not expire. (It can\n     * still fall out of cache based on recency of use, of course.)\n     *\n     * Has no effect if {@link OptionsBase.ttl} is not set.\n     */\n    updateAgeOnHas?: boolean\n\n    /**\n     * Allow {@link LRUCache#get} and {@link LRUCache#fetch} calls to return\n     * stale data, if available.\n     *\n     * By default, if you set `ttl`, stale items will only be deleted from the\n     * cache when you `get(key)`. That is, it's not preemptively pruning items,\n     * unless {@link OptionsBase.ttlAutopurge} is set.\n     *\n     * If you set `allowStale:true`, it'll return the stale value *as well as*\n     * deleting it. If you don't set this, then it'll return `undefined` when\n     * you try to get a stale entry.\n     *\n     * Note that when a stale entry is fetched, _even if it is returned due to\n     * `allowStale` being set_, it is removed from the cache immediately. You\n     * can suppress this behavior by setting\n     * {@link OptionsBase.noDeleteOnStaleGet}, either in the constructor, or in\n     * the options provided to {@link LRUCache#get}.\n     *\n     * This may be overridden by passing an options object to `cache.get()`.\n     * The `cache.has()` method will always return `false` for stale items.\n     *\n     * Only relevant if a ttl is set.\n     */\n    allowStale?: boolean\n\n    /**\n     * Function that is called on items when they are dropped from the\n     * cache, as `dispose(value, key, reason)`.\n     *\n     * This can be handy if you want to close file descriptors or do\n     * other cleanup tasks when items are no longer stored in the cache.\n     *\n     * **NOTE**: It is called _before_ the item has been fully removed\n     * from the cache, so if you want to put it right back in, you need\n     * to wait until the next tick. If you try to add it back in during\n     * the `dispose()` function call, it will break things in subtle and\n     * weird ways.\n     *\n     * Unlike several other options, this may _not_ be overridden by\n     * passing an option to `set()`, for performance reasons.\n     *\n     * The `reason` will be one of the following strings, corresponding\n     * to the reason for the item's deletion:\n     *\n     * - `evict` Item was evicted to make space for a new addition\n     * - `set` Item was overwritten by a new value\n     * - `expire` Item expired its TTL\n     * - `fetch` Item was deleted due to a failed or aborted fetch, or a\n     *   fetchMethod returning `undefined.\n     * - `delete` Item was removed by explicit `cache.delete(key)`,\n     *   `cache.clear()`, or `cache.set(key, undefined)`.\n     */\n    dispose?: Disposer<K, V>\n\n    /**\n     * The same as {@link OptionsBase.dispose}, but called *after* the entry\n     * is completely removed and the cache is once again in a clean state.\n     *\n     * It is safe to add an item right back into the cache at this point.\n     * However, note that it is *very* easy to inadvertently create infinite\n     * recursion this way.\n     */\n    disposeAfter?: Disposer<K, V>\n\n    /**\n     * Set to true to suppress calling the\n     * {@link OptionsBase.dispose} function if the entry key is\n     * still accessible within the cache.\n     *\n     * This may be overridden by passing an options object to\n     * {@link LRUCache#set}.\n     *\n     * Only relevant if `dispose` or `disposeAfter` are set.\n     */\n    noDisposeOnSet?: boolean\n\n    /**\n     * Boolean flag to tell the cache to not update the TTL when setting a new\n     * value for an existing key (ie, when updating a value rather than\n     * inserting a new value).  Note that the TTL value is _always_ set (if\n     * provided) when adding a new entry into the cache.\n     *\n     * Has no effect if a {@link OptionsBase.ttl} is not set.\n     *\n     * May be passed as an option to {@link LRUCache#set}.\n     */\n    noUpdateTTL?: boolean\n\n    /**\n     * Set to a positive integer to track the sizes of items added to the\n     * cache, and automatically evict items in order to stay below this size.\n     * Note that this may result in fewer than `max` items being stored.\n     *\n     * Attempting to add an item to the cache whose calculated size is greater\n     * that this amount will be a no-op. The item will not be cached, and no\n     * other items will be evicted.\n     *\n     * Optional, must be a positive integer if provided.\n     *\n     * Sets `maxEntrySize` to the same value, unless a different value is\n     * provided for `maxEntrySize`.\n     *\n     * At least one of `max`, `maxSize`, or `TTL` is required. This must be a\n     * positive integer if set.\n     *\n     * Even if size tracking is enabled, **it is strongly recommended to set a\n     * `max` to prevent unbounded growth of the cache.**\n     *\n     * Note also that size tracking can negatively impact performance,\n     * though for most cases, only minimally.\n     */\n    maxSize?: Size\n\n    /**\n     * The maximum allowed size for any single item in the cache.\n     *\n     * If a larger item is passed to {@link LRUCache#set} or returned by a\n     * {@link OptionsBase.fetchMethod} or {@link OptionsBase.memoMethod}, then\n     * it will not be stored in the cache.\n     *\n     * Attempting to add an item whose calculated size is greater than\n     * this amount will not cache the item or evict any old items, but\n     * WILL delete an existing value if one is already present.\n     *\n     * Optional, must be a positive integer if provided. Defaults to\n     * the value of `maxSize` if provided.\n     */\n    maxEntrySize?: Size\n\n    /**\n     * A function that returns a number indicating the item's size.\n     *\n     * Requires {@link OptionsBase.maxSize} to be set.\n     *\n     * If not provided, and {@link OptionsBase.maxSize} or\n     * {@link OptionsBase.maxEntrySize} are set, then all\n     * {@link LRUCache#set} calls **must** provide an explicit\n     * {@link SetOptions.size} or sizeCalculation param.\n     */\n    sizeCalculation?: SizeCalculator<K, V>\n\n    /**\n     * Method that provides the implementation for {@link LRUCache#fetch}\n     *\n     * ```ts\n     * fetchMethod(key, staleValue, { signal, options, context })\n     * ```\n     *\n     * If `fetchMethod` is not provided, then `cache.fetch(key)` is equivalent\n     * to `Promise.resolve(cache.get(key))`.\n     *\n     * If at any time, `signal.aborted` is set to `true`, or if the\n     * `signal.onabort` method is called, or if it emits an `'abort'` event\n     * which you can listen to with `addEventListener`, then that means that\n     * the fetch should be abandoned. This may be passed along to async\n     * functions aware of AbortController/AbortSignal behavior.\n     *\n     * The `fetchMethod` should **only** return `undefined` or a Promise\n     * resolving to `undefined` if the AbortController signaled an `abort`\n     * event. In all other cases, it should return or resolve to a value\n     * suitable for adding to the cache.\n     *\n     * The `options` object is a union of the options that may be provided to\n     * `set()` and `get()`. If they are modified, then that will result in\n     * modifying the settings to `cache.set()` when the value is resolved, and\n     * in the case of\n     * {@link OptionsBase.noDeleteOnFetchRejection} and\n     * {@link OptionsBase.allowStaleOnFetchRejection}, the handling of\n     * `fetchMethod` failures.\n     *\n     * For example, a DNS cache may update the TTL based on the value returned\n     * from a remote DNS server by changing `options.ttl` in the `fetchMethod`.\n     */\n    fetchMethod?: Fetcher<K, V, FC>\n\n    /**\n     * Method that provides the implementation for {@link LRUCache#memo}\n     */\n    memoMethod?: Memoizer<K, V, FC>\n\n    /**\n     * Set to true to suppress the deletion of stale data when a\n     * {@link OptionsBase.fetchMethod} returns a rejected promise.\n     */\n    noDeleteOnFetchRejection?: boolean\n\n    /**\n     * Do not delete stale items when they are retrieved with\n     * {@link LRUCache#get}.\n     *\n     * Note that the `get` return value will still be `undefined`\n     * unless {@link OptionsBase.allowStale} is true.\n     *\n     * When using time-expiring entries with `ttl`, by default stale\n     * items will be removed from the cache when the key is accessed\n     * with `cache.get()`.\n     *\n     * Setting this option will cause stale items to remain in the cache, until\n     * they are explicitly deleted with `cache.delete(key)`, or retrieved with\n     * `noDeleteOnStaleGet` set to `false`.\n     *\n     * This may be overridden by passing an options object to `cache.get()`.\n     *\n     * Only relevant if a ttl is used.\n     */\n    noDeleteOnStaleGet?: boolean\n\n    /**\n     * Set to true to allow returning stale data when a\n     * {@link OptionsBase.fetchMethod} throws an error or returns a rejected\n     * promise.\n     *\n     * This differs from using {@link OptionsBase.allowStale} in that stale\n     * data will ONLY be returned in the case that the {@link LRUCache#fetch}\n     * fails, not any other times.\n     *\n     * If a `fetchMethod` fails, and there is no stale value available, the\n     * `fetch()` will resolve to `undefined`. Ie, all `fetchMethod` errors are\n     * suppressed.\n     *\n     * Implies `noDeleteOnFetchRejection`.\n     *\n     * This may be set in calls to `fetch()`, or defaulted on the constructor,\n     * or overridden by modifying the options object in the `fetchMethod`.\n     */\n    allowStaleOnFetchRejection?: boolean\n\n    /**\n     * Set to true to return a stale value from the cache when the\n     * `AbortSignal` passed to the {@link OptionsBase.fetchMethod} dispatches\n     * an `'abort'` event, whether user-triggered, or due to internal cache\n     * behavior.\n     *\n     * Unless {@link OptionsBase.ignoreFetchAbort} is also set, the underlying\n     * {@link OptionsBase.fetchMethod} will still be considered canceled, and\n     * any value it returns will be ignored and not cached.\n     *\n     * Caveat: since fetches are aborted when a new value is explicitly\n     * set in the cache, this can lead to fetch returning a stale value,\n     * since that was the fallback value _at the moment the `fetch()` was\n     * initiated_, even though the new updated value is now present in\n     * the cache.\n     *\n     * For example:\n     *\n     * ```ts\n     * const cache = new LRUCache<string, any>({\n     *   ttl: 100,\n     *   fetchMethod: async (url, oldValue, { signal }) =>  {\n     *     const res = await fetch(url, { signal })\n     *     return await res.json()\n     *   }\n     * })\n     * cache.set('https://example.com/', { some: 'data' })\n     * // 100ms go by...\n     * const result = cache.fetch('https://example.com/')\n     * cache.set('https://example.com/', { other: 'thing' })\n     * console.log(await result) // { some: 'data' }\n     * console.log(cache.get('https://example.com/')) // { other: 'thing' }\n     * ```\n     */\n    allowStaleOnFetchAbort?: boolean\n\n    /**\n     * Set to true to ignore the `abort` event emitted by the `AbortSignal`\n     * object passed to {@link OptionsBase.fetchMethod}, and still cache the\n     * resulting resolution value, as long as it is not `undefined`.\n     *\n     * When used on its own, this means aborted {@link LRUCache#fetch} calls\n     * are not immediately resolved or rejected when they are aborted, and\n     * instead take the full time to await.\n     *\n     * When used with {@link OptionsBase.allowStaleOnFetchAbort}, aborted\n     * {@link LRUCache#fetch} calls will resolve immediately to their stale\n     * cached value or `undefined`, and will continue to process and eventually\n     * update the cache when they resolve, as long as the resulting value is\n     * not `undefined`, thus supporting a \"return stale on timeout while\n     * refreshing\" mechanism by passing `AbortSignal.timeout(n)` as the signal.\n     *\n     * For example:\n     *\n     * ```ts\n     * const c = new LRUCache({\n     *   ttl: 100,\n     *   ignoreFetchAbort: true,\n     *   allowStaleOnFetchAbort: true,\n     *   fetchMethod: async (key, oldValue, { signal }) => {\n     *     // note: do NOT pass the signal to fetch()!\n     *     // let's say this fetch can take a long time.\n     *     const res = await fetch(`https://slow-backend-server/${key}`)\n     *     return await res.json()\n     *   },\n     * })\n     *\n     * // this will return the stale value after 100ms, while still\n     * // updating in the background for next time.\n     * const val = await c.fetch('key', { signal: AbortSignal.timeout(100) })\n     * ```\n     *\n     * **Note**: regardless of this setting, an `abort` event _is still\n     * emitted on the `AbortSignal` object_, so may result in invalid results\n     * when passed to other underlying APIs that use AbortSignals.\n     *\n     * This may be overridden in the {@link OptionsBase.fetchMethod} or the\n     * call to {@link LRUCache#fetch}.\n     */\n    ignoreFetchAbort?: boolean\n  }\n\n  export interface OptionsMaxLimit<K, V, FC>\n    extends OptionsBase<K, V, FC> {\n    max: Count\n  }\n  export interface OptionsTTLLimit<K, V, FC>\n    extends OptionsBase<K, V, FC> {\n    ttl: Milliseconds\n    ttlAutopurge: boolean\n  }\n  export interface OptionsSizeLimit<K, V, FC>\n    extends OptionsBase<K, V, FC> {\n    maxSize: Size\n  }\n\n  /**\n   * The valid safe options for the {@link LRUCache} constructor\n   */\n  export type Options<K, V, FC> =\n    | OptionsMaxLimit<K, V, FC>\n    | OptionsSizeLimit<K, V, FC>\n    | OptionsTTLLimit<K, V, FC>\n\n  /**\n   * Entry objects used by {@link LRUCache#load} and {@link LRUCache#dump},\n   * and returned by {@link LRUCache#info}.\n   */\n  export interface Entry<V> {\n    value: V\n    ttl?: Milliseconds\n    size?: Size\n    start?: Milliseconds\n  }\n}\n\n/**\n * Default export, the thing you're using this module to get.\n *\n * The `K` and `V` types define the key and value types, respectively. The\n * optional `FC` type defines the type of the `context` object passed to\n * `cache.fetch()` and `cache.memo()`.\n *\n * Keys and values **must not** be `null` or `undefined`.\n *\n * All properties from the options object (with the exception of `max`,\n * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are\n * added as normal public members. (The listed options are read-only getters.)\n *\n * Changing any of these will alter the defaults for subsequent method calls.\n */\nexport class LRUCache<K extends {}, V extends {}, FC = unknown>\n  implements Map<K, V>\n{\n  // options that cannot be changed without disaster\n  readonly #max: LRUCache.Count\n  readonly #maxSize: LRUCache.Size\n  readonly #dispose?: LRUCache.Disposer<K, V>\n  readonly #disposeAfter?: LRUCache.Disposer<K, V>\n  readonly #fetchMethod?: LRUCache.Fetcher<K, V, FC>\n  readonly #memoMethod?: LRUCache.Memoizer<K, V, FC>\n\n  /**\n   * {@link LRUCache.OptionsBase.ttl}\n   */\n  ttl: LRUCache.Milliseconds\n\n  /**\n   * {@link LRUCache.OptionsBase.ttlResolution}\n   */\n  ttlResolution: LRUCache.Milliseconds\n  /**\n   * {@link LRUCache.OptionsBase.ttlAutopurge}\n   */\n  ttlAutopurge: boolean\n  /**\n   * {@link LRUCache.OptionsBase.updateAgeOnGet}\n   */\n  updateAgeOnGet: boolean\n  /**\n   * {@link LRUCache.OptionsBase.updateAgeOnHas}\n   */\n  updateAgeOnHas: boolean\n  /**\n   * {@link LRUCache.OptionsBase.allowStale}\n   */\n  allowStale: boolean\n\n  /**\n   * {@link LRUCache.OptionsBase.noDisposeOnSet}\n   */\n  noDisposeOnSet: boolean\n  /**\n   * {@link LRUCache.OptionsBase.noUpdateTTL}\n   */\n  noUpdateTTL: boolean\n  /**\n   * {@link LRUCache.OptionsBase.maxEntrySize}\n   */\n  maxEntrySize: LRUCache.Size\n  /**\n   * {@link LRUCache.OptionsBase.sizeCalculation}\n   */\n  sizeCalculation?: LRUCache.SizeCalculator<K, V>\n  /**\n   * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}\n   */\n  noDeleteOnFetchRejection: boolean\n  /**\n   * {@link LRUCache.OptionsBase.noDeleteOnStaleGet}\n   */\n  noDeleteOnStaleGet: boolean\n  /**\n   * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}\n   */\n  allowStaleOnFetchAbort: boolean\n  /**\n   * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}\n   */\n  allowStaleOnFetchRejection: boolean\n  /**\n   * {@link LRUCache.OptionsBase.ignoreFetchAbort}\n   */\n  ignoreFetchAbort: boolean\n\n  // computed properties\n  #size: LRUCache.Count\n  #calculatedSize: LRUCache.Size\n  #keyMap: Map<K, Index>\n  #keyList: (K | undefined)[]\n  #valList: (V | BackgroundFetch<V> | undefined)[]\n  #next: NumberArray\n  #prev: NumberArray\n  #head: Index\n  #tail: Index\n  #free: StackLike\n  #disposed?: DisposeTask<K, V>[]\n  #sizes?: ZeroArray\n  #starts?: ZeroArray\n  #ttls?: ZeroArray\n\n  #hasDispose: boolean\n  #hasFetchMethod: boolean\n  #hasDisposeAfter: boolean\n\n  /**\n   * Do not call this method unless you need to inspect the\n   * inner workings of the cache.  If anything returned by this\n   * object is modified in any way, strange breakage may occur.\n   *\n   * These fields are private for a reason!\n   *\n   * @internal\n   */\n  static unsafeExposeInternals<\n    K extends {},\n    V extends {},\n    FC extends unknown = unknown\n  >(c: LRUCache<K, V, FC>) {\n    return {\n      // properties\n      starts: c.#starts,\n      ttls: c.#ttls,\n      sizes: c.#sizes,\n      keyMap: c.#keyMap as Map<K, number>,\n      keyList: c.#keyList,\n      valList: c.#valList,\n      next: c.#next,\n      prev: c.#prev,\n      get head() {\n        return c.#head\n      },\n      get tail() {\n        return c.#tail\n      },\n      free: c.#free,\n      // methods\n      isBackgroundFetch: (p: any) => c.#isBackgroundFetch(p),\n      backgroundFetch: (\n        k: K,\n        index: number | undefined,\n        options: LRUCache.FetchOptions<K, V, FC>,\n        context: any\n      ): BackgroundFetch<V> =>\n        c.#backgroundFetch(\n          k,\n          index as Index | undefined,\n          options,\n          context\n        ),\n      moveToTail: (index: number): void =>\n        c.#moveToTail(index as Index),\n      indexes: (options?: { allowStale: boolean }) =>\n        c.#indexes(options),\n      rindexes: (options?: { allowStale: boolean }) =>\n        c.#rindexes(options),\n      isStale: (index: number | undefined) =>\n        c.#isStale(index as Index),\n    }\n  }\n\n  // Protected read-only members\n\n  /**\n   * {@link LRUCache.OptionsBase.max} (read-only)\n   */\n  get max(): LRUCache.Count {\n    return this.#max\n  }\n  /**\n   * {@link LRUCache.OptionsBase.maxSize} (read-only)\n   */\n  get maxSize(): LRUCache.Count {\n    return this.#maxSize\n  }\n  /**\n   * The total computed size of items in the cache (read-only)\n   */\n  get calculatedSize(): LRUCache.Size {\n    return this.#calculatedSize\n  }\n  /**\n   * The number of items stored in the cache (read-only)\n   */\n  get size(): LRUCache.Count {\n    return this.#size\n  }\n  /**\n   * {@link LRUCache.OptionsBase.fetchMethod} (read-only)\n   */\n  get fetchMethod(): LRUCache.Fetcher<K, V, FC> | undefined {\n    return this.#fetchMethod\n  }\n  get memoMethod(): LRUCache.Memoizer<K, V, FC> | undefined {\n    return this.#memoMethod\n  }\n  /**\n   * {@link LRUCache.OptionsBase.dispose} (read-only)\n   */\n  get dispose() {\n    return this.#dispose\n  }\n  /**\n   * {@link LRUCache.OptionsBase.disposeAfter} (read-only)\n   */\n  get disposeAfter() {\n    return this.#disposeAfter\n  }\n\n  constructor(\n    options: LRUCache.Options<K, V, FC> | LRUCache<K, V, FC>\n  ) {\n    const {\n      max = 0,\n      ttl,\n      ttlResolution = 1,\n      ttlAutopurge,\n      updateAgeOnGet,\n      updateAgeOnHas,\n      allowStale,\n      dispose,\n      disposeAfter,\n      noDisposeOnSet,\n      noUpdateTTL,\n      maxSize = 0,\n      maxEntrySize = 0,\n      sizeCalculation,\n      fetchMethod,\n      memoMethod,\n      noDeleteOnFetchRejection,\n      noDeleteOnStaleGet,\n      allowStaleOnFetchRejection,\n      allowStaleOnFetchAbort,\n      ignoreFetchAbort,\n    } = options\n\n    if (max !== 0 && !isPosInt(max)) {\n      throw new TypeError('max option must be a nonnegative integer')\n    }\n\n    const UintArray = max ? getUintArray(max) : Array\n    if (!UintArray) {\n      throw new Error('invalid max value: ' + max)\n    }\n\n    this.#max = max\n    this.#maxSize = maxSize\n    this.maxEntrySize = maxEntrySize || this.#maxSize\n    this.sizeCalculation = sizeCalculation\n    if (this.sizeCalculation) {\n      if (!this.#maxSize && !this.maxEntrySize) {\n        throw new TypeError(\n          'cannot set sizeCalculation without setting maxSize or maxEntrySize'\n        )\n      }\n      if (typeof this.sizeCalculation !== 'function') {\n        throw new TypeError('sizeCalculation set to non-function')\n      }\n    }\n\n    if (\n      memoMethod !== undefined &&\n      typeof memoMethod !== 'function'\n    ) {\n      throw new TypeError('memoMethod must be a function if defined')\n    }\n    this.#memoMethod = memoMethod\n\n    if (\n      fetchMethod !== undefined &&\n      typeof fetchMethod !== 'function'\n    ) {\n      throw new TypeError(\n        'fetchMethod must be a function if specified'\n      )\n    }\n    this.#fetchMethod = fetchMethod\n    this.#hasFetchMethod = !!fetchMethod\n\n    this.#keyMap = new Map()\n    this.#keyList = new Array(max).fill(undefined)\n    this.#valList = new Array(max).fill(undefined)\n    this.#next = new UintArray(max)\n    this.#prev = new UintArray(max)\n    this.#head = 0 as Index\n    this.#tail = 0 as Index\n    this.#free = Stack.create(max)\n    this.#size = 0\n    this.#calculatedSize = 0\n\n    if (typeof dispose === 'function') {\n      this.#dispose = dispose\n    }\n    if (typeof disposeAfter === 'function') {\n      this.#disposeAfter = disposeAfter\n      this.#disposed = []\n    } else {\n      this.#disposeAfter = undefined\n      this.#disposed = undefined\n    }\n    this.#hasDispose = !!this.#dispose\n    this.#hasDisposeAfter = !!this.#disposeAfter\n\n    this.noDisposeOnSet = !!noDisposeOnSet\n    this.noUpdateTTL = !!noUpdateTTL\n    this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection\n    this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection\n    this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort\n    this.ignoreFetchAbort = !!ignoreFetchAbort\n\n    // NB: maxEntrySize is set to maxSize if it's set\n    if (this.maxEntrySize !== 0) {\n      if (this.#maxSize !== 0) {\n        if (!isPosInt(this.#maxSize)) {\n          throw new TypeError(\n            'maxSize must be a positive integer if specified'\n          )\n        }\n      }\n      if (!isPosInt(this.maxEntrySize)) {\n        throw new TypeError(\n          'maxEntrySize must be a positive integer if specified'\n        )\n      }\n      this.#initializeSizeTracking()\n    }\n\n    this.allowStale = !!allowStale\n    this.noDeleteOnStaleGet = !!noDeleteOnStaleGet\n    this.updateAgeOnGet = !!updateAgeOnGet\n    this.updateAgeOnHas = !!updateAgeOnHas\n    this.ttlResolution =\n      isPosInt(ttlResolution) || ttlResolution === 0\n        ? ttlResolution\n        : 1\n    this.ttlAutopurge = !!ttlAutopurge\n    this.ttl = ttl || 0\n    if (this.ttl) {\n      if (!isPosInt(this.ttl)) {\n        throw new TypeError(\n          'ttl must be a positive integer if specified'\n        )\n      }\n      this.#initializeTTLTracking()\n    }\n\n    // do not allow completely unbounded caches\n    if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) {\n      throw new TypeError(\n        'At least one of max, maxSize, or ttl is required'\n      )\n    }\n    if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {\n      const code = 'LRU_CACHE_UNBOUNDED'\n      if (shouldWarn(code)) {\n        warned.add(code)\n        const msg =\n          'TTL caching without ttlAutopurge, max, or maxSize can ' +\n          'result in unbounded memory consumption.'\n        emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache)\n      }\n    }\n  }\n\n  /**\n   * Return the number of ms left in the item's TTL. If item is not in cache,\n   * returns `0`. Returns `Infinity` if item is in cache without a defined TTL.\n   */\n  getRemainingTTL(key: K) {\n    return this.#keyMap.has(key) ? Infinity : 0\n  }\n\n  #initializeTTLTracking() {\n    const ttls = new ZeroArray(this.#max)\n    const starts = new ZeroArray(this.#max)\n    this.#ttls = ttls\n    this.#starts = starts\n\n    this.#setItemTTL = (index, ttl, start = perf.now()) => {\n      starts[index] = ttl !== 0 ? start : 0\n      ttls[index] = ttl\n      if (ttl !== 0 && this.ttlAutopurge) {\n        const t = setTimeout(() => {\n          if (this.#isStale(index)) {\n            this.#delete(this.#keyList[index] as K, 'expire')\n          }\n        }, ttl + 1)\n        // unref() not supported on all platforms\n        /* c8 ignore start */\n        if (t.unref) {\n          t.unref()\n        }\n        /* c8 ignore stop */\n      }\n    }\n\n    this.#updateItemAge = index => {\n      starts[index] = ttls[index] !== 0 ? perf.now() : 0\n    }\n\n    this.#statusTTL = (status, index) => {\n      if (ttls[index]) {\n        const ttl = ttls[index]\n        const start = starts[index]\n        /* c8 ignore next */\n        if (!ttl || !start) return\n        status.ttl = ttl\n        status.start = start\n        status.now = cachedNow || getNow()\n        const age = status.now - start\n        status.remainingTTL = ttl - age\n      }\n    }\n\n    // debounce calls to perf.now() to 1s so we're not hitting\n    // that costly call repeatedly.\n    let cachedNow = 0\n    const getNow = () => {\n      const n = perf.now()\n      if (this.ttlResolution > 0) {\n        cachedNow = n\n        const t = setTimeout(\n          () => (cachedNow = 0),\n          this.ttlResolution\n        )\n        // not available on all platforms\n        /* c8 ignore start */\n        if (t.unref) {\n          t.unref()\n        }\n        /* c8 ignore stop */\n      }\n      return n\n    }\n\n    this.getRemainingTTL = key => {\n      const index = this.#keyMap.get(key)\n      if (index === undefined) {\n        return 0\n      }\n      const ttl = ttls[index]\n      const start = starts[index]\n      if (!ttl || !start) {\n        return Infinity\n      }\n      const age = (cachedNow || getNow()) - start\n      return ttl - age\n    }\n\n    this.#isStale = index => {\n      const s = starts[index]\n      const t = ttls[index]\n      return !!t && !!s && (cachedNow || getNow()) - s > t\n    }\n  }\n\n  // conditionally set private methods related to TTL\n  #updateItemAge: (index: Index) => void = () => {}\n  #statusTTL: (status: LRUCache.Status<V>, index: Index) => void =\n    () => {}\n  #setItemTTL: (\n    index: Index,\n    ttl: LRUCache.Milliseconds,\n    start?: LRUCache.Milliseconds\n    // ignore because we never call this if we're not already in TTL mode\n    /* c8 ignore start */\n  ) => void = () => {}\n  /* c8 ignore stop */\n\n  #isStale: (index: Index) => boolean = () => false\n\n  #initializeSizeTracking() {\n    const sizes = new ZeroArray(this.#max)\n    this.#calculatedSize = 0\n    this.#sizes = sizes\n    this.#removeItemSize = index => {\n      this.#calculatedSize -= sizes[index] as number\n      sizes[index] = 0\n    }\n    this.#requireSize = (k, v, size, sizeCalculation) => {\n      // provisionally accept background fetches.\n      // actual value size will be checked when they return.\n      if (this.#isBackgroundFetch(v)) {\n        return 0\n      }\n      if (!isPosInt(size)) {\n        if (sizeCalculation) {\n          if (typeof sizeCalculation !== 'function') {\n            throw new TypeError('sizeCalculation must be a function')\n          }\n          size = sizeCalculation(v, k)\n          if (!isPosInt(size)) {\n            throw new TypeError(\n              'sizeCalculation return invalid (expect positive integer)'\n            )\n          }\n        } else {\n          throw new TypeError(\n            'invalid size value (must be positive integer). ' +\n              'When maxSize or maxEntrySize is used, sizeCalculation ' +\n              'or size must be set.'\n          )\n        }\n      }\n      return size\n    }\n    this.#addItemSize = (\n      index: Index,\n      size: LRUCache.Size,\n      status?: LRUCache.Status<V>\n    ) => {\n      sizes[index] = size\n      if (this.#maxSize) {\n        const maxSize = this.#maxSize - (sizes[index] as number)\n        while (this.#calculatedSize > maxSize) {\n          this.#evict(true)\n        }\n      }\n      this.#calculatedSize += sizes[index] as number\n      if (status) {\n        status.entrySize = size\n        status.totalCalculatedSize = this.#calculatedSize\n      }\n    }\n  }\n\n  #removeItemSize: (index: Index) => void = _i => {}\n  #addItemSize: (\n    index: Index,\n    size: LRUCache.Size,\n    status?: LRUCache.Status<V>\n  ) => void = (_i, _s, _st) => {}\n  #requireSize: (\n    k: K,\n    v: V | BackgroundFetch<V>,\n    size?: LRUCache.Size,\n    sizeCalculation?: LRUCache.SizeCalculator<K, V>\n  ) => LRUCache.Size = (\n    _k: K,\n    _v: V | BackgroundFetch<V>,\n    size?: LRUCache.Size,\n    sizeCalculation?: LRUCache.SizeCalculator<K, V>\n  ) => {\n    if (size || sizeCalculation) {\n      throw new TypeError(\n        'cannot set size without setting maxSize or maxEntrySize on cache'\n      )\n    }\n    return 0\n  };\n\n  *#indexes({ allowStale = this.allowStale } = {}) {\n    if (this.#size) {\n      for (let i = this.#tail; true; ) {\n        if (!this.#isValidIndex(i)) {\n          break\n        }\n        if (allowStale || !this.#isStale(i)) {\n          yield i\n        }\n        if (i === this.#head) {\n          break\n        } else {\n          i = this.#prev[i] as Index\n        }\n      }\n    }\n  }\n\n  *#rindexes({ allowStale = this.allowStale } = {}) {\n    if (this.#size) {\n      for (let i = this.#head; true; ) {\n        if (!this.#isValidIndex(i)) {\n          break\n        }\n        if (allowStale || !this.#isStale(i)) {\n          yield i\n        }\n        if (i === this.#tail) {\n          break\n        } else {\n          i = this.#next[i] as Index\n        }\n      }\n    }\n  }\n\n  #isValidIndex(index: Index) {\n    return (\n      index !== undefined &&\n      this.#keyMap.get(this.#keyList[index] as K) === index\n    )\n  }\n\n  /**\n   * Return a generator yielding `[key, value]` pairs,\n   * in order from most recently used to least recently used.\n   */\n  *entries() {\n    for (const i of this.#indexes()) {\n      if (\n        this.#valList[i] !== undefined &&\n        this.#keyList[i] !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield [this.#keyList[i], this.#valList[i]] as [K, V]\n      }\n    }\n  }\n\n  /**\n   * Inverse order version of {@link LRUCache.entries}\n   *\n   * Return a generator yielding `[key, value]` pairs,\n   * in order from least recently used to most recently used.\n   */\n  *rentries() {\n    for (const i of this.#rindexes()) {\n      if (\n        this.#valList[i] !== undefined &&\n        this.#keyList[i] !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield [this.#keyList[i], this.#valList[i]]\n      }\n    }\n  }\n\n  /**\n   * Return a generator yielding the keys in the cache,\n   * in order from most recently used to least recently used.\n   */\n  *keys() {\n    for (const i of this.#indexes()) {\n      const k = this.#keyList[i]\n      if (\n        k !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield k\n      }\n    }\n  }\n\n  /**\n   * Inverse order version of {@link LRUCache.keys}\n   *\n   * Return a generator yielding the keys in the cache,\n   * in order from least recently used to most recently used.\n   */\n  *rkeys() {\n    for (const i of this.#rindexes()) {\n      const k = this.#keyList[i]\n      if (\n        k !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield k\n      }\n    }\n  }\n\n  /**\n   * Return a generator yielding the values in the cache,\n   * in order from most recently used to least recently used.\n   */\n  *values() {\n    for (const i of this.#indexes()) {\n      const v = this.#valList[i]\n      if (\n        v !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield this.#valList[i] as V\n      }\n    }\n  }\n\n  /**\n   * Inverse order version of {@link LRUCache.values}\n   *\n   * Return a generator yielding the values in the cache,\n   * in order from least recently used to most recently used.\n   */\n  *rvalues() {\n    for (const i of this.#rindexes()) {\n      const v = this.#valList[i]\n      if (\n        v !== undefined &&\n        !this.#isBackgroundFetch(this.#valList[i])\n      ) {\n        yield this.#valList[i]\n      }\n    }\n  }\n\n  /**\n   * Iterating over the cache itself yields the same results as\n   * {@link LRUCache.entries}\n   */\n  [Symbol.iterator]() {\n    return this.entries()\n  }\n\n  /**\n   * A String value that is used in the creation of the default string\n   * description of an object. Called by the built-in method\n   * `Object.prototype.toString`.\n   */\n  [Symbol.toStringTag] = 'LRUCache'\n\n  /**\n   * Find a value for which the supplied fn method returns a truthy value,\n   * similar to `Array.find()`. fn is called as `fn(value, key, cache)`.\n   */\n  find(\n    fn: (v: V, k: K, self: LRUCache<K, V, FC>) => boolean,\n    getOptions: LRUCache.GetOptions<K, V, FC> = {}\n  ) {\n    for (const i of this.#indexes()) {\n      const v = this.#valList[i]\n      const value = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined) continue\n      if (fn(value, this.#keyList[i] as K, this)) {\n        return this.get(this.#keyList[i] as K, getOptions)\n      }\n    }\n  }\n\n  /**\n   * Call the supplied function on each item in the cache, in order from most\n   * recently used to least recently used.\n   *\n   * `fn` is called as `fn(value, key, cache)`.\n   *\n   * If `thisp` is provided, function will be called in the `this`-context of\n   * the provided object, or the cache if no `thisp` object is provided.\n   *\n   * Does not update age or recenty of use, or iterate over stale values.\n   */\n  forEach(\n    fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any,\n    thisp: any = this\n  ) {\n    for (const i of this.#indexes()) {\n      const v = this.#valList[i]\n      const value = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined) continue\n      fn.call(thisp, value, this.#keyList[i] as K, this)\n    }\n  }\n\n  /**\n   * The same as {@link LRUCache.forEach} but items are iterated over in\n   * reverse order.  (ie, less recently used items are iterated over first.)\n   */\n  rforEach(\n    fn: (v: V, k: K, self: LRUCache<K, V, FC>) => any,\n    thisp: any = this\n  ) {\n    for (const i of this.#rindexes()) {\n      const v = this.#valList[i]\n      const value = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined) continue\n      fn.call(thisp, value, this.#keyList[i] as K, this)\n    }\n  }\n\n  /**\n   * Delete any stale entries. Returns true if anything was removed,\n   * false otherwise.\n   */\n  purgeStale() {\n    let deleted = false\n    for (const i of this.#rindexes({ allowStale: true })) {\n      if (this.#isStale(i)) {\n        this.#delete(this.#keyList[i] as K, 'expire')\n        deleted = true\n      }\n    }\n    return deleted\n  }\n\n  /**\n   * Get the extended info about a given entry, to get its value, size, and\n   * TTL info simultaneously. Returns `undefined` if the key is not present.\n   *\n   * Unlike {@link LRUCache#dump}, which is designed to be portable and survive\n   * serialization, the `start` value is always the current timestamp, and the\n   * `ttl` is a calculated remaining time to live (negative if expired).\n   *\n   * Always returns stale values, if their info is found in the cache, so be\n   * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})\n   * if relevant.\n   */\n  info(key: K): LRUCache.Entry<V> | undefined {\n    const i = this.#keyMap.get(key)\n    if (i === undefined) return undefined\n    const v = this.#valList[i]\n    const value: V | undefined = this.#isBackgroundFetch(v)\n      ? v.__staleWhileFetching\n      : v\n    if (value === undefined) return undefined\n    const entry: LRUCache.Entry<V> = { value }\n    if (this.#ttls && this.#starts) {\n      const ttl = this.#ttls[i]\n      const start = this.#starts[i]\n      if (ttl && start) {\n        const remain = ttl - (perf.now() - start)\n        entry.ttl = remain\n        entry.start = Date.now()\n      }\n    }\n    if (this.#sizes) {\n      entry.size = this.#sizes[i]\n    }\n    return entry\n  }\n\n  /**\n   * Return an array of [key, {@link LRUCache.Entry}] tuples which can be\n   * passed to {@link LRLUCache#load}.\n   *\n   * The `start` fields are calculated relative to a portable `Date.now()`\n   * timestamp, even if `performance.now()` is available.\n   *\n   * Stale entries are always included in the `dump`, even if\n   * {@link LRUCache.OptionsBase.allowStale} is false.\n   *\n   * Note: this returns an actual array, not a generator, so it can be more\n   * easily passed around.\n   */\n  dump() {\n    const arr: [K, LRUCache.Entry<V>][] = []\n    for (const i of this.#indexes({ allowStale: true })) {\n      const key = this.#keyList[i]\n      const v = this.#valList[i]\n      const value: V | undefined = this.#isBackgroundFetch(v)\n        ? v.__staleWhileFetching\n        : v\n      if (value === undefined || key === undefined) continue\n      const entry: LRUCache.Entry<V> = { value }\n      if (this.#ttls && this.#starts) {\n        entry.ttl = this.#ttls[i]\n        // always dump the start relative to a portable timestamp\n        // it's ok for this to be a bit slow, it's a rare operation.\n        const age = perf.now() - (this.#starts[i] as number)\n        entry.start = Math.floor(Date.now() - age)\n      }\n      if (this.#sizes) {\n        entry.size = this.#sizes[i]\n      }\n      arr.unshift([key, entry])\n    }\n    return arr\n  }\n\n  /**\n   * Reset the cache and load in the items in entries in the order listed.\n   *\n   * The shape of the resulting cache may be different if the same options are\n   * not used in both caches.\n   *\n   * The `start` fields are assumed to be calculated relative to a portable\n   * `Date.now()` timestamp, even if `performance.now()` is available.\n   */\n  load(arr: [K, LRUCache.Entry<V>][]) {\n    this.clear()\n    for (const [key, entry] of arr) {\n      if (entry.start) {\n        // entry.start is a portable timestamp, but we may be using\n        // node's performance.now(), so calculate the offset, so that\n        // we get the intended remaining TTL, no matter how long it's\n        // been on ice.\n        //\n        // it's ok for this to be a bit slow, it's a rare operation.\n        const age = Date.now() - entry.start\n        entry.start = perf.now() - age\n      }\n      this.set(key, entry.value, entry)\n    }\n  }\n\n  /**\n   * Add a value to the cache.\n   *\n   * Note: if `undefined` is specified as a value, this is an alias for\n   * {@link LRUCache#delete}\n   *\n   * Fields on the {@link LRUCache.SetOptions} options param will override\n   * their corresponding values in the constructor options for the scope\n   * of this single `set()` operation.\n   *\n   * If `start` is provided, then that will set the effective start\n   * time for the TTL calculation. Note that this must be a previous\n   * value of `performance.now()` if supported, or a previous value of\n   * `Date.now()` if not.\n   *\n   * Options object may also include `size`, which will prevent\n   * calling the `sizeCalculation` function and just use the specified\n   * number if it is a positive integer, and `noDisposeOnSet` which\n   * will prevent calling a `dispose` function in the case of\n   * overwrites.\n   *\n   * If the `size` (or return value of `sizeCalculation`) for a given\n   * entry is greater than `maxEntrySize`, then the item will not be\n   * added to the cache.\n   *\n   * Will update the recency of the entry.\n   *\n   * If the value is `undefined`, then this is an alias for\n   * `cache.delete(key)`. `undefined` is never stored in the cache.\n   */\n  set(\n    k: K,\n    v: V | BackgroundFetch<V> | undefined,\n    setOptions: LRUCache.SetOptions<K, V, FC> = {}\n  ) {\n    if (v === undefined) {\n      this.delete(k)\n      return this\n    }\n    const {\n      ttl = this.ttl,\n      start,\n      noDisposeOnSet = this.noDisposeOnSet,\n      sizeCalculation = this.sizeCalculation,\n      status,\n    } = setOptions\n    let { noUpdateTTL = this.noUpdateTTL } = setOptions\n\n    const size = this.#requireSize(\n      k,\n      v,\n      setOptions.size || 0,\n      sizeCalculation\n    )\n    // if the item doesn't fit, don't do anything\n    // NB: maxEntrySize set to maxSize by default\n    if (this.maxEntrySize && size > this.maxEntrySize) {\n      if (status) {\n        status.set = 'miss'\n        status.maxEntrySizeExceeded = true\n      }\n      // have to delete, in case something is there already.\n      this.#delete(k, 'set')\n      return this\n    }\n    let index = this.#size === 0 ? undefined : this.#keyMap.get(k)\n    if (index === undefined) {\n      // addition\n      index = (\n        this.#size === 0\n          ? this.#tail\n          : this.#free.length !== 0\n          ? this.#free.pop()\n          : this.#size === this.#max\n          ? this.#evict(false)\n          : this.#size\n      ) as Index\n      this.#keyList[index] = k\n      this.#valList[index] = v\n      this.#keyMap.set(k, index)\n      this.#next[this.#tail] = index\n      this.#prev[index] = this.#tail\n      this.#tail = index\n      this.#size++\n      this.#addItemSize(index, size, status)\n      if (status) status.set = 'add'\n      noUpdateTTL = false\n    } else {\n      // update\n      this.#moveToTail(index)\n      const oldVal = this.#valList[index] as V | BackgroundFetch<V>\n      if (v !== oldVal) {\n        if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {\n          oldVal.__abortController.abort(new Error('replaced'))\n          const { __staleWhileFetching: s } = oldVal\n          if (s !== undefined && !noDisposeOnSet) {\n            if (this.#hasDispose) {\n              this.#dispose?.(s as V, k, 'set')\n            }\n            if (this.#hasDisposeAfter) {\n              this.#disposed?.push([s as V, k, 'set'])\n            }\n          }\n        } else if (!noDisposeOnSet) {\n          if (this.#hasDispose) {\n            this.#dispose?.(oldVal as V, k, 'set')\n          }\n          if (this.#hasDisposeAfter) {\n            this.#disposed?.push([oldVal as V, k, 'set'])\n          }\n        }\n        this.#removeItemSize(index)\n        this.#addItemSize(index, size, status)\n        this.#valList[index] = v\n        if (status) {\n          status.set = 'replace'\n          const oldValue =\n            oldVal && this.#isBackgroundFetch(oldVal)\n              ? oldVal.__staleWhileFetching\n              : oldVal\n          if (oldValue !== undefined) status.oldValue = oldValue\n        }\n      } else if (status) {\n        status.set = 'update'\n      }\n    }\n    if (ttl !== 0 && !this.#ttls) {\n      this.#initializeTTLTracking()\n    }\n    if (this.#ttls) {\n      if (!noUpdateTTL) {\n        this.#setItemTTL(index, ttl, start)\n      }\n      if (status) this.#statusTTL(status, index)\n    }\n    if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {\n      const dt = this.#disposed\n      let task: DisposeTask<K, V> | undefined\n      while ((task = dt?.shift())) {\n        this.#disposeAfter?.(...task)\n      }\n    }\n    return this\n  }\n\n  /**\n   * Evict the least recently used item, returning its value or\n   * `undefined` if cache is empty.\n   */\n  pop(): V | undefined {\n    try {\n      while (this.#size) {\n        const val = this.#valList[this.#head]\n        this.#evict(true)\n        if (this.#isBackgroundFetch(val)) {\n          if (val.__staleWhileFetching) {\n            return val.__staleWhileFetching\n          }\n        } else if (val !== undefined) {\n          return val\n        }\n      }\n    } finally {\n      if (this.#hasDisposeAfter && this.#disposed) {\n        const dt = this.#disposed\n        let task: DisposeTask<K, V> | undefined\n        while ((task = dt?.shift())) {\n          this.#disposeAfter?.(...task)\n        }\n      }\n    }\n  }\n\n  #evict(free: boolean) {\n    const head = this.#head\n    const k = this.#keyList[head] as K\n    const v = this.#valList[head] as V\n    if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) {\n      v.__abortController.abort(new Error('evicted'))\n    } else if (this.#hasDispose || this.#hasDisposeAfter) {\n      if (this.#hasDispose) {\n        this.#dispose?.(v, k, 'evict')\n      }\n      if (this.#hasDisposeAfter) {\n        this.#disposed?.push([v, k, 'evict'])\n      }\n    }\n    this.#removeItemSize(head)\n    // if we aren't about to use the index, then null these out\n    if (free) {\n      this.#keyList[head] = undefined\n      this.#valList[head] = undefined\n      this.#free.push(head)\n    }\n    if (this.#size === 1) {\n      this.#head = this.#tail = 0 as Index\n      this.#free.length = 0\n    } else {\n      this.#head = this.#next[head] as Index\n    }\n    this.#keyMap.delete(k)\n    this.#size--\n    return head\n  }\n\n  /**\n   * Check if a key is in the cache, without updating the recency of use.\n   * Will return false if the item is stale, even though it is technically\n   * in the cache.\n   *\n   * Check if a key is in the cache, without updating the recency of\n   * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set\n   * to `true` in either the options or the constructor.\n   *\n   * Will return `false` if the item is stale, even though it is technically in\n   * the cache. The difference can be determined (if it matters) by using a\n   * `status` argument, and inspecting the `has` field.\n   *\n   * Will not update item age unless\n   * {@link LRUCache.OptionsBase.updateAgeOnHas} is set.\n   */\n  has(k: K, hasOptions: LRUCache.HasOptions<K, V, FC> = {}) {\n    const { updateAgeOnHas = this.updateAgeOnHas, status } =\n      hasOptions\n    const index = this.#keyMap.get(k)\n    if (index !== undefined) {\n      const v = this.#valList[index]\n      if (\n        this.#isBackgroundFetch(v) &&\n        v.__staleWhileFetching === undefined\n      ) {\n        return false\n      }\n      if (!this.#isStale(index)) {\n        if (updateAgeOnHas) {\n          this.#updateItemAge(index)\n        }\n        if (status) {\n          status.has = 'hit'\n          this.#statusTTL(status, index)\n        }\n        return true\n      } else if (status) {\n        status.has = 'stale'\n        this.#statusTTL(status, index)\n      }\n    } else if (status) {\n      status.has = 'miss'\n    }\n    return false\n  }\n\n  /**\n   * Like {@link LRUCache#get} but doesn't update recency or delete stale\n   * items.\n   *\n   * Returns `undefined` if the item is stale, unless\n   * {@link LRUCache.OptionsBase.allowStale} is set.\n   */\n  peek(k: K, peekOptions: LRUCache.PeekOptions<K, V, FC> = {}) {\n    const { allowStale = this.allowStale } = peekOptions\n    const index = this.#keyMap.get(k)\n    if (\n      index === undefined ||\n      (!allowStale && this.#isStale(index))\n    ) {\n      return\n    }\n    const v = this.#valList[index]\n    // either stale and allowed, or forcing a refresh of non-stale value\n    return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v\n  }\n\n  #backgroundFetch(\n    k: K,\n    index: Index | undefined,\n    options: LRUCache.FetchOptions<K, V, FC>,\n    context: any\n  ): BackgroundFetch<V> {\n    const v = index === undefined ? undefined : this.#valList[index]\n    if (this.#isBackgroundFetch(v)) {\n      return v\n    }\n\n    const ac = new AC()\n    const { signal } = options\n    // when/if our AC signals, then stop listening to theirs.\n    signal?.addEventListener('abort', () => ac.abort(signal.reason), {\n      signal: ac.signal,\n    })\n\n    const fetchOpts = {\n      signal: ac.signal,\n      options,\n      context,\n    }\n\n    const cb = (\n      v: V | undefined,\n      updateCache = false\n    ): V | undefined => {\n      const { aborted } = ac.signal\n      const ignoreAbort = options.ignoreFetchAbort && v !== undefined\n      if (options.status) {\n        if (aborted && !updateCache) {\n          options.status.fetchAborted = true\n          options.status.fetchError = ac.signal.reason\n          if (ignoreAbort) options.status.fetchAbortIgnored = true\n        } else {\n          options.status.fetchResolved = true\n        }\n      }\n      if (aborted && !ignoreAbort && !updateCache) {\n        return fetchFail(ac.signal.reason)\n      }\n      // either we didn't abort, and are still here, or we did, and ignored\n      const bf = p as BackgroundFetch<V>\n      if (this.#valList[index as Index] === p) {\n        if (v === undefined) {\n          if (bf.__staleWhileFetching) {\n            this.#valList[index as Index] = bf.__staleWhileFetching\n          } else {\n            this.#delete(k, 'fetch')\n          }\n        } else {\n          if (options.status) options.status.fetchUpdated = true\n          this.set(k, v, fetchOpts.options)\n        }\n      }\n      return v\n    }\n\n    const eb = (er: any) => {\n      if (options.status) {\n        options.status.fetchRejected = true\n        options.status.fetchError = er\n      }\n      return fetchFail(er)\n    }\n\n    const fetchFail = (er: any): V | undefined => {\n      const { aborted } = ac.signal\n      const allowStaleAborted =\n        aborted && options.allowStaleOnFetchAbort\n      const allowStale =\n        allowStaleAborted || options.allowStaleOnFetchRejection\n      const noDelete = allowStale || options.noDeleteOnFetchRejection\n      const bf = p as BackgroundFetch<V>\n      if (this.#valList[index as Index] === p) {\n        // if we allow stale on fetch rejections, then we need to ensure that\n        // the stale value is not removed from the cache when the fetch fails.\n        const del = !noDelete || bf.__staleWhileFetching === undefined\n        if (del) {\n          this.#delete(k, 'fetch')\n        } else if (!allowStaleAborted) {\n          // still replace the *promise* with the stale value,\n          // since we are done with the promise at this point.\n          // leave it untouched if we're still waiting for an\n          // aborted background fetch that hasn't yet returned.\n          this.#valList[index as Index] = bf.__staleWhileFetching\n        }\n      }\n      if (allowStale) {\n        if (options.status && bf.__staleWhileFetching !== undefined) {\n          options.status.returnedStale = true\n        }\n        return bf.__staleWhileFetching\n      } else if (bf.__returned === bf) {\n        throw er\n      }\n    }\n\n    const pcall = (\n      res: (v: V | undefined) => void,\n      rej: (e: any) => void\n    ) => {\n      const fmp = this.#fetchMethod?.(k, v, fetchOpts)\n      if (fmp && fmp instanceof Promise) {\n        fmp.then(v => res(v === undefined ? undefined : v), rej)\n      }\n      // ignored, we go until we finish, regardless.\n      // defer check until we are actually aborting,\n      // so fetchMethod can override.\n      ac.signal.addEventListener('abort', () => {\n        if (\n          !options.ignoreFetchAbort ||\n          options.allowStaleOnFetchAbort\n        ) {\n          res(undefined)\n          // when it eventually resolves, update the cache.\n          if (options.allowStaleOnFetchAbort) {\n            res = v => cb(v, true)\n          }\n        }\n      })\n    }\n\n    if (options.status) options.status.fetchDispatched = true\n    const p = new Promise(pcall).then(cb, eb)\n    const bf: BackgroundFetch<V> = Object.assign(p, {\n      __abortController: ac,\n      __staleWhileFetching: v,\n      __returned: undefined,\n    })\n\n    if (index === undefined) {\n      // internal, don't expose status.\n      this.set(k, bf, { ...fetchOpts.options, status: undefined })\n      index = this.#keyMap.get(k)\n    } else {\n      this.#valList[index] = bf\n    }\n    return bf\n  }\n\n  #isBackgroundFetch(p: any): p is BackgroundFetch<V> {\n    if (!this.#hasFetchMethod) return false\n    const b = p as BackgroundFetch<V>\n    return (\n      !!b &&\n      b instanceof Promise &&\n      b.hasOwnProperty('__staleWhileFetching') &&\n      b.__abortController instanceof AC\n    )\n  }\n\n  /**\n   * Make an asynchronous cached fetch using the\n   * {@link LRUCache.OptionsBase.fetchMethod} function.\n   *\n   * If the value is in the cache and not stale, then the returned\n   * Promise resolves to the value.\n   *\n   * If not in the cache, or beyond its TTL staleness, then\n   * `fetchMethod(key, staleValue, { options, signal, context })` is\n   * called, and the value returned will be added to the cache once\n   * resolved.\n   *\n   * If called with `allowStale`, and an asynchronous fetch is\n   * currently in progress to reload a stale value, then the former\n   * stale value will be returned.\n   *\n   * If called with `forceRefresh`, then the cached item will be\n   * re-fetched, even if it is not stale. However, if `allowStale` is also\n   * set, then the old value will still be returned. This is useful\n   * in cases where you want to force a reload of a cached value. If\n   * a background fetch is already in progress, then `forceRefresh`\n   * has no effect.\n   *\n   * If multiple fetches for the same key are issued, then they will all be\n   * coalesced into a single call to fetchMethod.\n   *\n   * Note that this means that handling options such as\n   * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort},\n   * {@link LRUCache.FetchOptions.signal},\n   * and {@link LRUCache.OptionsBase.allowStaleOnFetchRejection} will be\n   * determined by the FIRST fetch() call for a given key.\n   *\n   * This is a known (fixable) shortcoming which will be addresed on when\n   * someone complains about it, as the fix would involve added complexity and\n   * may not be worth the costs for this edge case.\n   *\n   * If {@link LRUCache.OptionsBase.fetchMethod} is not specified, then this is\n   * effectively an alias for `Promise.resolve(cache.get(key))`.\n   *\n   * When the fetch method resolves to a value, if the fetch has not\n   * been aborted due to deletion, eviction, or being overwritten,\n   * then it is added to the cache using the options provided.\n   *\n   * If the key is evicted or deleted before the `fetchMethod`\n   * resolves, then the AbortSignal passed to the `fetchMethod` will\n   * receive an `abort` event, and the promise returned by `fetch()`\n   * will reject with the reason for the abort.\n   *\n   * If a `signal` is passed to the `fetch()` call, then aborting the\n   * signal will abort the fetch and cause the `fetch()` promise to\n   * reject with the reason provided.\n   *\n   * **Setting `context`**\n   *\n   * If an `FC` type is set to a type other than `unknown`, `void`, or\n   * `undefined` in the {@link LRUCache} constructor, then all\n   * calls to `cache.fetch()` _must_ provide a `context` option. If\n   * set to `undefined` or `void`, then calls to fetch _must not_\n   * provide a `context` option.\n   *\n   * The `context` param allows you to provide arbitrary data that\n   * might be relevant in the course of fetching the data. It is only\n   * relevant for the course of a single `fetch()` operation, and\n   * discarded afterwards.\n   *\n   * **Note: `fetch()` calls are inflight-unique**\n   *\n   * If you call `fetch()` multiple times with the same key value,\n   * then every call after the first will resolve on the same\n   * promise<sup>1</sup>,\n   * _even if they have different settings that would otherwise change\n   * the behavior of the fetch_, such as `noDeleteOnFetchRejection`\n   * or `ignoreFetchAbort`.\n   *\n   * In most cases, this is not a problem (in fact, only fetching\n   * something once is what you probably want, if you're caching in\n   * the first place). If you are changing the fetch() options\n   * dramatically between runs, there's a good chance that you might\n   * be trying to fit divergent semantics into a single object, and\n   * would be better off with multiple cache instances.\n   *\n   * **1**: Ie, they're not the \"same Promise\", but they resolve at\n   * the same time, because they're both waiting on the same\n   * underlying fetchMethod response.\n   */\n\n  fetch(\n    k: K,\n    fetchOptions: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : LRUCache.FetchOptionsWithContext<K, V, FC>\n  ): Promise<undefined | V>\n\n  // this overload not allowed if context is required\n  fetch(\n    k: unknown extends FC\n      ? K\n      : FC extends undefined | void\n      ? K\n      : never,\n    fetchOptions?: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : never\n  ): Promise<undefined | V>\n\n  async fetch(\n    k: K,\n    fetchOptions: LRUCache.FetchOptions<K, V, FC> = {}\n  ): Promise<undefined | V> {\n    const {\n      // get options\n      allowStale = this.allowStale,\n      updateAgeOnGet = this.updateAgeOnGet,\n      noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n      // set options\n      ttl = this.ttl,\n      noDisposeOnSet = this.noDisposeOnSet,\n      size = 0,\n      sizeCalculation = this.sizeCalculation,\n      noUpdateTTL = this.noUpdateTTL,\n      // fetch exclusive options\n      noDeleteOnFetchRejection = this.noDeleteOnFetchRejection,\n      allowStaleOnFetchRejection = this.allowStaleOnFetchRejection,\n      ignoreFetchAbort = this.ignoreFetchAbort,\n      allowStaleOnFetchAbort = this.allowStaleOnFetchAbort,\n      context,\n      forceRefresh = false,\n      status,\n      signal,\n    } = fetchOptions\n\n    if (!this.#hasFetchMethod) {\n      if (status) status.fetch = 'get'\n      return this.get(k, {\n        allowStale,\n        updateAgeOnGet,\n        noDeleteOnStaleGet,\n        status,\n      })\n    }\n\n    const options = {\n      allowStale,\n      updateAgeOnGet,\n      noDeleteOnStaleGet,\n      ttl,\n      noDisposeOnSet,\n      size,\n      sizeCalculation,\n      noUpdateTTL,\n      noDeleteOnFetchRejection,\n      allowStaleOnFetchRejection,\n      allowStaleOnFetchAbort,\n      ignoreFetchAbort,\n      status,\n      signal,\n    }\n\n    let index = this.#keyMap.get(k)\n    if (index === undefined) {\n      if (status) status.fetch = 'miss'\n      const p = this.#backgroundFetch(k, index, options, context)\n      return (p.__returned = p)\n    } else {\n      // in cache, maybe already fetching\n      const v = this.#valList[index]\n      if (this.#isBackgroundFetch(v)) {\n        const stale =\n          allowStale && v.__staleWhileFetching !== undefined\n        if (status) {\n          status.fetch = 'inflight'\n          if (stale) status.returnedStale = true\n        }\n        return stale ? v.__staleWhileFetching : (v.__returned = v)\n      }\n\n      // if we force a refresh, that means do NOT serve the cached value,\n      // unless we are already in the process of refreshing the cache.\n      const isStale = this.#isStale(index)\n      if (!forceRefresh && !isStale) {\n        if (status) status.fetch = 'hit'\n        this.#moveToTail(index)\n        if (updateAgeOnGet) {\n          this.#updateItemAge(index)\n        }\n        if (status) this.#statusTTL(status, index)\n        return v\n      }\n\n      // ok, it is stale or a forced refresh, and not already fetching.\n      // refresh the cache.\n      const p = this.#backgroundFetch(k, index, options, context)\n      const hasStale = p.__staleWhileFetching !== undefined\n      const staleVal = hasStale && allowStale\n      if (status) {\n        status.fetch = isStale ? 'stale' : 'refresh'\n        if (staleVal && isStale) status.returnedStale = true\n      }\n      return staleVal ? p.__staleWhileFetching : (p.__returned = p)\n    }\n  }\n\n  /**\n   * In some cases, `cache.fetch()` may resolve to `undefined`, either because\n   * a {@link LRUCache.OptionsBase#fetchMethod} was not provided (turning\n   * `cache.fetch(k)` into just an async wrapper around `cache.get(k)`) or\n   * because `ignoreFetchAbort` was specified (either to the constructor or\n   * in the {@link LRUCache.FetchOptions}). Also, the\n   * {@link OptionsBase.fetchMethod} may return `undefined` or `void`, making\n   * the test even more complicated.\n   *\n   * Because inferring the cases where `undefined` might be returned are so\n   * cumbersome, but testing for `undefined` can also be annoying, this method\n   * can be used, which will reject if `this.fetch()` resolves to undefined.\n   */\n  forceFetch(\n    k: K,\n    fetchOptions: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : LRUCache.FetchOptionsWithContext<K, V, FC>\n  ): Promise<V>\n  // this overload not allowed if context is required\n  forceFetch(\n    k: unknown extends FC\n      ? K\n      : FC extends undefined | void\n      ? K\n      : never,\n    fetchOptions?: unknown extends FC\n      ? LRUCache.FetchOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.FetchOptionsNoContext<K, V>\n      : never\n  ): Promise<V>\n  async forceFetch(\n    k: K,\n    fetchOptions: LRUCache.FetchOptions<K, V, FC> = {}\n  ): Promise<V> {\n    const v = await this.fetch(\n      k,\n      fetchOptions as unknown extends FC\n        ? LRUCache.FetchOptions<K, V, FC>\n        : FC extends undefined | void\n        ? LRUCache.FetchOptionsNoContext<K, V>\n        : LRUCache.FetchOptionsWithContext<K, V, FC>\n    )\n    if (v === undefined) throw new Error('fetch() returned undefined')\n    return v\n  }\n\n  /**\n   * If the key is found in the cache, then this is equivalent to\n   * {@link LRUCache#get}. If not, in the cache, then calculate the value using\n   * the {@link LRUCache.OptionsBase.memoMethod}, and add it to the cache.\n   *\n   * If an `FC` type is set to a type other than `unknown`, `void`, or\n   * `undefined` in the LRUCache constructor, then all calls to `cache.memo()`\n   * _must_ provide a `context` option. If set to `undefined` or `void`, then\n   * calls to memo _must not_ provide a `context` option.\n   *\n   * The `context` param allows you to provide arbitrary data that might be\n   * relevant in the course of fetching the data. It is only relevant for the\n   * course of a single `memo()` operation, and discarded afterwards.\n   */\n  memo(\n    k: K,\n    memoOptions: unknown extends FC\n      ? LRUCache.MemoOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.MemoOptionsNoContext<K, V>\n      : LRUCache.MemoOptionsWithContext<K, V, FC>\n  ): V\n  // this overload not allowed if context is required\n  memo(\n    k: unknown extends FC\n      ? K\n      : FC extends undefined | void\n      ? K\n      : never,\n    memoOptions?: unknown extends FC\n      ? LRUCache.MemoOptions<K, V, FC>\n      : FC extends undefined | void\n      ? LRUCache.MemoOptionsNoContext<K, V>\n      : never\n  ): V\n  memo(k: K, memoOptions: LRUCache.MemoOptions<K, V, FC> = {}) {\n    const memoMethod = this.#memoMethod\n    if (!memoMethod) {\n      throw new Error('no memoMethod provided to constructor')\n    }\n    const { context, forceRefresh, ...options } = memoOptions\n    const v = this.get(k, options)\n    if (!forceRefresh && v !== undefined) return v\n    const vv = memoMethod(k, v, {\n      options,\n      context,\n    } as LRUCache.MemoizerOptions<K, V, FC>)\n    this.set(k, vv, options)\n    return vv\n  }\n\n  /**\n   * Return a value from the cache. Will update the recency of the cache\n   * entry found.\n   *\n   * If the key is not found, get() will return `undefined`.\n   */\n  get(k: K, getOptions: LRUCache.GetOptions<K, V, FC> = {}) {\n    const {\n      allowStale = this.allowStale,\n      updateAgeOnGet = this.updateAgeOnGet,\n      noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n      status,\n    } = getOptions\n    const index = this.#keyMap.get(k)\n    if (index !== undefined) {\n      const value = this.#valList[index]\n      const fetching = this.#isBackgroundFetch(value)\n      if (status) this.#statusTTL(status, index)\n      if (this.#isStale(index)) {\n        if (status) status.get = 'stale'\n        // delete only if not an in-flight background fetch\n        if (!fetching) {\n          if (!noDeleteOnStaleGet) {\n            this.#delete(k, 'expire')\n          }\n          if (status && allowStale) status.returnedStale = true\n          return allowStale ? value : undefined\n        } else {\n          if (\n            status &&\n            allowStale &&\n            value.__staleWhileFetching !== undefined\n          ) {\n            status.returnedStale = true\n          }\n          return allowStale ? value.__staleWhileFetching : undefined\n        }\n      } else {\n        if (status) status.get = 'hit'\n        // if we're currently fetching it, we don't actually have it yet\n        // it's not stale, which means this isn't a staleWhileRefetching.\n        // If it's not stale, and fetching, AND has a __staleWhileFetching\n        // value, then that means the user fetched with {forceRefresh:true},\n        // so it's safe to return that value.\n        if (fetching) {\n          return value.__staleWhileFetching\n        }\n        this.#moveToTail(index)\n        if (updateAgeOnGet) {\n          this.#updateItemAge(index)\n        }\n        return value\n      }\n    } else if (status) {\n      status.get = 'miss'\n    }\n  }\n\n  #connect(p: Index, n: Index) {\n    this.#prev[n] = p\n    this.#next[p] = n\n  }\n\n  #moveToTail(index: Index): void {\n    // if tail already, nothing to do\n    // if head, move head to next[index]\n    // else\n    //   move next[prev[index]] to next[index] (head has no prev)\n    //   move prev[next[index]] to prev[index]\n    // prev[index] = tail\n    // next[tail] = index\n    // tail = index\n    if (index !== this.#tail) {\n      if (index === this.#head) {\n        this.#head = this.#next[index] as Index\n      } else {\n        this.#connect(\n          this.#prev[index] as Index,\n          this.#next[index] as Index\n        )\n      }\n      this.#connect(this.#tail, index)\n      this.#tail = index\n    }\n  }\n\n  /**\n   * Deletes a key out of the cache.\n   *\n   * Returns true if the key was deleted, false otherwise.\n   */\n  delete(k: K) {\n    return this.#delete(k, 'delete')\n  }\n\n  #delete(k: K, reason: LRUCache.DisposeReason) {\n    let deleted = false\n    if (this.#size !== 0) {\n      const index = this.#keyMap.get(k)\n      if (index !== undefined) {\n        deleted = true\n        if (this.#size === 1) {\n          this.#clear(reason)\n        } else {\n          this.#removeItemSize(index)\n          const v = this.#valList[index]\n          if (this.#isBackgroundFetch(v)) {\n            v.__abortController.abort(new Error('deleted'))\n          } else if (this.#hasDispose || this.#hasDisposeAfter) {\n            if (this.#hasDispose) {\n              this.#dispose?.(v as V, k, reason)\n            }\n            if (this.#hasDisposeAfter) {\n              this.#disposed?.push([v as V, k, reason])\n            }\n          }\n          this.#keyMap.delete(k)\n          this.#keyList[index] = undefined\n          this.#valList[index] = undefined\n          if (index === this.#tail) {\n            this.#tail = this.#prev[index] as Index\n          } else if (index === this.#head) {\n            this.#head = this.#next[index] as Index\n          } else {\n            const pi = this.#prev[index] as number\n            this.#next[pi] = this.#next[index] as number\n            const ni = this.#next[index] as number\n            this.#prev[ni] = this.#prev[index] as number\n          }\n          this.#size--\n          this.#free.push(index)\n        }\n      }\n    }\n    if (this.#hasDisposeAfter && this.#disposed?.length) {\n      const dt = this.#disposed\n      let task: DisposeTask<K, V> | undefined\n      while ((task = dt?.shift())) {\n        this.#disposeAfter?.(...task)\n      }\n    }\n    return deleted\n  }\n\n  /**\n   * Clear the cache entirely, throwing away all values.\n   */\n  clear() {\n    return this.#clear('delete')\n  }\n  #clear(reason: LRUCache.DisposeReason) {\n    for (const index of this.#rindexes({ allowStale: true })) {\n      const v = this.#valList[index]\n      if (this.#isBackgroundFetch(v)) {\n        v.__abortController.abort(new Error('deleted'))\n      } else {\n        const k = this.#keyList[index]\n        if (this.#hasDispose) {\n          this.#dispose?.(v as V, k as K, reason)\n        }\n        if (this.#hasDisposeAfter) {\n          this.#disposed?.push([v as V, k as K, reason])\n        }\n      }\n    }\n\n    this.#keyMap.clear()\n    this.#valList.fill(undefined)\n    this.#keyList.fill(undefined)\n    if (this.#ttls && this.#starts) {\n      this.#ttls.fill(0)\n      this.#starts.fill(0)\n    }\n    if (this.#sizes) {\n      this.#sizes.fill(0)\n    }\n    this.#head = 0 as Index\n    this.#tail = 0 as Index\n    this.#free.length = 0\n    this.#calculatedSize = 0\n    this.#size = 0\n    if (this.#hasDisposeAfter && this.#disposed) {\n      const dt = this.#disposed\n      let task: DisposeTask<K, V> | undefined\n      while ((task = dt?.shift())) {\n        this.#disposeAfter?.(...task)\n      }\n    }\n  }\n}\n"],
  "mappings": "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",
  "names": ["perf", "warned", "PROCESS", "emitWarning", "msg", "type", "code", "fn", "AC", "AS", "_", "warnACPolyfill", "reason", "printACPolyfillWarning", "shouldWarn", "TYPE", "isPosInt", "n", "getUintArray", "max", "ZeroArray", "size", "_constructing", "_Stack", "HeapCls", "__privateSet", "s", "__privateGet", "Stack", "__privateAdd", "LRUCache", "#max", "#maxSize", "#dispose", "#disposeAfter", "#fetchMethod", "#memoMethod", "#size", "#calculatedSize", "#keyMap", "#keyList", "#valList", "#next", "#prev", "#head", "#tail", "#free", "#disposed", "#sizes", "#starts", "#ttls", "#hasDispose", "#hasFetchMethod", "#hasDisposeAfter", "c", "p", "#isBackgroundFetch", "k", "index", "options", "context", "#backgroundFetch", "#moveToTail", "#indexes", "#rindexes", "#isStale", "ttl", "ttlResolution", "ttlAutopurge", "updateAgeOnGet", "updateAgeOnHas", "allowStale", "dispose", "disposeAfter", "noDisposeOnSet", "noUpdateTTL", "maxSize", "maxEntrySize", "sizeCalculation", "fetchMethod", "memoMethod", "noDeleteOnFetchRejection", "noDeleteOnStaleGet", "allowStaleOnFetchRejection", "allowStaleOnFetchAbort", "ignoreFetchAbort", "UintArray", "#initializeSizeTracking", "#initializeTTLTracking", "key", "ttls", "starts", "#setItemTTL", "start", "t", "#delete", "#updateItemAge", "#statusTTL", "status", "cachedNow", "getNow", "age", "sizes", "#removeItemSize", "#requireSize", "v", "#addItemSize", "#evict", "_i", "_s", "_st", "_k", "_v", "i", "#isValidIndex", "getOptions", "value", "thisp", "deleted", "entry", "remain", "arr", "setOptions", "oldVal", "oldValue", "dt", "task", "val", "free", "head", "hasOptions", "peekOptions", "ac", "signal", "fetchOpts", "cb", "updateCache", "aborted", "ignoreAbort", "fetchFail", "bf", "eb", "er", "allowStaleAborted", "noDelete", "pcall", "res", "rej", "fmp", "b", "fetchOptions", "forceRefresh", "stale", "isStale", "staleVal", "memoOptions", "vv", "fetching", "#connect", "#clear", "pi", "ni"]
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                     Path(this.url, EscapePath(blobName)), this.pipeline);\n  }\n\n  /**\n   * Creates a {@link BlockBlobClient}\n   *\n   * @param blobName - A block blob name\n   *\n   *\n   * Example usage:\n   *\n   * ```js\n   * const content = \"Hello world!\";\n   *\n   * const blockBlobClient = containerClient.getBlockBlobClient(\"<blob name>\");\n   * const uploadBlobResponse = await blockBlobClient.upload(content, content.length);\n   * ```\n   */\n  public getBlockBlobClient(blobName: string): BlockBlobClient {\n    return new BlockBlobClient(appendToURLPath(this.url, EscapePath(blobName)), this.pipeline);\n  }\n\n  /**\n   * Creates a {@link PageBlobClient}\n   *\n   * @param blobName - A page blob name\n   */\n  public getPageBlobClient(blobName: string): PageBlobClient {\n    return new PageBlobClient(appendToURLPath(this.url, EscapePath(blobName)), this.pipeline);\n  }\n\n  /**\n   * Returns all user-defined metadata and system properties for the specified\n   * container. The data returned does not include the container's list of blobs.\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/get-container-properties\n   *\n   * WARNING: The `metadata` object returned in the response will have its keys in lowercase, even if\n   * they originally contained uppercase characters. This differs from the metadata keys returned by\n   * the `listContainers` method of {@link BlobServiceClient} using the `includeMetadata` option, which\n   * will retain their original casing.\n   *\n   * @param options - Options to Container Get Properties operation.\n   */\n  public async getProperties(\n    options: ContainerGetPropertiesOptions = {},\n  ): Promise<ContainerGetPropertiesResponse> {\n    if (!options.conditions) {\n      options.conditions = {};\n    }\n\n    return tracingClient.withSpan(\n      \"ContainerClient-getProperties\",\n      options,\n      async (updatedOptions) => {\n        return assertResponse<ContainerGetPropertiesHeaders, ContainerGetPropertiesHeaders>(\n          await this.containerContext.getProperties({\n            abortSignal: options.abortSignal,\n            ...options.conditions,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n      },\n    );\n  }\n\n  /**\n   * Marks the specified container for deletion. The container and any blobs\n   * contained within it are later deleted during garbage collection.\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-container\n   *\n   * @param options - Options to Container Delete operation.\n   */\n  public async delete(\n    options: ContainerDeleteMethodOptions = {},\n  ): Promise<ContainerDeleteResponse> {\n    if (!options.conditions) {\n      options.conditions = {};\n    }\n\n    return tracingClient.withSpan(\"ContainerClient-delete\", options, async (updatedOptions) => {\n      return assertResponse<ContainerDeleteHeaders, ContainerDeleteHeaders>(\n        await this.containerContext.delete({\n          abortSignal: options.abortSignal,\n          leaseAccessConditions: options.conditions,\n          modifiedAccessConditions: options.conditions,\n          tracingOptions: updatedOptions.tracingOptions,\n        }),\n      );\n    });\n  }\n\n  /**\n   * Marks the specified container for deletion if it exists. The container and any blobs\n   * contained within it are later deleted during garbage collection.\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-container\n   *\n   * @param options - Options to Container Delete operation.\n   */\n  public async deleteIfExists(\n    options: ContainerDeleteMethodOptions = {},\n  ): Promise<ContainerDeleteIfExistsResponse> {\n    return tracingClient.withSpan(\n      \"ContainerClient-deleteIfExists\",\n      options,\n      async (updatedOptions) => {\n        try {\n          const res = await this.delete(updatedOptions);\n          return {\n            succeeded: true,\n            ...res,\n            _response: res._response,\n          };\n        } catch (e: any) {\n          if (e.details?.errorCode === \"ContainerNotFound\") {\n            return {\n              succeeded: false,\n              ...e.response?.parsedHeaders,\n              _response: e.response,\n            };\n          }\n          throw e;\n        }\n      },\n    );\n  }\n\n  /**\n   * Sets one or more user-defined name-value pairs for the specified container.\n   *\n   * If no option provided, or no metadata defined in the parameter, the container\n   * metadata will be removed.\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/set-container-metadata\n   *\n   * @param metadata - Replace existing metadata with this value.\n   *                            If no value provided the existing metadata will be removed.\n   * @param options - Options to Container Set Metadata operation.\n   */\n  public async setMetadata(\n    metadata?: Metadata,\n    options: ContainerSetMetadataOptions = {},\n  ): Promise<ContainerSetMetadataResponse> {\n    if (!options.conditions) {\n      options.conditions = {};\n    }\n\n    if (options.conditions.ifUnmodifiedSince) {\n      throw new RangeError(\n        \"the IfUnmodifiedSince must have their default values because they are ignored by the blob service\",\n      );\n    }\n\n    return tracingClient.withSpan(\n      \"ContainerClient-setMetadata\",\n      options,\n      async (updatedOptions) => {\n        return assertResponse<ContainerSetMetadataHeaders, ContainerSetMetadataHeaders>(\n          await this.containerContext.setMetadata({\n            abortSignal: options.abortSignal,\n            leaseAccessConditions: options.conditions,\n            metadata,\n            modifiedAccessConditions: options.conditions,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n      },\n    );\n  }\n\n  /**\n   * Gets the permissions for the specified container. The permissions indicate\n   * whether container data may be accessed publicly.\n   *\n   * WARNING: JavaScript Date will potentially lose precision when parsing startsOn and expiresOn strings.\n   * For example, new Date(\"2018-12-31T03:44:23.8827891Z\").toISOString() will get \"2018-12-31T03:44:23.882Z\".\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/get-container-acl\n   *\n   * @param options - Options to Container Get Access Policy operation.\n   */\n  public async getAccessPolicy(\n    options: ContainerGetAccessPolicyOptions = {},\n  ): Promise<ContainerGetAccessPolicyResponse> {\n    if (!options.conditions) {\n      options.conditions = {};\n    }\n\n    return tracingClient.withSpan(\n      \"ContainerClient-getAccessPolicy\",\n      options,\n      async (updatedOptions) => {\n        const response = assertResponse<\n          ContainerGetAccessPolicyResponseModel,\n          ContainerGetAccessPolicyHeaders,\n          SignedIdentifierModel\n        >(\n          await this.containerContext.getAccessPolicy({\n            abortSignal: options.abortSignal,\n            leaseAccessConditions: options.conditions,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n\n        const res: ContainerGetAccessPolicyResponse = {\n          _response: response._response,\n          blobPublicAccess: response.blobPublicAccess,\n          date: response.date,\n          etag: response.etag,\n          errorCode: response.errorCode,\n          lastModified: response.lastModified,\n          requestId: response.requestId,\n          clientRequestId: response.clientRequestId,\n          signedIdentifiers: [],\n          version: response.version,\n        };\n\n        for (const identifier of response) {\n          let accessPolicy: any = undefined;\n          if (identifier.accessPolicy) {\n            accessPolicy = {\n              permissions: identifier.accessPolicy.permissions,\n            };\n\n            if (identifier.accessPolicy.expiresOn) {\n              accessPolicy.expiresOn = new Date(identifier.accessPolicy.expiresOn);\n            }\n\n            if (identifier.accessPolicy.startsOn) {\n              accessPolicy.startsOn = new Date(identifier.accessPolicy.startsOn);\n            }\n          }\n\n          res.signedIdentifiers.push({\n            accessPolicy,\n            id: identifier.id,\n          });\n        }\n\n        return res;\n      },\n    );\n  }\n\n  /**\n   * Sets the permissions for the specified container. The permissions indicate\n   * whether blobs in a container may be accessed publicly.\n   *\n   * When you set permissions for a container, the existing permissions are replaced.\n   * If no access or containerAcl provided, the existing container ACL will be\n   * removed.\n   *\n   * When you establish a stored access policy on a container, it may take up to 30 seconds to take effect.\n   * During this interval, a shared access signature that is associated with the stored access policy will\n   * fail with status code 403 (Forbidden), until the access policy becomes active.\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/set-container-acl\n   *\n   * @param access - The level of public access to data in the container.\n   * @param containerAcl - Array of elements each having a unique Id and details of the access policy.\n   * @param options - Options to Container Set Access Policy operation.\n   */\n  public async setAccessPolicy(\n    access?: PublicAccessType,\n    containerAcl?: SignedIdentifier[],\n    options: ContainerSetAccessPolicyOptions = {},\n  ): Promise<ContainerSetAccessPolicyResponse> {\n    options.conditions = options.conditions || {};\n    return tracingClient.withSpan(\n      \"ContainerClient-setAccessPolicy\",\n      options,\n      async (updatedOptions) => {\n        const acl: SignedIdentifierModel[] = [];\n        for (const identifier of containerAcl || []) {\n          acl.push({\n            accessPolicy: {\n              expiresOn: identifier.accessPolicy.expiresOn\n                ? truncatedISO8061Date(identifier.accessPolicy.expiresOn)\n                : \"\",\n              permissions: identifier.accessPolicy.permissions,\n              startsOn: identifier.accessPolicy.startsOn\n                ? truncatedISO8061Date(identifier.accessPolicy.startsOn)\n                : \"\",\n            },\n            id: identifier.id,\n          });\n        }\n\n        return assertResponse<ContainerSetAccessPolicyHeaders, ContainerSetAccessPolicyHeaders>(\n          await this.containerContext.setAccessPolicy({\n            abortSignal: options.abortSignal,\n            access,\n            containerAcl: acl,\n            leaseAccessConditions: options.conditions,\n            modifiedAccessConditions: options.conditions,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n      },\n    );\n  }\n\n  /**\n   * Get a {@link BlobLeaseClient} that manages leases on the container.\n   *\n   * @param proposeLeaseId - Initial proposed lease Id.\n   * @returns A new BlobLeaseClient object for managing leases on the container.\n   */\n  public getBlobLeaseClient(proposeLeaseId?: string): BlobLeaseClient {\n    return new BlobLeaseClient(this, proposeLeaseId);\n  }\n\n  /**\n   * Creates a new block blob, or updates the content of an existing block blob.\n   *\n   * Updating an existing block blob overwrites any existing metadata on the blob.\n   * Partial updates are not supported; the content of the existing blob is\n   * overwritten with the new content. To perform a partial update of a block blob's,\n   * use {@link BlockBlobClient.stageBlock} and {@link BlockBlobClient.commitBlockList}.\n   *\n   * This is a non-parallel uploading method, please use {@link BlockBlobClient.uploadFile},\n   * {@link BlockBlobClient.uploadStream} or {@link BlockBlobClient.uploadBrowserData} for better\n   * performance with concurrency uploading.\n   *\n   * @see https://learn.microsoft.com/rest/api/storageservices/put-blob\n   *\n   * @param blobName - Name of the block blob to create or update.\n   * @param body - Blob, string, ArrayBuffer, ArrayBufferView or a function\n   *                               which returns a new Readable stream whose offset is from data source beginning.\n   * @param contentLength - Length of body in bytes. Use Buffer.byteLength() to calculate body length for a\n   *                               string including non non-Base64/Hex-encoded characters.\n   * @param options - Options to configure the Block Blob Upload operation.\n   * @returns Block Blob upload response data and the corresponding BlockBlobClient instance.\n   */\n  public async uploadBlockBlob(\n    blobName: string,\n    body: HttpRequestBody,\n    contentLength: number,\n    options: BlockBlobUploadOptions = {},\n  ): Promise<{ blockBlobClient: BlockBlobClient; response: BlockBlobUploadResponse }> {\n    return tracingClient.withSpan(\n      \"ContainerClient-uploadBlockBlob\",\n      options,\n      async (updatedOptions) => {\n        const blockBlobClient = this.getBlockBlobClient(blobName);\n        const response = await blockBlobClient.upload(body, contentLength, updatedOptions);\n        return {\n          blockBlobClient,\n          response,\n        };\n      },\n    );\n  }\n\n  /**\n   * Marks the specified blob or snapshot for deletion. The blob is later deleted\n   * during garbage collection. Note that in order to delete a blob, you must delete\n   * all of its snapshots. You can delete both at the same time with the Delete\n   * Blob operation.\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-blob\n   *\n   * @param blobName -\n   * @param options - Options to Blob Delete operation.\n   * @returns Block blob deletion response data.\n   */\n  public async deleteBlob(\n    blobName: string,\n    options: ContainerDeleteBlobOptions = {},\n  ): Promise<BlobDeleteResponse> {\n    return tracingClient.withSpan(\"ContainerClient-deleteBlob\", options, async (updatedOptions) => {\n      let blobClient = this.getBlobClient(blobName);\n      if (options.versionId) {\n        blobClient = blobClient.withVersion(options.versionId);\n      }\n      return blobClient.delete(updatedOptions);\n    });\n  }\n\n  /**\n   * listBlobFlatSegment returns a single segment of blobs starting from the\n   * specified Marker. Use an empty Marker to start enumeration from the beginning.\n   * After getting a segment, process it, and then call listBlobsFlatSegment again\n   * (passing the the previously-returned Marker) to get the next segment.\n   * @see https://learn.microsoft.com/rest/api/storageservices/list-blobs\n   *\n   * @param marker - A string value that identifies the portion of the list to be returned with the next list operation.\n   * @param options - Options to Container List Blob Flat Segment operation.\n   */\n  private async listBlobFlatSegment(\n    marker?: string,\n    options: ContainerListBlobsSegmentOptions = {},\n  ): Promise<ContainerListBlobFlatSegmentResponse> {\n    return tracingClient.withSpan(\n      \"ContainerClient-listBlobFlatSegment\",\n      options,\n      async (updatedOptions) => {\n        const response = assertResponse<\n          ListBlobsFlatSegmentResponseInternal,\n          ContainerListBlobFlatSegmentHeaders,\n          ListBlobsFlatSegmentResponseInternal\n        >(\n          await this.containerContext.listBlobFlatSegment({\n            marker,\n            ...options,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n\n        const wrappedResponse: ContainerListBlobFlatSegmentResponse = {\n          ...response,\n          _response: {\n            ...response._response,\n            parsedBody: ConvertInternalResponseOfListBlobFlat(response._response.parsedBody),\n          }, // _response is made non-enumerable\n          segment: {\n            ...response.segment,\n            blobItems: response.segment.blobItems.map((blobItemInternal) => {\n              const blobItem: BlobItem = {\n                ...blobItemInternal,\n                name: BlobNameToString(blobItemInternal.name),\n                tags: toTags(blobItemInternal.blobTags),\n                objectReplicationSourceProperties: parseObjectReplicationRecord(\n                  blobItemInternal.objectReplicationMetadata,\n                ),\n              };\n              return blobItem;\n            }),\n          },\n        };\n        return wrappedResponse;\n      },\n    );\n  }\n\n  /**\n   * listBlobHierarchySegment returns a single segment of blobs starting from\n   * the specified Marker. Use an empty Marker to start enumeration from the\n   * beginning. After getting a segment, process it, and then call listBlobsHierarchicalSegment\n   * again (passing the the previously-returned Marker) to get the next segment.\n   * @see https://learn.microsoft.com/rest/api/storageservices/list-blobs\n   *\n   * @param delimiter - The character or string used to define the virtual hierarchy\n   * @param marker - A string value that identifies the portion of the list to be returned with the next list operation.\n   * @param options - Options to Container List Blob Hierarchy Segment operation.\n   */\n  private async listBlobHierarchySegment(\n    delimiter: string,\n    marker?: string,\n    options: ContainerListBlobsSegmentOptions = {},\n  ): Promise<ContainerListBlobHierarchySegmentResponse> {\n    return tracingClient.withSpan(\n      \"ContainerClient-listBlobHierarchySegment\",\n      options,\n      async (updatedOptions) => {\n        const response = assertResponse<\n          ContainerListBlobHierarchySegmentResponseModel,\n          ContainerListBlobHierarchySegmentHeaders,\n          ListBlobsHierarchySegmentResponseInternal\n        >(\n          await this.containerContext.listBlobHierarchySegment(delimiter, {\n            marker,\n            ...options,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n\n        const wrappedResponse: ContainerListBlobHierarchySegmentResponse = {\n          ...response,\n          _response: {\n            ...response._response,\n            parsedBody: ConvertInternalResponseOfListBlobHierarchy(response._response.parsedBody),\n          }, // _response is made non-enumerable\n          segment: {\n            ...response.segment,\n            blobItems: response.segment.blobItems.map((blobItemInternal) => {\n              const blobItem: BlobItem = {\n                ...blobItemInternal,\n                name: BlobNameToString(blobItemInternal.name),\n                tags: toTags(blobItemInternal.blobTags),\n                objectReplicationSourceProperties: parseObjectReplicationRecord(\n                  blobItemInternal.objectReplicationMetadata,\n                ),\n              };\n              return blobItem;\n            }),\n            blobPrefixes: response.segment.blobPrefixes?.map((blobPrefixInternal) => {\n              const blobPrefix: BlobPrefix = {\n                ...blobPrefixInternal,\n                name: BlobNameToString(blobPrefixInternal.name),\n              };\n              return blobPrefix;\n            }),\n          },\n        };\n        return wrappedResponse;\n      },\n    );\n  }\n\n  /**\n   * Returns an AsyncIterableIterator for ContainerListBlobFlatSegmentResponse\n   *\n   * @param marker - A string value that identifies the portion of\n   *                          the list of blobs to be returned with the next listing operation. The\n   *                          operation returns the ContinuationToken value within the response body if the\n   *                          listing operation did not return all blobs remaining to be listed\n   *                          with the current page. The ContinuationToken value can be used as the value for\n   *                          the marker parameter in a subsequent call to request the next page of list\n   *                          items. The marker value is opaque to the client.\n   * @param options - Options to list blobs operation.\n   */\n  private async *listSegments(\n    marker?: string,\n    options: ContainerListBlobsSegmentOptions = {},\n  ): AsyncIterableIterator<ContainerListBlobFlatSegmentResponse> {\n    let listBlobsFlatSegmentResponse;\n    if (!!marker || marker === undefined) {\n      do {\n        listBlobsFlatSegmentResponse = await this.listBlobFlatSegment(marker, options);\n        marker = listBlobsFlatSegmentResponse.continuationToken;\n        yield await listBlobsFlatSegmentResponse;\n      } while (marker);\n    }\n  }\n\n  /**\n   * Returns an AsyncIterableIterator of {@link BlobItem} objects\n   *\n   * @param options - Options to list blobs operation.\n   */\n  private async *listItems(\n    options: ContainerListBlobsSegmentOptions = {},\n  ): AsyncIterableIterator<BlobItem> {\n    let marker: string | undefined;\n    for await (const listBlobsFlatSegmentResponse of this.listSegments(marker, options)) {\n      yield* listBlobsFlatSegmentResponse.segment.blobItems;\n    }\n  }\n\n  /**\n   * Returns an async iterable iterator to list all the blobs\n   * under the specified account.\n   *\n   * .byPage() returns an async iterable iterator to list the blobs in pages.\n   *\n   * Example using `for await` syntax:\n   *\n   * ```js\n   * // Get the containerClient before you run these snippets,\n   * // Can be obtained from `blobServiceClient.getContainerClient(\"<your-container-name>\");`\n   * let i = 1;\n   * for await (const blob of containerClient.listBlobsFlat()) {\n   *   console.log(`Blob ${i++}: ${blob.name}`);\n   * }\n   * ```\n   *\n   * Example using `iter.next()`:\n   *\n   * ```js\n   * let i = 1;\n   * let iter = containerClient.listBlobsFlat();\n   * let blobItem = await iter.next();\n   * while (!blobItem.done) {\n   *   console.log(`Blob ${i++}: ${blobItem.value.name}`);\n   *   blobItem = await iter.next();\n   * }\n   * ```\n   *\n   * Example using `byPage()`:\n   *\n   * ```js\n   * // passing optional maxPageSize in the page settings\n   * let i = 1;\n   * for await (const response of containerClient.listBlobsFlat().byPage({ maxPageSize: 20 })) {\n   *   for (const blob of response.segment.blobItems) {\n   *     console.log(`Blob ${i++}: ${blob.name}`);\n   *   }\n   * }\n   * ```\n   *\n   * Example using paging with a marker:\n   *\n   * ```js\n   * let i = 1;\n   * let iterator = containerClient.listBlobsFlat().byPage({ maxPageSize: 2 });\n   * let response = (await iterator.next()).value;\n   *\n   * // Prints 2 blob names\n   * for (const blob of response.segment.blobItems) {\n   *   console.log(`Blob ${i++}: ${blob.name}`);\n   * }\n   *\n   * // Gets next marker\n   * let marker = response.continuationToken;\n   *\n   * // Passing next marker as continuationToken\n   *\n   * iterator = containerClient.listBlobsFlat().byPage({ continuationToken: marker, maxPageSize: 10 });\n   * response = (await iterator.next()).value;\n   *\n   * // Prints 10 blob names\n   * for (const blob of response.segment.blobItems) {\n   *   console.log(`Blob ${i++}: ${blob.name}`);\n   * }\n   * ```\n   *\n   * @param options - Options to list blobs.\n   * @returns An asyncIterableIterator that supports paging.\n   */\n  public listBlobsFlat(\n    options: ContainerListBlobsOptions = {},\n  ): PagedAsyncIterableIterator<BlobItem, ContainerListBlobFlatSegmentResponse> {\n    const include: ListBlobsIncludeItem[] = [];\n    if (options.includeCopy) {\n      include.push(\"copy\");\n    }\n    if (options.includeDeleted) {\n      include.push(\"deleted\");\n    }\n    if (options.includeMetadata) {\n      include.push(\"metadata\");\n    }\n    if (options.includeSnapshots) {\n      include.push(\"snapshots\");\n    }\n    if (options.includeVersions) {\n      include.push(\"versions\");\n    }\n    if (options.includeUncommitedBlobs) {\n      include.push(\"uncommittedblobs\");\n    }\n    if (options.includeTags) {\n      include.push(\"tags\");\n    }\n    if (options.includeDeletedWithVersions) {\n      include.push(\"deletedwithversions\");\n    }\n    if (options.includeImmutabilityPolicy) {\n      include.push(\"immutabilitypolicy\");\n    }\n    if (options.includeLegalHold) {\n      include.push(\"legalhold\");\n    }\n    if (options.prefix === \"\") {\n      options.prefix = undefined;\n    }\n\n    const updatedOptions: ContainerListBlobsSegmentOptions = {\n      ...options,\n      ...(include.length > 0 ? { include: include } : {}),\n    };\n\n    // AsyncIterableIterator to iterate over blobs\n    const iter = this.listItems(updatedOptions);\n    return {\n      /**\n       * The next method, part of the iteration protocol\n       */\n      next() {\n        return iter.next();\n      },\n      /**\n       * The connection to the async iterator, part of the iteration protocol\n       */\n      [Symbol.asyncIterator]() {\n        return this;\n      },\n      /**\n       * Return an AsyncIterableIterator that works a page at a time\n       */\n      byPage: (settings: PageSettings = {}) => {\n        return this.listSegments(settings.continuationToken, {\n          maxPageSize: settings.maxPageSize,\n          ...updatedOptions,\n        });\n      },\n    };\n  }\n\n  /**\n   * Returns an AsyncIterableIterator for ContainerListBlobHierarchySegmentResponse\n   *\n   * @param delimiter - The character or string used to define the virtual hierarchy\n   * @param marker - A string value that identifies the portion of\n   *                          the list of blobs to be returned with the next listing operation. The\n   *                          operation returns the ContinuationToken value within the response body if the\n   *                          listing operation did not return all blobs remaining to be listed\n   *                          with the current page. The ContinuationToken value can be used as the value for\n   *                          the marker parameter in a subsequent call to request the next page of list\n   *                          items. The marker value is opaque to the client.\n   * @param options - Options to list blobs operation.\n   */\n  private async *listHierarchySegments(\n    delimiter: string,\n    marker?: string,\n    options: ContainerListBlobsSegmentOptions = {},\n  ): AsyncIterableIterator<ContainerListBlobHierarchySegmentResponse> {\n    let listBlobsHierarchySegmentResponse;\n    if (!!marker || marker === undefined) {\n      do {\n        listBlobsHierarchySegmentResponse = await this.listBlobHierarchySegment(\n          delimiter,\n          marker,\n          options,\n        );\n        marker = listBlobsHierarchySegmentResponse.continuationToken;\n        yield await listBlobsHierarchySegmentResponse;\n      } while (marker);\n    }\n  }\n\n  /**\n   * Returns an AsyncIterableIterator for {@link BlobPrefix} and {@link BlobItem} objects.\n   *\n   * @param delimiter - The character or string used to define the virtual hierarchy\n   * @param options - Options to list blobs operation.\n   */\n  private async *listItemsByHierarchy(\n    delimiter: string,\n    options: ContainerListBlobsSegmentOptions = {},\n  ): AsyncIterableIterator<({ kind: \"prefix\" } & BlobPrefix) | ({ kind: \"blob\" } & BlobItem)> {\n    let marker: string | undefined;\n    for await (const listBlobsHierarchySegmentResponse of this.listHierarchySegments(\n      delimiter,\n      marker,\n      options,\n    )) {\n      const segment = listBlobsHierarchySegmentResponse.segment;\n      if (segment.blobPrefixes) {\n        for (const prefix of segment.blobPrefixes) {\n          yield {\n            kind: \"prefix\",\n            ...prefix,\n          };\n        }\n      }\n      for (const blob of segment.blobItems) {\n        yield { kind: \"blob\", ...blob };\n      }\n    }\n  }\n\n  /**\n   * Returns an async iterable iterator to list all the blobs by hierarchy.\n   * under the specified account.\n   *\n   * .byPage() returns an async iterable iterator to list the blobs by hierarchy in pages.\n   *\n   * Example using `for await` syntax:\n   *\n   * ```js\n   * for await (const item of containerClient.listBlobsByHierarchy(\"/\")) {\n   *   if (item.kind === \"prefix\") {\n   *     console.log(`\\tBlobPrefix: ${item.name}`);\n   *   } else {\n   *     console.log(`\\tBlobItem: name - ${item.name}`);\n   *   }\n   * }\n   * ```\n   *\n   * Example using `iter.next()`:\n   *\n   * ```js\n   * let iter = containerClient.listBlobsByHierarchy(\"/\", { prefix: \"prefix1/\" });\n   * let entity = await iter.next();\n   * while (!entity.done) {\n   *   let item = entity.value;\n   *   if (item.kind === \"prefix\") {\n   *     console.log(`\\tBlobPrefix: ${item.name}`);\n   *   } else {\n   *     console.log(`\\tBlobItem: name - ${item.name}`);\n   *   }\n   *   entity = await iter.next();\n   * }\n   * ```\n   *\n   * Example using `byPage()`:\n   *\n   * ```js\n   * console.log(\"Listing blobs by hierarchy by page\");\n   * for await (const response of containerClient.listBlobsByHierarchy(\"/\").byPage()) {\n   *   const segment = response.segment;\n   *   if (segment.blobPrefixes) {\n   *     for (const prefix of segment.blobPrefixes) {\n   *       console.log(`\\tBlobPrefix: ${prefix.name}`);\n   *     }\n   *   }\n   *   for (const blob of response.segment.blobItems) {\n   *     console.log(`\\tBlobItem: name - ${blob.name}`);\n   *   }\n   * }\n   * ```\n   *\n   * Example using paging with a max page size:\n   *\n   * ```js\n   * console.log(\"Listing blobs by hierarchy by page, specifying a prefix and a max page size\");\n   *\n   * let i = 1;\n   * for await (const response of containerClient\n   *   .listBlobsByHierarchy(\"/\", { prefix: \"prefix2/sub1/\" })\n   *   .byPage({ maxPageSize: 2 })) {\n   *   console.log(`Page ${i++}`);\n   *   const segment = response.segment;\n   *\n   *   if (segment.blobPrefixes) {\n   *     for (const prefix of segment.blobPrefixes) {\n   *       console.log(`\\tBlobPrefix: ${prefix.name}`);\n   *     }\n   *   }\n   *\n   *   for (const blob of response.segment.blobItems) {\n   *     console.log(`\\tBlobItem: name - ${blob.name}`);\n   *   }\n   * }\n   * ```\n   *\n   * @param delimiter - The character or string used to define the virtual hierarchy\n   * @param options - Options to list blobs operation.\n   */\n  public listBlobsByHierarchy(\n    delimiter: string,\n    options: ContainerListBlobsOptions = {},\n  ): PagedAsyncIterableIterator<\n    ({ kind: \"prefix\" } & BlobPrefix) | ({ kind: \"blob\" } & BlobItem),\n    ContainerListBlobHierarchySegmentResponse\n  > {\n    if (delimiter === \"\") {\n      throw new RangeError(\"delimiter should contain one or more characters\");\n    }\n\n    const include: ListBlobsIncludeItem[] = [];\n    if (options.includeCopy) {\n      include.push(\"copy\");\n    }\n    if (options.includeDeleted) {\n      include.push(\"deleted\");\n    }\n    if (options.includeMetadata) {\n      include.push(\"metadata\");\n    }\n    if (options.includeSnapshots) {\n      include.push(\"snapshots\");\n    }\n    if (options.includeVersions) {\n      include.push(\"versions\");\n    }\n    if (options.includeUncommitedBlobs) {\n      include.push(\"uncommittedblobs\");\n    }\n    if (options.includeTags) {\n      include.push(\"tags\");\n    }\n    if (options.includeDeletedWithVersions) {\n      include.push(\"deletedwithversions\");\n    }\n    if (options.includeImmutabilityPolicy) {\n      include.push(\"immutabilitypolicy\");\n    }\n    if (options.includeLegalHold) {\n      include.push(\"legalhold\");\n    }\n    if (options.prefix === \"\") {\n      options.prefix = undefined;\n    }\n\n    const updatedOptions: ContainerListBlobsSegmentOptions = {\n      ...options,\n      ...(include.length > 0 ? { include: include } : {}),\n    };\n    // AsyncIterableIterator to iterate over blob prefixes and blobs\n    const iter = this.listItemsByHierarchy(delimiter, updatedOptions);\n    return {\n      /**\n       * The next method, part of the iteration protocol\n       */\n      async next() {\n        return iter.next();\n      },\n      /**\n       * The connection to the async iterator, part of the iteration protocol\n       */\n      [Symbol.asyncIterator]() {\n        return this;\n      },\n      /**\n       * Return an AsyncIterableIterator that works a page at a time\n       */\n      byPage: (settings: PageSettings = {}) => {\n        return this.listHierarchySegments(delimiter, settings.continuationToken, {\n          maxPageSize: settings.maxPageSize,\n          ...updatedOptions,\n        });\n      },\n    };\n  }\n\n  /**\n   * The Filter Blobs operation enables callers to list blobs in the container whose tags\n   * match a given search expression.\n   *\n   * @param tagFilterSqlExpression - The where parameter enables the caller to query blobs whose tags match a given expression.\n   *                                        The given expression must evaluate to true for a blob to be returned in the results.\n   *                                        The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter;\n   *                                        however, only a subset of the OData filter syntax is supported in the Blob service.\n   * @param marker - A string value that identifies the portion of\n   *                          the list of blobs to be returned with the next listing operation. The\n   *                          operation returns the continuationToken value within the response body if the\n   *                          listing operation did not return all blobs remaining to be listed\n   *                          with the current page. The continuationToken value can be used as the value for\n   *                          the marker parameter in a subsequent call to request the next page of list\n   *                          items. The marker value is opaque to the client.\n   * @param options - Options to find blobs by tags.\n   */\n  private async findBlobsByTagsSegment(\n    tagFilterSqlExpression: string,\n    marker?: string,\n    options: ContainerFindBlobsByTagsSegmentOptions = {},\n  ): Promise<ContainerFindBlobsByTagsSegmentResponse> {\n    return tracingClient.withSpan(\n      \"ContainerClient-findBlobsByTagsSegment\",\n      options,\n      async (updatedOptions) => {\n        const response = assertResponse<\n          ContainerFilterBlobsResponse,\n          ContainerFilterBlobsHeaders,\n          FilterBlobSegmentModel\n        >(\n          await this.containerContext.filterBlobs({\n            abortSignal: options.abortSignal,\n            where: tagFilterSqlExpression,\n            marker,\n            maxPageSize: options.maxPageSize,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n\n        const wrappedResponse: ContainerFindBlobsByTagsSegmentResponse = {\n          ...response,\n          _response: response._response, // _response is made non-enumerable\n          blobs: response.blobs.map((blob) => {\n            let tagValue = \"\";\n            if (blob.tags?.blobTagSet.length === 1) {\n              tagValue = blob.tags.blobTagSet[0].value;\n            }\n            return { ...blob, tags: toTags(blob.tags), tagValue };\n          }),\n        };\n        return wrappedResponse;\n      },\n    );\n  }\n\n  /**\n   * Returns an AsyncIterableIterator for ContainerFindBlobsByTagsSegmentResponse.\n   *\n   * @param tagFilterSqlExpression -  The where parameter enables the caller to query blobs whose tags match a given expression.\n   *                                         The given expression must evaluate to true for a blob to be returned in the results.\n   *                                         The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter;\n   *                                         however, only a subset of the OData filter syntax is supported in the Blob service.\n   * @param marker - A string value that identifies the portion of\n   *                          the list of blobs to be returned with the next listing operation. The\n   *                          operation returns the continuationToken value within the response body if the\n   *                          listing operation did not return all blobs remaining to be listed\n   *                          with the current page. The continuationToken value can be used as the value for\n   *                          the marker parameter in a subsequent call to request the next page of list\n   *                          items. The marker value is opaque to the client.\n   * @param options - Options to find blobs by tags.\n   */\n  private async *findBlobsByTagsSegments(\n    tagFilterSqlExpression: string,\n    marker?: string,\n    options: ContainerFindBlobsByTagsSegmentOptions = {},\n  ): AsyncIterableIterator<ContainerFindBlobsByTagsSegmentResponse> {\n    let response;\n    if (!!marker || marker === undefined) {\n      do {\n        response = await this.findBlobsByTagsSegment(tagFilterSqlExpression, marker, options);\n        response.blobs = response.blobs || [];\n        marker = response.continuationToken;\n        yield response;\n      } while (marker);\n    }\n  }\n\n  /**\n   * Returns an AsyncIterableIterator for blobs.\n   *\n   * @param tagFilterSqlExpression -  The where parameter enables the caller to query blobs whose tags match a given expression.\n   *                                         The given expression must evaluate to true for a blob to be returned in the results.\n   *                                         The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter;\n   *                                         however, only a subset of the OData filter syntax is supported in the Blob service.\n   * @param options - Options to findBlobsByTagsItems.\n   */\n  private async *findBlobsByTagsItems(\n    tagFilterSqlExpression: string,\n    options: ContainerFindBlobsByTagsSegmentOptions = {},\n  ): AsyncIterableIterator<FilterBlobItem> {\n    let marker: string | undefined;\n    for await (const segment of this.findBlobsByTagsSegments(\n      tagFilterSqlExpression,\n      marker,\n      options,\n    )) {\n      yield* segment.blobs;\n    }\n  }\n\n  /**\n   * Returns an async iterable iterator to find all blobs with specified tag\n   * under the specified container.\n   *\n   * .byPage() returns an async iterable iterator to list the blobs in pages.\n   *\n   * Example using `for await` syntax:\n   *\n   * ```js\n   * let i = 1;\n   * for await (const blob of containerClient.findBlobsByTags(\"tagkey='tagvalue'\")) {\n   *   console.log(`Blob ${i++}: ${blob.name}`);\n   * }\n   * ```\n   *\n   * Example using `iter.next()`:\n   *\n   * ```js\n   * let i = 1;\n   * const iter = containerClient.findBlobsByTags(\"tagkey='tagvalue'\");\n   * let blobItem = await iter.next();\n   * while (!blobItem.done) {\n   *   console.log(`Blob ${i++}: ${blobItem.value.name}`);\n   *   blobItem = await iter.next();\n   * }\n   * ```\n   *\n   * Example using `byPage()`:\n   *\n   * ```js\n   * // passing optional maxPageSize in the page settings\n   * let i = 1;\n   * for await (const response of containerClient.findBlobsByTags(\"tagkey='tagvalue'\").byPage({ maxPageSize: 20 })) {\n   *   if (response.blobs) {\n   *     for (const blob of response.blobs) {\n   *       console.log(`Blob ${i++}: ${blob.name}`);\n   *     }\n   *   }\n   * }\n   * ```\n   *\n   * Example using paging with a marker:\n   *\n   * ```js\n   * let i = 1;\n   * let iterator = containerClient.findBlobsByTags(\"tagkey='tagvalue'\").byPage({ maxPageSize: 2 });\n   * let response = (await iterator.next()).value;\n   *\n   * // Prints 2 blob names\n   * if (response.blobs) {\n   *   for (const blob of response.blobs) {\n   *     console.log(`Blob ${i++}: ${blob.name}`);\n   *   }\n   * }\n   *\n   * // Gets next marker\n   * let marker = response.continuationToken;\n   * // Passing next marker as continuationToken\n   * iterator = containerClient\n   *   .findBlobsByTags(\"tagkey='tagvalue'\")\n   *   .byPage({ continuationToken: marker, maxPageSize: 10 });\n   * response = (await iterator.next()).value;\n   *\n   * // Prints blob names\n   * if (response.blobs) {\n   *   for (const blob of response.blobs) {\n   *      console.log(`Blob ${i++}: ${blob.name}`);\n   *   }\n   * }\n   * ```\n   *\n   * @param tagFilterSqlExpression -  The where parameter enables the caller to query blobs whose tags match a given expression.\n   *                                         The given expression must evaluate to true for a blob to be returned in the results.\n   *                                         The[OData - ABNF] filter syntax rule defines the formal grammar for the value of the where query parameter;\n   *                                         however, only a subset of the OData filter syntax is supported in the Blob service.\n   * @param options - Options to find blobs by tags.\n   */\n  public findBlobsByTags(\n    tagFilterSqlExpression: string,\n    options: ContainerFindBlobByTagsOptions = {},\n  ): PagedAsyncIterableIterator<FilterBlobItem, ContainerFindBlobsByTagsSegmentResponse> {\n    // AsyncIterableIterator to iterate over blobs\n    const listSegmentOptions: ContainerFindBlobsByTagsSegmentOptions = {\n      ...options,\n    };\n\n    const iter = this.findBlobsByTagsItems(tagFilterSqlExpression, listSegmentOptions);\n    return {\n      /**\n       * The next method, part of the iteration protocol\n       */\n      next() {\n        return iter.next();\n      },\n      /**\n       * The connection to the async iterator, part of the iteration protocol\n       */\n      [Symbol.asyncIterator]() {\n        return this;\n      },\n      /**\n       * Return an AsyncIterableIterator that works a page at a time\n       */\n      byPage: (settings: PageSettings = {}) => {\n        return this.findBlobsByTagsSegments(tagFilterSqlExpression, settings.continuationToken, {\n          maxPageSize: settings.maxPageSize,\n          ...listSegmentOptions,\n        });\n      },\n    };\n  }\n\n  /**\n   * The Get Account Information operation returns the sku name and account kind\n   * for the specified account.\n   * The Get Account Information operation is available on service versions beginning\n   * with version 2018-03-28.\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information\n   *\n   * @param options - Options to the Service Get Account Info operation.\n   * @returns Response data for the Service Get Account Info operation.\n   */\n  public async getAccountInfo(\n    options: ContainerGetAccountInfoOptions = {},\n  ): Promise<ContainerGetAccountInfoResponse> {\n    return tracingClient.withSpan(\n      \"ContainerClient-getAccountInfo\",\n      options,\n      async (updatedOptions) => {\n        return assertResponse<ContainerGetAccountInfoHeaders, ContainerGetAccountInfoHeaders>(\n          await this.containerContext.getAccountInfo({\n            abortSignal: options.abortSignal,\n            tracingOptions: updatedOptions.tracingOptions,\n          }),\n        );\n      },\n    );\n  }\n\n  private getContainerNameFromUrl(): string {\n    let containerName;\n    try {\n      //  URL may look like the following\n      // \"https://myaccount.blob.core.windows.net/mycontainer?sasString\";\n      // \"https://myaccount.blob.core.windows.net/mycontainer\";\n      // IPv4/IPv6 address hosts, Endpoints - `http://127.0.0.1:10000/devstoreaccount1/containername`\n      // http://localhost:10001/devstoreaccount1/containername\n\n      const parsedUrl = new URL(this.url);\n\n      if (parsedUrl.hostname.split(\".\")[1] === \"blob\") {\n        // \"https://myaccount.blob.core.windows.net/containername\".\n        // \"https://customdomain.com/containername\".\n        // .getPath() -> /containername\n        containerName = parsedUrl.pathname.split(\"/\")[1];\n      } else if (isIpEndpointStyle(parsedUrl)) {\n        // IPv4/IPv6 address hosts... Example - http://192.0.0.10:10001/devstoreaccount1/containername\n        // Single word domain without a [dot] in the endpoint... Example - http://localhost:10001/devstoreaccount1/containername\n        // .getPath() -> /devstoreaccount1/containername\n        containerName = parsedUrl.pathname.split(\"/\")[2];\n      } else {\n        // \"https://customdomain.com/containername\".\n        // .getPath() -> /containername\n        containerName = parsedUrl.pathname.split(\"/\")[1];\n      }\n\n      // decode the encoded containerName - to get all the special characters that might be present in it\n      containerName = decodeURIComponent(containerName);\n\n      if (!containerName) {\n        throw new Error(\"Provided containerName is invalid.\");\n      }\n\n      return containerName;\n    } catch (error: any) {\n      throw new Error(\"Unable to extract containerName with provided information.\");\n    }\n  }\n\n  /**\n   * Only available for ContainerClient constructed with a shared key credential.\n   *\n   * Generates a Blob Container Service Shared Access Signature (SAS) URI based on the client properties\n   * and parameters passed in. The SAS is signed by the shared key credential of the client.\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas\n   *\n   * @param options - Optional parameters.\n   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.\n   */\n  public generateSasUrl(options: ContainerGenerateSasUrlOptions): Promise<string> {\n    return new Promise((resolve) => {\n      if (!(this.credential instanceof StorageSharedKeyCredential)) {\n        throw new RangeError(\n          \"Can only generate the SAS when the client is initialized with a shared key credential\",\n        );\n      }\n\n      const sas = generateBlobSASQueryParameters(\n        {\n          containerName: this._containerName,\n          ...options,\n        },\n        this.credential,\n      ).toString();\n\n      resolve(appendToURLQuery(this.url, sas));\n    });\n  }\n\n  /**\n   * Only available for ContainerClient constructed with a shared key credential.\n   *\n   * Generates string to sign for a Blob Container Service Shared Access Signature (SAS) URI\n   * based on the client properties and parameters passed in. The SAS is signed by the shared key credential of the client.\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas\n   *\n   * @param options - Optional parameters.\n   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.\n   */\n  /* eslint-disable-next-line @azure/azure-sdk/ts-naming-options*/\n  public generateSasStringToSign(options: ContainerGenerateSasUrlOptions): string {\n    if (!(this.credential instanceof StorageSharedKeyCredential)) {\n      throw new RangeError(\n        \"Can only generate the SAS when the client is initialized with a shared key credential\",\n      );\n    }\n\n    return generateBlobSASQueryParametersInternal(\n      {\n        containerName: this._containerName,\n        ...options,\n      },\n      this.credential,\n    ).stringToSign;\n  }\n\n  /**\n   * Generates a Blob Container Service Shared Access Signature (SAS) URI based on the client properties\n   * and parameters passed in. The SAS is signed by the input user delegation key.\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas\n   *\n   * @param options - Optional parameters.\n   * @param userDelegationKey -  Return value of `blobServiceClient.getUserDelegationKey()`\n   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.\n   */\n  public generateUserDelegationSasUrl(\n    options: ContainerGenerateSasUrlOptions,\n    userDelegationKey: UserDelegationKey,\n  ): Promise<string> {\n    return new Promise((resolve) => {\n      const sas = generateBlobSASQueryParameters(\n        {\n          containerName: this._containerName,\n          ...options,\n        },\n        userDelegationKey,\n        this.accountName,\n      ).toString();\n\n      resolve(appendToURLQuery(this.url, sas));\n    });\n  }\n\n  /**\n   * Generates string to sign for a Blob Container Service Shared Access Signature (SAS) URI\n   * based on the client properties and parameters passed in. The SAS is signed by the input user delegation key.\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas\n   *\n   * @param options - Optional parameters.\n   * @param userDelegationKey -  Return value of `blobServiceClient.getUserDelegationKey()`\n   * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token.\n   */\n\n  public generateUserDelegationSasStringToSign(\n    options: ContainerGenerateSasUrlOptions,\n    userDelegationKey: UserDelegationKey,\n  ): string {\n    return generateBlobSASQueryParametersInternal(\n      {\n        containerName: this._containerName,\n        ...options,\n      },\n      userDelegationKey,\n      this.accountName,\n    ).stringToSign;\n  }\n\n  /**\n   * Creates a BlobBatchClient object to conduct batch operations.\n   *\n   * @see https://learn.microsoft.com/en-us/rest/api/storageservices/blob-batch\n   *\n   * @returns A new BlobBatchClient object for this container.\n   */\n  public getBlobBatchClient(): BlobBatchClient {\n    return new BlobBatchClient(this.url, this.pipeline);\n  }\n}\n"]}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 {"version":3,"file":"index.mjs","names":["fatfs","asyncMapSettled","filter","find","flatMap","flatten","isEmpty","keyBy","mapToArray","mixin","ms","noop","once","pick","semver","tarStream","uniq","asyncMap","vmdkToVhd","vhdToVMDK","writeOvaOn","cancelable","CancelToken","fromEvents","ignoreErrors","pRetry","createLogger","decorateWith","defer","deferrable","limitConcurrency","parseDuration","PassThrough","pipeline","forbiddenOperation","operationFailed","parseDateTime","Xapi","XapiBase","XapiDiskSource","Ref","synchronized","fatfsBuffer","addMbr","init","fatfsBufferInit","camelToSnakeCase","forEach","map","pDelay","promisifyAll","debounceWithKey","mixins","OTHER_CONFIG_TEMPLATE","asInteger","canSrHaveNewVdiOfSize","isVmHvm","isVmRunning","prepareXapiParam","toQcow2Stream","log","AggregateError","Error","constructor","errors","message","VDI_FORMAT_VHD","VDI_FORMAT_RAW","IPV4_CONFIG_MODES","IPV6_CONFIG_MODES","_dec","Object","values","_dec2","onError","warn","_dec3","_dec4","_dec5","_dec6","_dec7","_dec8","_dec9","_dec10","_dec11","hostRef","_class","_class2","guessVhdSizeOnImport","maxUncoalescedVdis","restartHostTimeout","vdiExportConcurrency","vmEvacuationConcurrency","vmExportConcurrency","vmMigrationConcurrency","vmSnapshotConcurrency","opts","_guessVhdSizeOnImport","_maxUncoalescedVdis","_restartHostTimeout","_vmEvacuationConcurrency","waitStreamEnd","stream","VDI_exportContent","VM_export","_migrateVmWithStorageMotion","VM_snapshot","getObject","args","tmp","_xapiId","apply","_waitObjectState","idOrUuidOrRef","predicate","object","loop","waitObject","then","_getOrWaitObject","_setObjectProperties","props","_context","$ref","ref","$type","type","Promise","all","value","name","call","setDefaultSr","srId","pool","set_default_SR","setPoolMaster","hostId","disableHa","enableHa","heartbeatSrs","configuration","joinPool","masterAddress","masterUsername","masterPassword","force","emergencyShutdownHost","host","debug","name_label","$resident_VMs","vm","is_control_domain","callAsync","clearHost","$pool","migrationNetworkRef","id","undefined","network","other_config","params","EMPTY","popParamsAndTrim","n","last","i","length","pop","delay","when","code","onRetry","error","disableHost","forgetHost","ejectHostFromPool","enableHost","installCertificateOnHost","certificate","chain","privateKey","setHostMultipathing","$defer","multipathing","enabled","pluggedPbds","$PBDs","pbd","currently_attached","unplugPbd","plugPbd","update_other_config","multipathhandle","powerOnHost","rebootHost","setRemoteSyslogHost","syslogDestination","set_logging","syslog_destination","shutdownHost","bypassEvacuate","_cloneVm","nameLabel","_copyVm","sr","snapshotRef","VM_destroy","cloneVm","vmId","fast","cloneRef","copyVm","srOrSrId","remoteCopyVm","targetXapi","targetSrId","compress","body","onVmCreation","set_name_label","VM_import","getVmConsole","disable_pv_vnc","console","$consoles","protocol","exportVmOva","$cancelToken","vmRef","useSnapshot","exportedVm","cancelToken","collectedDisks","blockDevice","$VBDs","vdi","$VDI","push","getStream","$exportContent","format","fileName","description","name_description","capacityMB","Math","ceil","virtual_size","nics","vif","$VIFs","macAddress","MAC_autogenerated","MAC","networkName","writeStream","disks","vmName","vmDescription","cpuCount","VCPUs_at_startup","vmMemoryMB","memory_dynamic_max","firmware","HVM_boot_params","statusCode","headers","statusMessage","destroyed","destroySnapshot","_context2","cancel","destroy","hostXapi","migrationNetwork","$PIFs","pif","management","$network","mapVdisSrs","mapVifsNetworks","bypassAssert","srRef","getDefaultSrRef","defaultSr","$default_SR","getMigrationSrRef","$id","isSrConnected","$SR","hostPbds","Set","PBDs","connectedSrs","Map","isConnected","get","some","has","set","vdis","vbds","$snapshots","concat","vbd","is_a_snapshot","$snapshot_of","vifsMap","defaultNetworkRef","vmVifs","vifDevices","_","device","vifs","err","_failOnCbtError","VM_disableChangedBlockTracking","_callInstallationPlugin","catch","_error$params","_error$params$include","includes","installSupplementalPack","createTemporaryVdiOnHost","$destroy","uuid","installSupplementalPackOnAllHosts","isSrAvailable","content_type","physical_size","physical_utilisation","hosts","objects","findAvailableSharedSr","createTemporaryVdiOnSr","pt","pipe","_importOvaVm","descriptionLabel","memory","networks","nCpus","tables","VM_create","memory_dynamic_min","memory_static_max","memory_static_min","VCPUs_max","onFailure","op","update_blocked_operations","compression","objectId","networkId","VIF_create","VM","resolve","reject","extract","on","entry","cb","diskMetadata","path","resume","nodeStream","table","vhdStream","grainLogicalAddressList","grainFileOffsetList","size","VDI_create","SR","_rawLength","VBD_create","userdevice","String","position","VDI","$importContent","e","start","start_on","importVm","data","migrateVm","migrationNetworkId","accrossPools","useStorageMotion","_startVm","bypassMacAddressesCheck","vmMacAddresses","existingMacAddresses","obj","power_state","mac","assign","hostNameLabel","retry","startVm","startOnly","options","status","unpauseVm","resumeVm","startVmOnCd","order","update_HVM_boot_params","templateNameLabel","base_template_name","template","is_a_template","bootloader","PV_bootloader","bootables","promises","cdDrive","_getVmCdDrive","set_bootable","Boolean","bootable","set_PV_bootloader","_context3","_context4","_cloneVdi","moveVdi","vdiId","barrier","$VM","newVdi","_resizeVdi","_ejectCdFromVm","_insertCdIntoVm","cd","_context5","connectVbd","vbdId","destroyVbdsFromVm","VBDs","VBD_destroy","resizeVdi","ejectCdFromVm","insertCdIntoVm","cdId","snapshotVdi","snap","exportVdiAsVmdk","filename","none","base","nbdConcurrency","preferNbd","vhdResult","vmdkStream","exportVdiAsQcow2","disk","vdiRef","xapi","$xapi","createNetwork","pifId","mtu","vlan","networkRef","MTU","automatic","editPif","physPif","physical","bond_master_of","pifs","wasAttached","vlans","VLAN_master_of","isNotEmpty","newPifs","pifRef","_context6","createBondedNetwork","bondMode","pifIds","masterPifIds","deleteNetwork","pifsByHost","bonds","bond","tunnels","tunnel","access_PIF","_doDockerAction","action","containerId","$resident_on","$master","vmuuid","container","registerDockerContainer","deregisterDockerContainer","startDockerContainer","stopDockerContainer","restartDockerContainer","pauseDockerContainer","unpauseDockerContainer","getCloudInitConfig","templateId","config","templateuuid","slice","createCoreOsCloudInitConfigDrive","vdiUuid","sruuid","replace","createCloudInitConfigDrive","userConfig","networkConfig","fsLabel","buffer","label","createLabel","mkdir","writeFile","createFileSystem","JSON","stringify","platform","viridian","minSize","shared","findAvailableSr","_getHostServerTimeShift","abs","Date","now","isHostServerTimeConsistent","assertConsistentHostServerTime","isHyperThreadingEnabled","threads_per_core","cpu_info","getSmartctlHealth","parse","getSmartctlInformation","deviceNames","informations","getHostBiosInfo","cache","_biosData$systemManu","biosData","currentBiosVersion","hostServerName","toLowerCase","servers","response","fetch","json","serverData","latestBiosVersion","biosLink","isUpToDate","eq","loose","_applyDecoratedDescriptor","prototype","getOwnPropertyDescriptor","default"],"sources":["../../src/xapi/index.mjs"],"sourcesContent":["/* eslint eslint-comments/disable-enable-pair: [error, {allowWholeFile: true}] */\n/* eslint-disable camelcase */\nimport fatfs from '@vates/fatfs'\nimport asyncMapSettled from '@xen-orchestra/async-map/legacy.js'\nimport filter from 'lodash/filter.js'\nimport find from 'lodash/find.js'\nimport flatMap from 'lodash/flatMap.js'\nimport flatten from 'lodash/flatten.js'\nimport isEmpty from 'lodash/isEmpty.js'\nimport keyBy from 'lodash/keyBy.js'\nimport mapToArray from 'lodash/map.js'\nimport mixin from '@xen-orchestra/mixin/legacy.js'\nimport ms from 'ms'\nimport noop from 'lodash/noop.js'\nimport once from 'lodash/once.js'\nimport pick from 'lodash/pick.js'\nimport semver from 'semver'\nimport tarStream from 'tar-stream'\nimport uniq from 'lodash/uniq.js'\nimport { asyncMap } from '@xen-orchestra/async-map'\nimport { vmdkToVhd, vhdToVMDK, writeOvaOn } from 'xo-vmdk-to-vhd'\nimport { cancelable, CancelToken, fromEvents, ignoreErrors, pRetry } from 'promise-toolbox'\nimport { createLogger } from '@xen-orchestra/log'\nimport { decorateWith } from '@vates/decorate-with'\nimport { defer as deferrable } from 'golike-defer'\nimport { limitConcurrency } from 'limit-concurrency-decorator'\nimport { parseDuration } from '@vates/parse-duration'\nimport { PassThrough, pipeline } from 'stream'\nimport { forbiddenOperation, operationFailed } from 'xo-common/api-errors.js'\nimport { parseDateTime, Xapi as XapiBase, XapiDiskSource } from '@xen-orchestra/xapi'\nimport { Ref } from 'xen-api'\nimport { synchronized } from 'decorator-synchronized'\n\nimport fatfsBuffer, { addMbr, init as fatfsBufferInit } from '../fatfs-buffer.mjs'\nimport { camelToSnakeCase, forEach, map, pDelay, promisifyAll } from '../utils.mjs'\nimport { debounceWithKey } from '../_pDebounceWithKey.mjs'\n\nimport mixins from './mixins/index.mjs'\nimport OTHER_CONFIG_TEMPLATE from './other-config-template.mjs'\nimport { asInteger, canSrHaveNewVdiOfSize, isVmHvm, isVmRunning, prepareXapiParam } from './utils.mjs'\nimport { toQcow2Stream } from '@xen-orchestra/qcow2'\n\nconst log = createLogger('xo:xapi')\n\nclass AggregateError extends Error {\n  constructor(errors, message) {\n    super(message)\n    this.errors = errors\n  }\n}\n\n// ===================================================================\n\nexport * from './utils.mjs'\n\n// VDI formats. (Raw is not available for delta vdi.)\nexport const VDI_FORMAT_VHD = 'vhd'\nexport const VDI_FORMAT_RAW = 'raw'\n\nexport const IPV4_CONFIG_MODES = ['None', 'DHCP', 'Static']\nexport const IPV6_CONFIG_MODES = ['None', 'DHCP', 'Static', 'Autoconf']\n\n// ===================================================================\n\n@mixin(Object.values(mixins))\nexport default class Xapi extends XapiBase {\n  constructor({\n    guessVhdSizeOnImport,\n    maxUncoalescedVdis,\n    restartHostTimeout,\n    vdiExportConcurrency,\n    vmEvacuationConcurrency,\n    vmExportConcurrency,\n    vmMigrationConcurrency = 3,\n    vmSnapshotConcurrency,\n    ...opts\n  }) {\n    super(opts)\n\n    this._guessVhdSizeOnImport = guessVhdSizeOnImport\n    this._maxUncoalescedVdis = maxUncoalescedVdis\n    this._restartHostTimeout = parseDuration(restartHostTimeout)\n    this._vmEvacuationConcurrency = vmEvacuationConcurrency\n\n    //  close event is emitted when the export is canceled via browser. See https://github.com/vatesfr/xen-orchestra/issues/5535\n    const waitStreamEnd = async stream => fromEvents(await stream, ['end', 'close'])\n    this.VDI_exportContent = limitConcurrency(vdiExportConcurrency, waitStreamEnd)(this.VDI_exportContent)\n    this.VM_export = limitConcurrency(vmExportConcurrency, waitStreamEnd)(this.VM_export)\n\n    this._migrateVmWithStorageMotion = limitConcurrency(vmMigrationConcurrency)(this._migrateVmWithStorageMotion)\n    this.VM_snapshot = limitConcurrency(vmSnapshotConcurrency)(this.VM_snapshot)\n\n    // Patch getObject to resolve _xapiId property.\n    this.getObject = (\n      getObject =>\n      (...args) => {\n        let tmp\n        if ((tmp = args[0]) != null && (tmp = tmp._xapiId) != null) {\n          args[0] = tmp\n        }\n        return getObject.apply(this, args)\n      }\n    )(this.getObject)\n  }\n\n  // Wait for an object to be in a given state.\n  //\n  // Faster than waitObject() with a function.\n  async _waitObjectState(idOrUuidOrRef, predicate) {\n    const object = this.getObject(idOrUuidOrRef, null)\n    if (object && predicate(object)) {\n      return object\n    }\n\n    const loop = () => this.waitObject(idOrUuidOrRef).then(object => (predicate(object) ? object : loop()))\n\n    return loop()\n  }\n\n  // Returns the objects if already presents or waits for it.\n  async _getOrWaitObject(idOrUuidOrRef) {\n    return this.getObject(idOrUuidOrRef, null) || this.waitObject(idOrUuidOrRef)\n  }\n\n  // =================================================================\n\n  _setObjectProperties(object, props) {\n    const { $ref: ref, $type: type } = object\n\n    // TODO: the thrown error should contain the name of the\n    // properties that failed to be set.\n    return Promise.all(\n      mapToArray(props, (value, name) => {\n        if (value != null) {\n          return this.call(`${type}.set_${camelToSnakeCase(name)}`, ref, prepareXapiParam(value))\n        }\n      })\n    )::ignoreErrors()\n  }\n\n  // =================================================================\n\n  setDefaultSr(srId) {\n    return this.pool.set_default_SR(this.getObject(srId).$ref)\n  }\n\n  // =================================================================\n\n  async setPoolMaster(hostId) {\n    await this.call('pool.designate_new_master', this.getObject(hostId).$ref)\n  }\n\n  // =================================================================\n\n  async disableHa() {\n    await this.call('pool.disable_ha')\n  }\n\n  // =================================================================\n\n  async enableHa(heartbeatSrs, configuration) {\n    await this.call(\n      'pool.enable_ha',\n      heartbeatSrs.map(srId => this.getObject(srId).$ref),\n      configuration\n    )\n  }\n\n  // =================================================================\n\n  async joinPool(masterAddress, masterUsername, masterPassword, force = false) {\n    await this.call(force ? 'pool.join_force' : 'pool.join', masterAddress, masterUsername, masterPassword)\n  }\n\n  // =================================================================\n\n  async emergencyShutdownHost(hostId) {\n    const host = this.getObject(hostId)\n    log.debug(`Emergency shutdown: ${host.name_label}`)\n\n    await this.call('host.disable', host.$ref)\n\n    await asyncMap(host.$resident_VMs, vm => {\n      if (!vm.is_control_domain) {\n        return ignoreErrors.call(this.callAsync('VM.suspend', vm.$ref))\n      }\n    })\n\n    await this.callAsync('host.shutdown', host.$ref)\n  }\n\n  // =================================================================\n\n  // Disable the host and evacuate all its VMs.\n  //\n  // If `force` is false and the evacuation failed, the host is re-\n  // enabled and the error is thrown.\n  async clearHost({ $ref: hostRef, $pool: pool }, force) {\n    await this.call('host.disable', hostRef)\n\n    const migrationNetworkRef = (id => {\n      if (id !== undefined) {\n        const network = this.getObject(id, undefined)\n        if (network === undefined) {\n          throw new Error('could not find migration network ' + id)\n        }\n        return network.$ref\n      }\n    })(pool.other_config['xo:migrationNetwork'])\n\n    // host ref\n    // migration network: optional and might not be supported\n    // batch size: optional and might not be supported\n    const params = [hostRef, migrationNetworkRef ?? Ref.EMPTY, this._vmEvacuationConcurrency]\n\n    // Removes n params from the end and keeps removing until a non-empty param is found\n    const popParamsAndTrim = (n = 0) => {\n      let last\n      let i = 0\n      while (i < n || (last = params[params.length - 1]) === undefined || last === Ref.EMPTY) {\n        if (params.length <= 1) {\n          throw new Error('not enough params left')\n        }\n        params.pop()\n        i++\n      }\n    }\n\n    popParamsAndTrim()\n\n    try {\n      await pRetry(() => this.callAsync('host.evacuate', ...params), {\n        delay: 0,\n        when: { code: 'MESSAGE_PARAMETER_COUNT_MISMATCH' },\n        onRetry: error => {\n          log.warn(error)\n          popParamsAndTrim(1)\n        },\n      })\n    } catch (error) {\n      if (!force) {\n        await this.call('host.enable', hostRef)\n\n        throw error\n      }\n    }\n  }\n\n  async disableHost(hostId) {\n    await this.call('host.disable', this.getObject(hostId).$ref)\n  }\n\n  async forgetHost(hostId) {\n    await this.callAsync('host.destroy', this.getObject(hostId).$ref)\n  }\n\n  async ejectHostFromPool(hostId) {\n    await this.call('pool.eject', this.getObject(hostId).$ref)\n  }\n\n  async enableHost(hostId) {\n    await this.call('host.enable', this.getObject(hostId).$ref)\n  }\n\n  async installCertificateOnHost(hostId, { certificate, chain = '', privateKey }) {\n    try {\n      await this.call('host.install_server_certificate', this.getObject(hostId).$ref, certificate, privateKey, chain)\n    } catch (error) {\n      // CH/XCP-ng reset the connection on the certificate install\n      if (error.code !== 'ECONNRESET') {\n        throw error\n      }\n    }\n  }\n\n  // Resources:\n  // - Citrix XenServer ® 7.0 Administrator's Guide ch. 5.4\n  // - https://github.com/xcp-ng/xenadmin/blob/60dd70fc36faa0ec91654ec97e24b7af36acff9f/XenModel/Actions/Host/EditMultipathAction.cs\n  // - https://github.com/serencorbett1/xenadmin/blob/1c3fb0c1112e4e316423afc6a028066001d3dea1/XenModel/XenAPI-Extensions/SR.cs\n  @decorateWith(deferrable.onError(log.warn))\n  async setHostMultipathing($defer, hostId, multipathing) {\n    const host = this.getObject(hostId)\n\n    if (host.enabled) {\n      await this.disableHost(hostId)\n      $defer(() => this.enableHost(hostId))\n    }\n\n    // Xen center evacuate running VMs before unplugging the PBDs.\n    // The evacuate method uses the live migration to migrate running VMs\n    // from host to another. It only works when a shared SR is present\n    // in the host. For this reason we chose to show a warning instead.\n    const pluggedPbds = host.$PBDs.filter(pbd => pbd.currently_attached)\n    await asyncMapSettled(pluggedPbds, async pbd => {\n      const ref = pbd.$ref\n      await this.unplugPbd(ref)\n      $defer(() => this.plugPbd(ref))\n    })\n\n    return host.update_other_config(\n      multipathing\n        ? {\n            multipathing: 'true',\n            multipathhandle: 'dmp',\n          }\n        : {\n            multipathing: 'false',\n          }\n    )\n  }\n\n  async powerOnHost(hostId) {\n    await this.callAsync('host.power_on', this.getObject(hostId).$ref)\n  }\n\n  async rebootHost(hostId, force = false) {\n    const host = this.getObject(hostId)\n\n    await this.clearHost(host, force)\n    await this.callAsync('host.reboot', host.$ref)\n  }\n\n  async setRemoteSyslogHost(hostId, syslogDestination) {\n    const host = this.getObject(hostId)\n    await host.set_logging(\n      syslogDestination === null\n        ? {}\n        : {\n            syslog_destination: syslogDestination,\n          }\n    )\n    await this.call('host.syslog_reconfigure', host.$ref)\n  }\n\n  async shutdownHost(hostId, { force = false, bypassEvacuate = false } = {}) {\n    const host = this.getObject(hostId)\n    if (bypassEvacuate) {\n      await this.call('host.disable', host.$ref)\n    } else {\n      await this.clearHost(host, force)\n    }\n    await this.callAsync('host.shutdown', host.$ref)\n  }\n\n  // =================================================================\n\n  // Clone a VM: make a fast copy by fast copying each of its VDIs\n  // (using snapshots where possible) on the same SRs.\n  _cloneVm(vm, nameLabel = vm.name_label) {\n    log.debug(`Cloning VM ${vm.name_label}${nameLabel !== vm.name_label ? ` as ${nameLabel}` : ''}`)\n\n    return this.callAsync('VM.clone', vm.$ref, nameLabel)\n  }\n\n  // Copy a VM: make a normal copy of a VM and all its VDIs.\n  //\n  // If a SR is specified, it will contains the copies of the VDIs,\n  // otherwise they will use the SRs they are on.\n  async _copyVm(vm, nameLabel = vm.name_label, sr = undefined) {\n    let snapshotRef\n    if (isVmRunning(vm)) {\n      snapshotRef = await this.VM_snapshot(vm.$ref)\n    }\n\n    log.debug(\n      `Copying VM ${vm.name_label}${nameLabel !== vm.name_label ? ` as ${nameLabel}` : ''}${\n        sr ? ` on ${sr.name_label}` : ''\n      }`\n    )\n\n    try {\n      return await this.callAsync('VM.copy', snapshotRef || vm.$ref, nameLabel, sr ? sr.$ref : '')\n    } finally {\n      if (snapshotRef) {\n        await this.VM_destroy(snapshotRef)\n      }\n    }\n  }\n\n  async cloneVm(vmId, { nameLabel = undefined, fast = true } = {}) {\n    const vm = this.getObject(vmId)\n\n    const cloneRef = await (fast ? this._cloneVm(vm, nameLabel) : this._copyVm(vm, nameLabel))\n\n    return /* await */ this._getOrWaitObject(cloneRef)\n  }\n\n  async copyVm(vmId, { nameLabel = undefined, srOrSrId = undefined } = {}) {\n    return /* await */ this._getOrWaitObject(\n      await this._copyVm(this.getObject(vmId), nameLabel, srOrSrId !== undefined ? this.getObject(srOrSrId) : undefined)\n    )\n  }\n\n  async remoteCopyVm(vmId, targetXapi, targetSrId, { compress, nameLabel = undefined } = {}) {\n    // Fall back on local copy if possible.\n    if (targetXapi === this) {\n      return {\n        vm: await this.copyVm(vmId, { nameLabel, srOrSrId: targetSrId }),\n      }\n    }\n\n    const sr = targetXapi.getObject(targetSrId)\n    const stream = (\n      await this.VM_export(this.getObject(vmId).$ref, {\n        compress,\n      })\n    ).body\n\n    const onVmCreation = nameLabel !== undefined ? vm => vm.set_name_label(nameLabel) : null\n\n    const vm = await targetXapi._getOrWaitObject(await targetXapi.VM_import(stream, sr.$ref, onVmCreation))\n\n    return {\n      vm,\n    }\n  }\n\n  getVmConsole(vmId) {\n    const vm = this.getObject(vmId)\n\n    if (vm.other_config.disable_pv_vnc === '1') {\n      throw new Error('console is disabled for this VM')\n    }\n\n    const console = find(vm.$consoles, { protocol: 'rfb' })\n    if (!console) {\n      throw new Error('no RFB console found')\n    }\n\n    return console\n  }\n\n  @cancelable\n  async exportVmOva($cancelToken, vmRef) {\n    const vm = this.getObject(vmRef)\n    const useSnapshot = isVmRunning(vm)\n    let exportedVm\n    if (useSnapshot) {\n      const snapshotRef = await this.VM_snapshot(vmRef, {\n        name_label: vm.name_label,\n        cancelToken: $cancelToken,\n      })\n      exportedVm = this.getObject(snapshotRef)\n    } else {\n      exportedVm = vm\n    }\n\n    const collectedDisks = []\n    for (const blockDevice of exportedVm.$VBDs) {\n      if (blockDevice.type === 'Disk') {\n        const vdi = blockDevice.$VDI\n        collectedDisks.push({\n          getStream: () => {\n            return vdi.$exportContent({ cancelToken: $cancelToken, format: VDI_FORMAT_VHD })\n          },\n          name: vdi.name_label,\n          fileName: vdi.name_label + '.vmdk',\n          description: vdi.name_description,\n          capacityMB: Math.ceil(vdi.virtual_size / 1024 / 1024),\n        })\n      }\n    }\n    const nics = []\n    for (const vif of exportedVm.$VIFs) {\n      nics.push({\n        macAddress: vif.MAC_autogenerated ? '' : vif.MAC,\n        networkName: this.getObject(vif.network).name_label,\n      })\n    }\n\n    const writeStream = new PassThrough()\n    writeOvaOn(writeStream, {\n      disks: collectedDisks,\n      vmName: exportedVm.name_label,\n      vmDescription: exportedVm.name_description,\n      cpuCount: exportedVm.VCPUs_at_startup,\n      vmMemoryMB: Math.ceil(exportedVm.memory_dynamic_max / 1024 / 1024),\n      firmware: exportedVm.HVM_boot_params.firmware,\n      nics,\n    })\n\n    writeStream.statusCode = 200\n    writeStream.headers = { 'content-type': 'application/ova' }\n    writeStream.statusMessage = 'OK'\n\n    let destroyed = false\n    const destroySnapshot = () => {\n      if (useSnapshot && !destroyed) {\n        destroyed = true\n        this.VM_destroy(exportedVm.$ref)::ignoreErrors()\n      }\n    }\n    writeStream.cancel = () => {\n      destroySnapshot()\n      return writeStream.destroy()\n    }\n    writeStream.once('end', destroySnapshot)\n    writeStream.once('error', destroySnapshot)\n    return writeStream\n  }\n\n  async _migrateVmWithStorageMotion(\n    vm,\n    hostXapi,\n    host,\n    {\n      migrationNetwork = find(host.$PIFs, pif => pif.management).$network, // TODO: handle not found\n      sr,\n      mapVdisSrs = {},\n      mapVifsNetworks,\n      force = false,\n      bypassAssert = false,\n    }\n  ) {\n    const srRef = sr !== undefined ? hostXapi.getObject(sr).$ref : undefined\n    const getDefaultSrRef = once(() => {\n      const defaultSr = host.$pool.$default_SR\n      if (defaultSr === undefined) {\n        throw new Error(`This operation requires a default SR to be set on the pool ${host.$pool.name_label}`)\n      }\n      return defaultSr.$ref\n    })\n\n    // VDIs/SRs mapping\n    // For VDI:\n    // - If a map of VDI -> SR was explicitly passed: use it\n    // - Else if SR was explicitly passed: use it\n    // - Else if VDI SR is reachable from the destination host: use it\n    // - Else: use the migration main SR or the pool's default SR (error if none of them is defined)\n    function getMigrationSrRef(vdi) {\n      if (mapVdisSrs[vdi.$id] !== undefined) {\n        return hostXapi.getObject(mapVdisSrs[vdi.$id]).$ref\n      }\n\n      if (srRef !== undefined) {\n        return srRef\n      }\n\n      if (isSrConnected(vdi.$SR)) {\n        return vdi.$SR.$ref\n      }\n\n      return getDefaultSrRef()\n    }\n\n    const hostPbds = new Set(host.PBDs)\n    const connectedSrs = new Map()\n    const isSrConnected = sr => {\n      let isConnected = connectedSrs.get(sr.$ref)\n      if (isConnected === undefined) {\n        isConnected = sr.PBDs.some(ref => hostPbds.has(ref))\n        connectedSrs.set(sr.$ref, isConnected)\n      }\n      return isConnected\n    }\n\n    // VDIs/SRs mapping\n    // For VDI-snapshot:\n    // - If VDI-snapshot is an orphan snapshot: same logic as a VDI\n    // - Else: don't add it to the map (VDI -> SR). It will be managed by the XAPI (snapshot will be migrated to the same SR as its parent active VDI)\n    const vdis = {}\n    const vbds = flatMap(vm.$snapshots, '$VBDs').concat(vm.$VBDs)\n    for (const vbd of vbds) {\n      if (vbd.type === 'Disk') {\n        const vdi = vbd.$VDI\n        // We need to explicitly test VDI.is_a_snapshot because there is a problem with XAPI itself (observed on\n        // an XCP-ng 8.1 host, might be related to CBT), where some non-snapshot VDIs have a snapshot_of\n        // property not equal to OpaqueRef:NULL as expected but containing a reference to an existing VDI.\n        //\n        // https://team.vates.fr/vates/pl/9m4u5rsr7tfcdroykwq6i6mcmo\n        if (vdi.is_a_snapshot && vdi.$snapshot_of !== undefined) {\n          continue\n        }\n        vdis[vdi.$ref] = getMigrationSrRef(vdi)\n      }\n    }\n\n    // VIFs/Networks mapping\n    const vifsMap = {}\n    if (vm.$pool !== host.$pool) {\n      const defaultNetworkRef = find(host.$PIFs, pif => pif.management).$network.$ref\n      // Add snapshots' VIFs which VM has no VIFs on these devices\n      const vmVifs = vm.$VIFs\n      const vifDevices = new Set(vmVifs.map(_ => _.device))\n      const vifs = flatMap(vm.$snapshots, '$VIFs')\n        .filter(vif => !vifDevices.has(vif.device))\n        .concat(vmVifs)\n      for (const vif of vifs) {\n        vifsMap[vif.$ref] =\n          mapVifsNetworks && mapVifsNetworks[vif.$id]\n            ? hostXapi.getObject(mapVifsNetworks[vif.$id]).$ref\n            : defaultNetworkRef\n      }\n    }\n\n    const params = [\n      vm.$ref,\n      await hostXapi.call('host.migrate_receive', host.$ref, migrationNetwork.$ref, {}), // token\n      true, // Live migration.\n      vdis,\n      vifsMap,\n      {\n        force: force ? 'true' : 'false',\n      },\n      // FIXME: missing param `vgu_map`, it does not cause issues ATM but it\n      // might need to be changed one day.\n      // {},\n    ]\n\n    if (!bypassAssert) {\n      try {\n        await this.callAsync('VM.assert_can_migrate', ...params)\n      } catch (err) {\n        if (err.code !== 'VDI_CBT_ENABLED') {\n          // cbt disabling is handled later, by the migrate_end call\n          throw err\n        }\n      }\n    }\n    const loop = async (_failOnCbtError = false) => {\n      try {\n        await this.callAsync('VM.migrate_send', ...params)\n      } catch (err) {\n        if (err.code === 'VDI_CBT_ENABLED' && !_failOnCbtError) {\n          // as of 20240619, CBT must be disabled on all disks to allow migration to go through\n          // it will be re enabled if needed by backups\n          // the next backup after a storage migration will be a full backup\n          await this.VM_disableChangedBlockTracking(vm.$ref)\n          return loop(true)\n        }\n        if (err.code === 'TOO_MANY_STORAGE_MIGRATES') {\n          await pDelay(1e4)\n          return loop()\n        }\n        throw err\n      }\n    }\n    return loop().then(noop)\n  }\n\n  @synchronized()\n  _callInstallationPlugin(hostRef, vdi) {\n    return this.call('host.call_plugin', hostRef, 'install-supp-pack', 'install', { vdi }).catch(error => {\n      if (error.code !== 'XENAPI_PLUGIN_FAILURE' || !error.params?.[2]?.includes?.('UPDATE_ALREADY_APPLIED')) {\n        throw error\n      }\n      log.warn('_callInstallationPlugin', { error })\n    })\n  }\n\n  @decorateWith(deferrable)\n  async installSupplementalPack($defer, stream, { hostId }) {\n    if (!stream.length) {\n      throw new Error('stream must have a length')\n    }\n\n    const vdi = await this.createTemporaryVdiOnHost(\n      stream,\n      hostId,\n      '[XO] Supplemental pack ISO',\n      'small temporary VDI to store a supplemental pack ISO'\n    )\n    $defer(() => vdi.$destroy())\n\n    await this._callInstallationPlugin(this.getObject(hostId).$ref, vdi.uuid)\n  }\n\n  @decorateWith(deferrable)\n  async installSupplementalPackOnAllHosts($defer, stream) {\n    if (!stream.length) {\n      throw new Error('stream must have a length')\n    }\n\n    const isSrAvailable = sr =>\n      sr && sr.content_type === 'user' && sr.physical_size - sr.physical_utilisation >= stream.length\n\n    const hosts = filter(this.objects.all, { $type: 'host' })\n\n    const sr = this.findAvailableSharedSr(stream.length)\n\n    // Shared SR available: create only 1 VDI for all the installations\n    if (sr) {\n      const vdi = await this.createTemporaryVdiOnSr(\n        stream,\n        sr,\n        '[XO] Supplemental pack ISO',\n        'small temporary VDI to store a supplemental pack ISO'\n      )\n      $defer(() => vdi.$destroy())\n\n      // Install pack sequentially to prevent concurrent access to the unique VDI\n      for (const host of hosts) {\n        await this._callInstallationPlugin(host.$ref, vdi.uuid)\n      }\n\n      return\n    }\n\n    // No shared SR available: find an available local SR on each host\n    return Promise.all(\n      hosts.map(\n        deferrable(async ($defer, host) => {\n          // pipe stream synchronously to several PassThroughs to be able to pipe them asynchronously later\n          const pt = stream.pipe(new PassThrough())\n          pt.length = stream.length\n\n          const sr = find(\n            host.$PBDs.map(_ => _.$SR),\n            isSrAvailable\n          )\n\n          if (!sr) {\n            throw new Error('no SR available to store installation file')\n          }\n\n          const vdi = await this.createTemporaryVdiOnSr(\n            pt,\n            sr,\n            '[XO] Supplemental pack ISO',\n            'small temporary VDI to store a supplemental pack ISO'\n          )\n          $defer(() => vdi.$destroy())\n\n          await this._callInstallationPlugin(host.$ref, vdi.uuid)\n        })\n      )\n    )\n  }\n\n  @decorateWith(deferrable)\n  async _importOvaVm($defer, stream, { descriptionLabel, disks, memory, nameLabel, networks, nCpus, tables }, sr) {\n    // 1. Create VM.\n    const vm = await this._getOrWaitObject(\n      await this.VM_create({\n        ...OTHER_CONFIG_TEMPLATE,\n        memory_dynamic_max: memory,\n        memory_dynamic_min: memory,\n        memory_static_max: memory,\n        memory_static_min: memory,\n        name_description: descriptionLabel,\n        name_label: nameLabel,\n        VCPUs_at_startup: nCpus,\n        VCPUs_max: nCpus,\n      })\n    )\n    $defer.onFailure(() => this.VM_destroy(vm.$ref))\n    // Disable start and change the VM name label during import.\n    await Promise.all([\n      asyncMapSettled(['start', 'start_on'], op => vm.update_blocked_operations(op, 'OVA import in progress...')),\n      vm.set_name_label(`[Importing...] ${nameLabel}`),\n    ])\n\n    // 2. Create VDIs & Vifs.\n    const vdis = {}\n    const compression = {}\n    const vifDevices = await this.call('VM.get_allowed_VIF_devices', vm.$ref)\n    if (networks.length > vifDevices.length) {\n      throw operationFailed({ objectId: vm.id, code: 'TOO_MANY_VIFs' })\n    }\n    await Promise.all(\n      map(networks, (networkId, i) =>\n        this.VIF_create({\n          device: vifDevices[i],\n          network: this.getObject(networkId).$ref,\n          VM: vm.$ref,\n        })\n      )\n    )\n\n    // 3. Import VDIs contents.\n    await new Promise((resolve, reject) => {\n      const extract = tarStream.extract()\n\n      stream.on('error', reject)\n\n      extract.on('finish', resolve)\n      extract.on('error', reject)\n      extract.on('entry', async (entry, stream, cb) => {\n        const diskMetadata = disks.find(({ path }) => path === entry.name)\n        // Not a disk to import\n        if (!diskMetadata) {\n          stream.on('end', cb)\n          stream.resume()\n          return\n        }\n        const nodeStream = new PassThrough()\n        pipeline(stream, nodeStream, () => {})\n        const table = tables[entry.name]\n        const vhdStream = await vmdkToVhd(\n          nodeStream, // tar-stream stream are not node stream\n          table.grainLogicalAddressList,\n          table.grainFileOffsetList,\n          compression[entry.name] === 'gzip',\n          entry.size\n        )\n\n        try {\n          // vmdk size can be wrong in ova\n          // we use the size in the vmdk descriptor to create the vdi\n          const vdi = (vdis[diskMetadata.path] = await this._getOrWaitObject(\n            await this.VDI_create({\n              name_description: diskMetadata.descriptionLabel,\n              name_label: diskMetadata.nameLabel,\n              SR: sr.$ref,\n              virtual_size: vhdStream._rawLength,\n            })\n          ))\n          $defer.onFailure(() => vdi.$destroy())\n          compression[diskMetadata.path] = diskMetadata.compression\n          await this.VBD_create({\n            userdevice: String(diskMetadata.position),\n            VDI: vdi.$ref,\n            VM: vm.$ref,\n          })\n\n          await vdi.$importContent(vhdStream, { format: VDI_FORMAT_VHD })\n          // See: https://github.com/mafintosh/tar-stream#extracting\n          // No import parallelization.\n        } catch (e) {\n          reject(e)\n        } finally {\n          cb()\n        }\n      })\n      stream.pipe(extract)\n    })\n\n    // Enable start and restore the VM name label after import.\n    await Promise.all([vm.update_blocked_operations({ start: null, start_on: null }), vm.set_name_label(nameLabel)])\n    return vm\n  }\n\n  // TODO: an XVA can contain multiple VMs\n  async importVm(stream, { data, srId, type = 'xva' } = {}) {\n    const sr = srId && this.getObject(srId)\n\n    if (type === 'xva') {\n      return /* await */ this._getOrWaitObject(await this.VM_import(stream, sr?.$ref))\n    }\n\n    if (type === 'ova') {\n      return this._getOrWaitObject(await this._importOvaVm(stream, data, sr))\n    }\n\n    throw new Error(`unsupported type: '${type}'`)\n  }\n\n  async migrateVm(\n    vmId,\n    hostXapi,\n    hostId,\n    { force = false, mapVdisSrs, mapVifsNetworks, migrationNetworkId, sr, bypassAssert } = {}\n  ) {\n    const vm = this.getObject(vmId)\n    const host = hostXapi.getObject(hostId)\n\n    const accrossPools = vm.$pool !== host.$pool\n    const useStorageMotion =\n      accrossPools ||\n      sr !== undefined ||\n      migrationNetworkId !== undefined ||\n      !isEmpty(mapVifsNetworks) ||\n      !isEmpty(mapVdisSrs)\n\n    if (useStorageMotion) {\n      await this._migrateVmWithStorageMotion(vm, hostXapi, host, {\n        migrationNetwork: migrationNetworkId && hostXapi.getObject(migrationNetworkId),\n        sr,\n        mapVdisSrs,\n        mapVifsNetworks,\n        force,\n        bypassAssert,\n      })\n    } else {\n      try {\n        await this.callAsync('VM.pool_migrate', vm.$ref, host.$ref, {\n          force: force ? 'true' : 'false',\n        })\n      } catch (error) {\n        if (error.code !== 'VM_REQUIRES_SR') {\n          throw error\n        }\n\n        // Retry using motion storage.\n        await this._migrateVmWithStorageMotion(vm, hostXapi, host, { force })\n      }\n    }\n  }\n\n  async _startVm(vm, { force = false, bypassMacAddressesCheck = force, hostId } = {}) {\n    if (!bypassMacAddressesCheck) {\n      const vmMacAddresses = vm.$VIFs.map(vif => vif.MAC)\n      if (new Set(vmMacAddresses).size !== vmMacAddresses.length) {\n        throw operationFailed({ objectId: vm.id, code: 'DUPLICATED_MAC_ADDRESS' })\n      }\n\n      const existingMacAddresses = new Set(\n        filter(\n          this.objects.all,\n          obj => obj.id !== vm.id && obj.$type === 'VM' && obj.power_state === 'Running'\n        ).flatMap(vm => vm.$VIFs.map(vif => vif.MAC))\n      )\n      if (vmMacAddresses.some(mac => existingMacAddresses.has(mac))) {\n        throw operationFailed({ objectId: vm.id, code: 'DUPLICATED_MAC_ADDRESS' })\n      }\n    }\n\n    log.debug(`Starting VM ${vm.name_label}`)\n\n    if (force) {\n      await vm.update_blocked_operations({ start: null, start_on: null })\n    }\n\n    const vmRef = vm.$ref\n    if (hostId === undefined) {\n      try {\n        await this.call(\n          'VM.start',\n          vmRef,\n          false, // Start paused?\n          false // Skip pre-boot checks?\n        )\n      } catch (error) {\n        if (error.code !== 'NO_HOSTS_AVAILABLE') {\n          throw error\n        }\n\n        throw Object.assign(\n          new AggregateError(\n            await asyncMap(await this.call('host.get_all'), async hostRef => {\n              const hostNameLabel = await this.call('host.get_name_label', hostRef)\n              try {\n                await this.call('VM.assert_can_boot_here', vmRef, hostRef)\n                return `${hostNameLabel}: OK`\n              } catch (error) {\n                return `${hostNameLabel}: ${error.message}`\n              }\n            }),\n            error.message\n          ),\n          { code: error.code, params: error.params }\n        )\n      }\n    } else {\n      const hostRef = this.getObject(hostId).$ref\n      let retry\n      do {\n        retry = false\n\n        try {\n          await this.callAsync('VM.start_on', vmRef, hostRef, false, false)\n        } catch (error) {\n          if (error.code !== 'NO_HOSTS_AVAILABLE') {\n            throw error\n          }\n\n          await this.call('VM.assert_can_boot_here', vmRef, hostRef)\n\n          // Something has changed between the last two calls, starting the VM should be retried\n          retry = true\n        }\n      } while (retry)\n    }\n  }\n\n  /**\n   *\n   * @param {string} vmId\n   * @param {object} options\n   * @param {boolean} [options.startOnly] - If true, don't try to unpause/resume the VM if VM_BAD_POWER_STATE is thrown\n   *\n   */\n  async startVm(vmId, { startOnly = false, ...options } = {}) {\n    try {\n      await this._startVm(this.getObject(vmId), options)\n    } catch (e) {\n      if (e.code === 'OPERATION_BLOCKED') {\n        throw forbiddenOperation('Start', e.params[1])\n      }\n      if (e.code === 'VM_BAD_POWER_STATE' && !startOnly) {\n        const status = e.params[2]\n        if (status === 'running') {\n          throw e\n        }\n\n        return status === 'paused' ? this.unpauseVm(vmId) : this.resumeVm(vmId)\n      }\n      throw e\n    }\n  }\n\n  async startVmOnCd(vmId) {\n    const vm = this.getObject(vmId)\n\n    if (isVmHvm(vm)) {\n      const { order } = vm.HVM_boot_params\n\n      await vm.update_HVM_boot_params('order', 'd')\n\n      try {\n        await this._startVm(vm)\n      } finally {\n        await vm.update_HVM_boot_params('order', order)\n      }\n    } else {\n      // Find the original template by name (*sigh*).\n      const templateNameLabel = vm.other_config.base_template_name\n      const template =\n        templateNameLabel &&\n        find(this.objects.all, obj => obj.$type === 'VM' && obj.is_a_template && obj.name_label === templateNameLabel)\n\n      const bootloader = vm.PV_bootloader\n      const bootables = []\n      try {\n        const promises = []\n\n        const cdDrive = this._getVmCdDrive(vm)\n        forEach(vm.$VBDs, vbd => {\n          promises.push(vbd.set_bootable(vbd === cdDrive))\n\n          bootables.push([vbd, Boolean(vbd.bootable)])\n        })\n\n        promises.push(\n          vm.set_PV_bootloader('eliloader'),\n          vm.update_other_config({\n            'install-distro': template && template.other_config['install-distro'],\n            'install-repository': 'cdrom',\n          })\n        )\n\n        await Promise.all(promises)\n\n        await this._startVm(vm)\n      } finally {\n        vm.set_PV_bootloader(bootloader)::ignoreErrors()\n\n        forEach(bootables, ([vbd, bootable]) => {\n          vbd.set_bootable(bootable)::ignoreErrors()\n        })\n      }\n    }\n  }\n\n  // =================================================================\n\n  _cloneVdi(vdi) {\n    log.debug(`Cloning VDI ${vdi.name_label}`)\n\n    return this.callAsync('VDI.clone', vdi.$ref)\n  }\n\n  async moveVdi(vdiId, srId, { _failOnCbtError = false } = {}) {\n    const vdi = this.getObject(vdiId)\n    const sr = this.getObject(srId)\n\n    if (vdi.SR === sr.$ref) {\n      return vdi\n    }\n\n    log.debug(`Moving VDI ${vdi.name_label} from ${vdi.$SR.name_label} to ${sr.name_label}`)\n    try {\n      return this.barrier(\n        await pRetry(() => this.callAsync('VDI.pool_migrate', vdi.$ref, sr.$ref, {}), {\n          when: { code: 'TOO_MANY_STORAGE_MIGRATES' },\n        })\n      )\n    } catch (error) {\n      const { code } = error\n      if (code === 'VDI_CBT_ENABLED' && !_failOnCbtError) {\n        log.debug(`${vdi.name_label} has CBT enabled`)\n        // disks attached to dom0 are a xapi internal\n        // it can be, for example, during an export\n        // we shouldn't consider these VBDs are relevant here\n        const vbds = vdi.$VBDs.filter(({ $VM }) => $VM.is_control_domain === false)\n        if (vbds.length === 0) {\n          log.debug(`will disable CBT on ${vdi.name_label}  `)\n          await this.callAsync('VDI.disable_cbt', vdi.$ref)\n        } else {\n          if (vbds.length > 1) {\n            // no implicit workaround if vdi is attached to multiple VMs\n            throw error\n          }\n          // 20240629 we need to disable CBT on all disks of the VM since the xapi\n          // checks all disk of a VM even to migrate only one disk\n          const vbd = vbds[0]\n          log.debug(`will disable CBT on the full VM ${vbd.$VM.name_label}, containing disk ${vdi.name_label}  `)\n          await this.VM_disableChangedBlockTracking(vbd.VM)\n        }\n\n        // cbt will be re enabled when needed on next backup\n        // after a migration the next delta backup is always a base copy\n        // and this will only enabled cbt on needed disks\n\n        // retry migrating disk\n        return this.moveVdi(vdiId, srId, { _failOnCbtError: true })\n      }\n      if (code !== 'NO_HOSTS_AVAILABLE' && code !== 'LICENCE_RESTRICTION' && code !== 'VDI_NEEDS_VM_FOR_MIGRATE') {\n        throw error\n      }\n      const newVdi = await this.barrier(await this.callAsync('VDI.copy', vdi.$ref, sr.$ref))\n      await asyncMapSettled(vdi.$VBDs, async vbd => {\n        await this.call('VBD.destroy', vbd.$ref)\n        await this.VBD_create({\n          ...vbd,\n          VDI: newVdi.$ref,\n        })\n      })\n      await vdi.$destroy()\n\n      return newVdi\n    }\n  }\n\n  _resizeVdi(vdi, size) {\n    log.debug(`Resizing VDI ${vdi.name_label} from ${vdi.virtual_size} to ${size}`)\n\n    return this.callAsync('VDI.resize', vdi.$ref, size)\n  }\n\n  _getVmCdDrive(vm) {\n    for (const vbd of vm.$VBDs) {\n      if (vbd.type === 'CD') {\n        return vbd\n      }\n    }\n  }\n\n  async _ejectCdFromVm(vm) {\n    const cdDrive = this._getVmCdDrive(vm)\n    if (cdDrive) {\n      await this.callAsync('VBD.eject', cdDrive.$ref)\n    }\n  }\n\n  async _insertCdIntoVm(cd, vm, { bootable = false, force = false } = {}) {\n    const cdDrive = await this._getVmCdDrive(vm)\n    if (cdDrive) {\n      try {\n        await this.callAsync('VBD.insert', cdDrive.$ref, cd.$ref)\n      } catch (error) {\n        if (!force || error.code !== 'VBD_NOT_EMPTY') {\n          throw error\n        }\n\n        await this.callAsync('VBD.eject', cdDrive.$ref)::ignoreErrors()\n\n        // Retry.\n        await this.callAsync('VBD.insert', cdDrive.$ref, cd.$ref)\n      }\n\n      if (bootable !== Boolean(cdDrive.bootable)) {\n        await cdDrive.set_bootable(bootable)\n      }\n    } else {\n      await this.VBD_create({\n        bootable,\n        type: 'CD',\n        VDI: cd.$ref,\n        VM: vm.$ref,\n      })\n    }\n  }\n\n  async connectVbd(vbdId) {\n    await this.callAsync('VBD.plug', vbdId)\n  }\n\n  // TODO: remove when no longer used.\n  async destroyVbdsFromVm(vmId) {\n    await Promise.all(this.getObject(vmId).VBDs.map(async ref => this.VBD_destroy(ref)))\n  }\n\n  async resizeVdi(vdiId, size) {\n    await this._resizeVdi(this.getObject(vdiId), size)\n  }\n\n  async ejectCdFromVm(vmId) {\n    await this._ejectCdFromVm(this.getObject(vmId))\n  }\n\n  async insertCdIntoVm(cdId, vmId, opts = undefined) {\n    await this._insertCdIntoVm(this.getObject(cdId), this.getObject(vmId), opts)\n  }\n\n  // -----------------------------------------------------------------\n\n  async snapshotVdi(vdiId, nameLabel) {\n    const vdi = this.getObject(vdiId)\n\n    const snap = await this._getOrWaitObject(await this.callAsync('VDI.snapshot', vdi.$ref))\n\n    if (nameLabel) {\n      await snap.set_name_label(nameLabel)\n    }\n\n    return snap\n  }\n\n  async exportVdiAsVmdk(vdi, filename, { cancelToken = CancelToken.none, base, nbdConcurrency, preferNbd } = {}) {\n    vdi = this.getObject(vdi)\n    const params = { cancelToken, format: VDI_FORMAT_VHD, nbdConcurrency, preferNbd }\n    if (base !== undefined) {\n      params.base = base\n    }\n    let vhdResult\n    const vmdkStream = await vhdToVMDK(`${vdi.name_label}.vmdk`, async () => {\n      vhdResult = await this.VDI_exportContent(vdi.$ref, params)\n      return vhdResult\n    })\n    return vmdkStream\n  }\n\n  async exportVdiAsQcow2(vdi, filename, { cancelToken = CancelToken.none, base, nbdConcurrency, preferNbd } = {}) {\n    vdi = this.getObject(vdi)\n\n    const disk = new XapiDiskSource({\n      vdiRef: vdi.$ref,\n      xapi: vdi.$xapi,\n      nbdConcurrency,\n      preferNbd,\n    })\n    await disk.init()\n    const stream = toQcow2Stream(disk)\n    return stream\n  }\n\n  // =================================================================\n\n  @decorateWith(deferrable)\n  async createNetwork($defer, { name, description = 'Created with Xen Orchestra', pifId, mtu, vlan }) {\n    const networkRef = await this.call('network.create', {\n      name_label: name,\n      name_description: description,\n      MTU: mtu,\n      // Set automatic to false so XenCenter does not get confused\n      // https://citrix.github.io/xenserver-sdk/#network\n      other_config: { automatic: 'false' },\n    })\n    $defer.onFailure(() => this.callAsync('network.destroy', networkRef))\n    if (pifId) {\n      await this.call('pool.create_VLAN_from_PIF', this.getObject(pifId).$ref, networkRef, asInteger(vlan))\n    }\n\n    return this._getOrWaitObject(networkRef)\n  }\n\n  async editPif(pifId, { vlan }) {\n    const pif = this.getObject(pifId)\n    const physPif = find(\n      this.objects.all,\n      obj =>\n        obj.$type === 'PIF' &&\n        (obj.physical || !isEmpty(obj.bond_master_of)) &&\n        obj.$pool === pif.$pool &&\n        obj.device === pif.device\n    )\n\n    if (!physPif) {\n      throw new Error('PIF not found')\n    }\n\n    const pifs = this.getObject(pif.network).$PIFs\n\n    const wasAttached = {}\n    forEach(pifs, pif => {\n      wasAttached[pif.host] = pif.currently_attached\n    })\n\n    const vlans = uniq(pifs.map(pif => pif.VLAN_master_of))\n    await Promise.all(vlans.map(vlan => Ref.isNotEmpty(vlan) && this.callAsync('VLAN.destroy', vlan)))\n\n    const newPifs = await this.call('pool.create_VLAN_from_PIF', physPif.$ref, pif.network, asInteger(vlan))\n    await Promise.all(\n      newPifs.map(\n        pifRef => !wasAttached[this.getObject(pifRef).host] && this.callAsync('PIF.unplug', pifRef)::ignoreErrors()\n      )\n    )\n  }\n\n  @decorateWith(deferrable)\n  async createBondedNetwork($defer, { bondMode, pifIds: masterPifIds, ...params }) {\n    const network = await this.createNetwork(params)\n    $defer.onFailure(() => this.deleteNetwork(network))\n\n    const pifsByHost = {}\n    masterPifIds.forEach(pifId => {\n      this.getObject(pifId).$network.$PIFs.forEach(pif => {\n        if (pifsByHost[pif.host] === undefined) {\n          pifsByHost[pif.host] = []\n        }\n        pifsByHost[pif.host].push(pif.$ref)\n      })\n    })\n\n    await asyncMapSettled(pifsByHost, pifs => this.call('Bond.create', network.$ref, pifs, '', bondMode))\n\n    return network\n  }\n\n  async deleteNetwork(networkId) {\n    const network = this.getObject(networkId)\n    const pifs = network.$PIFs\n\n    const vlans = uniq(pifs.map(pif => pif.VLAN_master_of))\n    await Promise.all(vlans.map(vlan => Ref.isNotEmpty(vlan) && this.callAsync('VLAN.destroy', vlan)))\n\n    const bonds = uniq(flatten(pifs.map(pif => pif.bond_master_of)))\n    await Promise.all(bonds.map(bond => this.call('Bond.destroy', bond)))\n\n    const tunnels = filter(this.objects.all, { $type: 'tunnel' })\n    await Promise.all(\n      pifs.map(async pif => {\n        const tunnel = find(tunnels, { access_PIF: pif.$ref })\n        if (tunnel != null) {\n          await this.callAsync('tunnel.destroy', tunnel.$ref)\n        }\n      })\n    )\n\n    await this.callAsync('network.destroy', network.$ref)\n  }\n\n  // =================================================================\n\n  async _doDockerAction(vmId, action, containerId) {\n    const vm = this.getObject(vmId)\n    const host = vm.$resident_on || this.pool.$master\n\n    return /* await */ this.call('host.call_plugin', host.$ref, 'xscontainer', action, {\n      vmuuid: vm.uuid,\n      container: containerId,\n    })\n  }\n\n  async registerDockerContainer(vmId) {\n    await this._doDockerAction(vmId, 'register')\n  }\n\n  async deregisterDockerContainer(vmId) {\n    await this._doDockerAction(vmId, 'deregister')\n  }\n\n  async startDockerContainer(vmId, containerId) {\n    await this._doDockerAction(vmId, 'start', containerId)\n  }\n\n  async stopDockerContainer(vmId, containerId) {\n    await this._doDockerAction(vmId, 'stop', containerId)\n  }\n\n  async restartDockerContainer(vmId, containerId) {\n    await this._doDockerAction(vmId, 'restart', containerId)\n  }\n\n  async pauseDockerContainer(vmId, containerId) {\n    await this._doDockerAction(vmId, 'pause', containerId)\n  }\n\n  async unpauseDockerContainer(vmId, containerId) {\n    await this._doDockerAction(vmId, 'unpause', containerId)\n  }\n\n  async getCloudInitConfig(templateId) {\n    const template = this.getObject(templateId)\n    const host = this.pool.$master\n\n    const config = await this.call('host.call_plugin', host.$ref, 'xscontainer', 'get_config_drive_default', {\n      templateuuid: template.uuid,\n    })\n    return config.slice(4) // FIXME remove the \"True\" string on the beginning\n  }\n\n  // Specific CoreOS Config Drive\n  async createCoreOsCloudInitConfigDrive(vmId, srId, config) {\n    const vm = this.getObject(vmId)\n    const host = this.pool.$master\n    const sr = this.getObject(srId)\n\n    // See https://github.com/xenserver/xscontainer/blob/master/src/scripts/xscontainer-pluginexample\n    const vdiUuid = (\n      await this.call('host.call_plugin', host.$ref, 'xscontainer', 'create_config_drive', {\n        vmuuid: vm.uuid,\n        sruuid: sr.uuid,\n        configuration: config,\n      })\n    ).replace(/^True/, '')\n    await this.registerDockerContainer(vmId)\n\n    return vdiUuid\n  }\n\n  // Generic Config Drive\n  @decorateWith(deferrable)\n  async createCloudInitConfigDrive($defer, vmId, srId, userConfig, networkConfig) {\n    const vm = this.getObject(vmId)\n    const sr = this.getObject(srId)\n\n    // First, create a small VDI (10MB) which will become the ConfigDrive\n    const fsLabel = 'cidata     '\n    let buffer = fatfsBufferInit({ label: fsLabel })\n\n    // Then, generate a FAT fs\n    const { createLabel, mkdir, writeFile } = promisifyAll(fatfs.createFileSystem(fatfsBuffer(buffer)))\n\n    await Promise.all([\n      // preferred datasource: NoCloud\n      //\n      // https://cloudinit.readthedocs.io/en/latest/topics/datasources/nocloud.html\n      writeFile('meta-data', 'instance-id: ' + vm.uuid + '\\n'),\n      writeFile('user-data', userConfig),\n      networkConfig !== undefined && writeFile('network-config', networkConfig),\n\n      // fallback datasource: Config Drive 2\n      //\n      // https://cloudinit.readthedocs.io/en/latest/topics/datasources/configdrive.html#version-2\n      mkdir('openstack').then(() =>\n        mkdir('openstack/latest').then(() =>\n          Promise.all([\n            writeFile('openstack/latest/meta_data.json', JSON.stringify({ uuid: vm.uuid })),\n            writeFile('openstack/latest/user_data', userConfig),\n          ])\n        )\n      ),\n      createLabel(fsLabel),\n    ])\n    // only add the MBR for windows VM\n    if (vm.platform.viridian === 'true') {\n      buffer = addMbr(buffer)\n    }\n    const vdi = await this._getOrWaitObject(\n      await this.VDI_create({\n        name_label: 'XO CloudConfigDrive',\n        SR: sr.$ref,\n        virtual_size: buffer.length,\n      })\n    )\n    $defer.onFailure(() => vdi.$destroy())\n\n    // ignore errors, I (JFT) don't understand why they are emitted\n    // because it works\n    await vdi.$importContent(buffer, { format: VDI_FORMAT_RAW }).catch(error => {\n      log.warn('importVdiContent: ', { error })\n    })\n\n    await this.VBD_create({ VDI: vdi.$ref, VM: vm.$ref })\n\n    return vdi.uuid\n  }\n\n  @decorateWith(deferrable)\n  async createTemporaryVdiOnSr($defer, stream, sr, name_label, name_description) {\n    const vdi = await this._getOrWaitObject(\n      await this.VDI_create({\n        name_description,\n        name_label,\n        SR: sr.$ref,\n        virtual_size: stream.length,\n      })\n    )\n    $defer.onFailure(() => vdi.$destroy())\n\n    await vdi.$importContent(stream, { format: VDI_FORMAT_RAW })\n\n    return vdi\n  }\n\n  // Create VDI on an adequate local SR\n  async createTemporaryVdiOnHost(stream, hostId, name_label, name_description) {\n    const pbd = find(this.getObject(hostId).$PBDs, pbd => canSrHaveNewVdiOfSize(pbd.$SR, stream.length))\n\n    if (pbd == null) {\n      throw new Error('no SR available')\n    }\n\n    return this.createTemporaryVdiOnSr(stream, pbd.$SR, name_label, name_description)\n  }\n\n  findAvailableSharedSr(minSize) {\n    return find(this.objects.all, obj => obj.$type === 'SR' && obj.shared && canSrHaveNewVdiOfSize(obj, minSize))\n  }\n\n  // Main purpose: upload update on VDI\n  // Is a local SR on a non master host OK?\n  findAvailableSr(minSize) {\n    return find(this.objects.all, obj => obj.$type === 'SR' && canSrHaveNewVdiOfSize(obj, minSize))\n  }\n\n  @decorateWith(debounceWithKey, 60e3, hostRef => hostRef)\n  async _getHostServerTimeShift(hostRef) {\n    return Math.abs(parseDateTime(await this.call('host.get_servertime', hostRef)) * 1e3 - Date.now())\n  }\n\n  async isHostServerTimeConsistent(hostRef) {\n    return (await this._getHostServerTimeShift(hostRef)) < 30e3\n  }\n\n  async assertConsistentHostServerTime(hostRef) {\n    if (!(await this.isHostServerTimeConsistent(hostRef))) {\n      throw new Error(\n        `host server time and XOA date are not consistent with each other (${ms(\n          await this._getHostServerTimeShift(hostRef)\n        )})`\n      )\n    }\n  }\n\n  async isHyperThreadingEnabled(hostId) {\n    const host = this.getObject(hostId)\n\n    // For XCP-ng >=8.3, data is already available in XAPI\n    const { threads_per_core } = host.cpu_info\n    if (threads_per_core !== undefined) {\n      return threads_per_core > 1\n    }\n\n    try {\n      return (await this.call('host.call_plugin', host.$ref, 'hyperthreading.py', 'get_hyperthreading', {})) !== 'false'\n    } catch (error) {\n      if (error.code === 'XENAPI_MISSING_PLUGIN' || error.code === 'UNKNOWN_XENAPI_PLUGIN_FUNCTION') {\n        return null\n      } else {\n        throw error\n      }\n    }\n  }\n\n  async getSmartctlHealth(hostId) {\n    try {\n      return JSON.parse(await this.call('host.call_plugin', this.getObject(hostId).$ref, 'smartctl.py', 'health', {}))\n    } catch (error) {\n      if (error.code === 'XENAPI_MISSING_PLUGIN' || error.code === 'UNKNOWN_XENAPI_PLUGIN_FUNCTION') {\n        return null\n      } else {\n        throw error\n      }\n    }\n  }\n\n  async getSmartctlInformation(hostId, deviceNames) {\n    try {\n      const informations = JSON.parse(\n        await this.call('host.call_plugin', this.getObject(hostId).$ref, 'smartctl.py', 'information', {})\n      )\n      if (deviceNames === undefined) {\n        return informations\n      }\n      return pick(informations, deviceNames)\n    } catch (error) {\n      if (error.code === 'XENAPI_MISSING_PLUGIN' || error.code === 'UNKNOWN_XENAPI_PLUGIN_FUNCTION') {\n        return null\n      } else {\n        throw error\n      }\n    }\n  }\n\n  async getHostBiosInfo(ref, { cache } = {}) {\n    const biosData = await this.call('host.get_bios_strings', ref)\n\n    const { 'bios-version': currentBiosVersion, 'system-product-name': hostServerName } = biosData\n\n    if (biosData['system-manufacturer']?.toLowerCase() !== '2crsi') {\n      return\n    }\n\n    // this code has race conditions which might lead to multiple fetches in parallel\n    // but it's no big deal\n    let servers\n    if (!cache?.has('servers')) {\n      const response = await fetch(\n        'https://pictures.2cr.si/Images_site_web_Odoo/Pages_produit/VATES-BIOS_BMC_last-version.json'\n      )\n      const json = await response.json()\n      servers = keyBy(json[0]['2CRSi_Servers'], 'Server_Name')\n\n      cache?.set('servers', servers)\n    } else {\n      servers = cache.get('servers')\n    }\n\n    const serverData = servers[hostServerName]\n\n    if (serverData === undefined) {\n      return\n    }\n\n    const { 'BIOS-Version': latestBiosVersion, 'BIOS-link': biosLink } = serverData\n\n    // Compare versions loosely to handle non-standard formats\n    const isUpToDate = semver.eq(currentBiosVersion, latestBiosVersion, { loose: true })\n\n    return { currentBiosVersion, latestBiosVersion, biosLink, isUpToDate }\n  }\n}\n"],"mappings":"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","ignoreList":[]}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         );
}

function subscribe(name, subscription) {
  return channel(name).subscribe(subscription);
}

function unsubscribe(name, subscription) {
  return channel(name).unsubscribe(subscription);
}

function hasSubscribers(name) {
  const channel = channels.get(name);
  if (!channel) return false;

  return channel.hasSubscribers;
}

const traceEvents = [
  'start',
  'end',
  'asyncStart',
  'asyncEnd',
  'error',
];

function assertChannel(value, name) {
  if (!(value instanceof Channel)) {
    throw new ERR_INVALID_ARG_TYPE(name, ['Channel'], value);
  }
}

class TracingChannel {
  constructor(nameOrChannels) {
    if (typeof nameOrChannels === 'string') {
      this.start = channel(`tracing:${nameOrChannels}:start`);
      this.end = channel(`tracing:${nameOrChannels}:end`);
      this.asyncStart = channel(`tracing:${nameOrChannels}:asyncStart`);
      this.asyncEnd = channel(`tracing:${nameOrChannels}:asyncEnd`);
      this.error = channel(`tracing:${nameOrChannels}:error`);
    } else if (typeof nameOrChannels === 'object') {
      const { start, end, asyncStart, asyncEnd, error } = nameOrChannels;

      assertChannel(start, 'nameOrChannels.start');
      assertChannel(end, 'nameOrChannels.end');
      assertChannel(asyncStart, 'nameOrChannels.asyncStart');
      assertChannel(asyncEnd, 'nameOrChannels.asyncEnd');
      assertChannel(error, 'nameOrChannels.error');

      this.start = start;
      this.end = end;
      this.asyncStart = asyncStart;
      this.asyncEnd = asyncEnd;
      this.error = error;
    } else {
      throw new ERR_INVALID_ARG_TYPE('nameOrChannels',
                                     ['string', 'object', 'Channel'],
                                     nameOrChannels);
    }
  }

  subscribe(handlers) {
    for (const name of traceEvents) {
      if (!handlers[name]) continue;

      this[name]?.subscribe(handlers[name]);
    }
  }

  unsubscribe(handlers) {
    let done = true;

    for (const name of traceEvents) {
      if (!handlers[name]) continue;

      if (!this[name]?.unsubscribe(handlers[name])) {
        done = false;
      }
    }

    return done;
  }

  traceSync(fn, context = {}, thisArg, ...args) {
    const { start, end, error } = this;

    return start.runStores(context, () => {
      try {
        const result = ReflectApply(fn, thisArg, args);
        context.result = result;
        return result;
      } catch (err) {
        context.error = err;
        error.publish(context);
        throw err;
      } finally {
        end.publish(context);
      }
    });
  }

  tracePromise(fn, context = {}, thisArg, ...args) {
    const { start, end, asyncStart, asyncEnd, error } = this;

    function reject(err) {
      context.error = err;
      error.publish(context);
      asyncStart.publish(context);
      // TODO: Is there a way to have asyncEnd _after_ the continuation?
      asyncEnd.publish(context);
      return PromiseReject(err);
    }

    function resolve(result) {
      context.result = result;
      asyncStart.publish(context);
      // TODO: Is there a way to have asyncEnd _after_ the continuation?
      asyncEnd.publish(context);
      return result;
    }

    return start.runStores(context, () => {
      try {
        let promise = ReflectApply(fn, thisArg, args);
        // Convert thenables to native promises
        if (!(promise instanceof Promise)) {
          promise = PromiseResolve(promise);
        }
        return PromisePrototypeThen(promise, resolve, reject);
      } catch (err) {
        context.error = err;
        error.publish(context);
        throw err;
      } finally {
        end.publish(context);
      }
    });
  }

  traceCallback(fn, position = -1, context = {}, thisArg, ...args) {
    const { start, end, asyncStart, asyncEnd, error } = this;

    function wrappedCallback(err, res) {
      if (err) {
        context.error = err;
        error.publish(context);
      } else {
        context.result = res;
      }

      // Using runStores here enables manual context failure recovery
      asyncStart.runStores(context, () => {
        try {
          if (callback) {
            return ReflectApply(callback, this, arguments);
          }
        } finally {
          asyncEnd.publish(context);
        }
      });
    }

    const callback = args.at(position);
    if (typeof callback !== 'function') {
      throw new ERR_INVALID_ARG_TYPE('callback', ['function'], callback);
    }
    ArrayPrototypeSplice(args, position, 1, wrappedCallback);

    return start.runStores(context, () => {
      try {
        return ReflectApply(fn, thisArg, args);
      } catch (err) {
        context.error = err;
        error.publish(context);
        throw err;
      } finally {
        end.publish(context);
      }
    });
  }
}

function tracingChannel(nameOrChannels) {
  return new TracingChannel(nameOrChannels);
}

module.exports = {
  channel,
  hasSubscribers,
  subscribe,
  tracingChannel,
  unsubscribe,
  Channel,
};
             // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  Array,
  ArrayIsArray,
  ArrayPrototypePush,
  FunctionPrototypeBind,
  FunctionPrototypeCall,
  ObjectDefineProperty,
  ObjectSetPrototypeOf,
  ReflectApply,
  SymbolAsyncDispose,
  SymbolDispose,
} = primordials;

const errors = require('internal/errors');
const {
  kStateSymbol,
  _createSocketHandle,
  newHandle,
} = require('internal/dgram');
const { guessHandleType } = internalBinding('util');
const {
  ERR_BUFFER_OUT_OF_BOUNDS,
  ERR_INVALID_ARG_TYPE,
  ERR_MISSING_ARGS,
  ERR_SOCKET_ALREADY_BOUND,
  ERR_SOCKET_BAD_BUFFER_SIZE,
  ERR_SOCKET_BUFFER_SIZE,
  ERR_SOCKET_DGRAM_IS_CONNECTED,
  ERR_SOCKET_DGRAM_NOT_CONNECTED,
  ERR_SOCKET_DGRAM_NOT_RUNNING,
  ERR_INVALID_FD_TYPE,
} = errors.codes;
const {
  isInt32,
  validateAbortSignal,
  validateString,
  validateNumber,
  validatePort,
} = require('internal/validators');
const { Buffer } = require('buffer');
const { deprecate, promisify } = require('internal/util');
const { isArrayBufferView } = require('internal/util/types');
const EventEmitter = require('events');
const {
  defaultTriggerAsyncIdScope,
  symbols: { async_id_symbol, owner_symbol },
} = require('internal/async_hooks');
const { UV_UDP_REUSEADDR } = internalBinding('constants').os;

const {
  constants: { UV_UDP_IPV6ONLY },
  UDP,
  SendWrap,
} = internalBinding('udp_wrap');

const dc = require('diagnostics_channel');
const udpSocketChannel = dc.channel('udp.socket');

const BIND_STATE_UNBOUND = 0;
const BIND_STATE_BINDING = 1;
const BIND_STATE_BOUND = 2;

const CONNECT_STATE_DISCONNECTED = 0;
const CONNECT_STATE_CONNECTING = 1;
const CONNECT_STATE_CONNECTED = 2;

const RECV_BUFFER = true;
const SEND_BUFFER = false;

// Lazily loaded
let _cluster = null;
function lazyLoadCluster() {
  if (!_cluster) _cluster = require('cluster');
  return _cluster;
}

const errnoException = errors.errnoException;
const exceptionWithHostPort = errors.exceptionWithHostPort;


function Socket(type, listener) {
  FunctionPrototypeCall(EventEmitter, this);
  let lookup;
  let recvBufferSize;
  let sendBufferSize;

  let options;
  if (type !== null && typeof type === 'object') {
    options = type;
    type = options.type;
    lookup = options.lookup;
    recvBufferSize = options.recvBufferSize;
    sendBufferSize = options.sendBufferSize;
  }

  const handle = newHandle(type, lookup);
  handle[owner_symbol] = this;

  this[async_id_symbol] = handle.getAsyncId();
  this.type = type;

  if (typeof listener === 'function')
    this.on('message', listener);

  this[kStateSymbol] = {
    handle,
    receiving: false,
    bindState: BIND_STATE_UNBOUND,
    connectState: CONNECT_STATE_DISCONNECTED,
    queue: undefined,
    reuseAddr: options && options.reuseAddr, // Use UV_UDP_REUSEADDR if true.
    ipv6Only: options && options.ipv6Only,
    recvBufferSize,
    sendBufferSize,
  };

  if (options?.signal !== undefined) {
    const { signal } = options;
    validateAbortSignal(signal, 'options.signal');
    const onAborted = () => {
      if (this[kStateSymbol].handle) this.close();
    };
    if (signal.aborted) {
      onAborted();
    } else {
      const disposable = EventEmitter.addAbortListener(signal, onAborted);
      this.once('close', disposable[SymbolDispose]);
    }
  }
  if (udpSocketChannel.hasSubscribers) {
    udpSocketChannel.publish({
      socket: this,
    });
  }
}
ObjectSetPrototypeOf(Socket.prototype, EventEmitter.prototype);
ObjectSetPrototypeOf(Socket, EventEmitter);


function createSocket(type, listener) {
  return new Socket(type, listener);
}


function startListening(socket) {
  const state = socket[kStateSymbol];

  state.handle.onmessage = onMessage;
  state.handle.onerror = onError;
  state.handle.recvStart();
  state.receiving = true;
  state.bindState = BIND_STATE_BOUND;

  if (state.recvBufferSize)
    bufferSize(socket, state.recvBufferSize, RECV_BUFFER);

  if (state.sendBufferSize)
    bufferSize(socket, state.sendBufferSize, SEND_BUFFER);

  socket.emit('listening');
}

function replaceHandle(self, newHandle) {
  const state = self[kStateSymbol];
  const oldHandle = state.handle;
  // Sync the old handle state to new handle
  if (!oldHandle.hasRef() && typeof newHandle.unref === 'function') {
    newHandle.unref();
  }
  // Set up the handle that we got from primary.
  newHandle.lookup = oldHandle.lookup;
  newHandle.bind = oldHandle.bind;
  newHandle.send = oldHandle.send;
  newHandle[owner_symbol] = self;

  // Replace the existing handle by the handle we got from primary.
  oldHandle.close();
  state.handle = newHandle;
}

function bufferSize(self, size, buffer) {
  if (size >>> 0 !== size)
    throw new ERR_SOCKET_BAD_BUFFER_SIZE();

  const ctx = {};
  const ret = self[kStateSymbol].handle.bufferSize(size, buffer, ctx);
  if (ret === undefined) {
    throw new ERR_SOCKET_BUFFER_SIZE(ctx);
  }
  return ret;
}

// Query primary process to get the server handle and utilize it.
function bindServerHandle(self, options, errCb) {
  const cluster = lazyLoadCluster();

  const state = self[kStateSymbol];
  cluster._getServer(self, options, (err, handle) => {
    if (err) {
      errCb(err);
      return;
    }

    if (!state.handle) {
      // Handle has been closed in the mean time.
      return handle.close();
    }

    replaceHandle(self, handle);
    startListening(self);
  });
}

Socket.prototype.bind = function(port_, address_ /* , callback */) {
  let port = port_;

  healthCheck(this);
  const state = this[kStateSymbol];

  if (state.bindState !== BIND_STATE_UNBOUND)
    throw new ERR_SOCKET_ALREADY_BOUND();

  state.bindState = BIND_STATE_BINDING;

  const cb = arguments.length && arguments[arguments.length - 1];
  if (typeof cb === 'function') {
    function removeListeners() {
      this.removeListener('error', removeListeners);
      this.removeListener('listening', onListening);
    }

    function onListening() {
      FunctionPrototypeCall(removeListeners, this);
      FunctionPrototypeCall(cb, this);
    }

    this.on('error', removeListeners);
    this.on('listening', onListening);
  }

  if (port !== null &&
      typeof port === 'object' &&
      typeof port.recvStart === 'function') {
    replaceHandle(this, port);
    startListening(this);
    return this;
  }

  // Open an existing fd instead of creating a new one.
  if (port !== null && typeof port === 'object' &&
      isInt32(port.fd) && port.fd > 0) {
    const fd = port.fd;
    const exclusive = !!port.exclusive;
    const state = this[kStateSymbol];

    const cluster = lazyLoadCluster();

    if (cluster.isWorker && !exclusive) {
      bindServerHandle(this, {
        address: null,
        port: null,
        addressType: this.type,
        fd,
        flags: null,
      }, (err) => {
        // Callback to handle error.
        const ex = errnoException(err, 'open');
        state.bindState = BIND_STATE_UNBOUND;
        this.emit('error', ex);
      });
      return this;
    }

    const type = guessHandleType(fd);
    if (type !== 'UDP')
      throw new ERR_INVALID_FD_TYPE(type);
    const err = state.handle.open(fd);

    if (err)
      throw errnoException(err, 'open');

    startListening(this);
    return this;
  }

  let address;
  let exclusive;

  if (port !== null && typeof port === 'object') {
    address = port.address || '';
    exclusive = !!port.exclusive;
    port = port.port;
  } else {
    address = typeof address_ === 'function' ? '' : address_;
    exclusive = false;
  }

  // Defaulting address for bind to all interfaces
  if (!address) {
    if (this.type === 'udp4')
      address = '0.0.0.0';
    else
      address = '::';
  }

  // Resolve address first
  state.handle.lookup(address, (err, ip) => {
    if (err) {
      state.bindState = BIND_STATE_UNBOUND;
      this.emit('error', err);
      return;
    }

    const cluster = lazyLoadCluster();

    let flags = 0;
    if (state.reuseAddr)
      flags |= UV_UDP_REUSEADDR;
    if (state.ipv6Only)
      flags |= UV_UDP_IPV6ONLY;

    if (cluster.isWorker && !exclusive) {
      bindServerHandle(this, {
        address: ip,
        port: port,
        addressType: this.type,
        fd: -1,
        flags: flags,
      }, (err) => {
        // Callback to handle error.
        const ex = exceptionWithHostPort(err, 'bind', ip, port);
        state.bindState = BIND_STATE_UNBOUND;
        this.emit('error', ex);
      });
    } else {
      if (!state.handle)
        return; // Handle has been closed in the mean time

      const err = state.handle.bind(ip, port || 0, flags);
      if (err) {
        const ex = exceptionWithHostPort(err, 'bind', ip, port);
        state.bindState = BIND_STATE_UNBOUND;
        this.emit('error', ex);
        // Todo: close?
        return;
      }

      startListening(this);
    }
  });

  return this;
};

Socket.prototype.connect = function(port, address, callback) {
  port = validatePort(port, 'Port', false);
  if (typeof address === 'function') {
    callback = address;
    address = '';
  } else if (address === undefined) {
    address = '';
  }

  validateString(address, 'address');

  const state = this[kStateSymbol];

  if (state.connectState !== CONNECT_STATE_DISCONNECTED)
    throw new ERR_SOCKET_DGRAM_IS_CONNECTED();

  state.connectState = CONNECT_STATE_CONNECTING;
  if (state.bindState === BIND_STATE_UNBOUND)
    this.bind({ port: 0, exclusive: true }, null);

  if (state.bindState !== BIND_STATE_BOUND) {
    enqueue(this, FunctionPrototypeBind(_connect, this,
                                        port, address, callback));
    return;
  }

  ReflectApply(_connect, this, [port, address, callback]);
};


function _connect(port, address, callback) {
  const state = this[kStateSymbol];
  if (callback)
    this.once('connect', callback);

  const afterDns = (ex, ip) => {
    defaultTriggerAsyncIdScope(
      this[async_id_symbol],
      doConnect,
      ex, this, ip, address, port, callback,
    );
  };

  state.handle.lookup(address, afterDns);
}


function doConnect(ex, self, ip, address, port, callback) {
  const state = self[kStateSymbol];
  if (!state.handle)
    return;

  if (!ex) {
    const err = state.handle.connect(ip, port);
    if (err) {
      ex = exceptionWithHostPort(err, 'connect', address, port);
    }
  }

  if (ex) {
    state.connectState = CONNECT_STATE_DISCONNECTED;
    return process.nextTick(() => {
      if (callback) {
        self.removeListener('connect', callback);
        callback(ex);
      } else {
        self.emit('error', ex);
      }
    });
  }

  state.connectState = CONNECT_STATE_CONNECTED;
  process.nextTick(() => self.emit('connect'));
}


Socket.prototype.disconnect = function() {
  const state = this[kStateSymbol];
  if (state.connectState !== CONNECT_STATE_CONNECTED)
    throw new ERR_SOCKET_DGRAM_NOT_CONNECTED();

  const err = state.handle.disconnect();
  if (err)
    throw errnoException(err, 'connect');
  else
    state.connectState = CONNECT_STATE_DISCONNECTED;
};


// Thin wrapper around `send`, here for compatibility with dgram_legacy.js
Socket.prototype.sendto = function(buffer,
                                   offset,
                                   length,
                                   port,
                                   address,
                                   callback) {
  validateNumber(offset, 'offset');
  validateNumber(length, 'length');
  validateNumber(port, 'port');
  validateString(address, 'address');

  this.send(buffer, offset, length, port, address, callback);
};


function sliceBuffer(buffer, offset, length) {
  if (typeof buffer === 'string') {
    buffer = Buffer.from(buffer);
  } else if (!isArrayBufferView(buffer)) {
    throw new ERR_INVALID_ARG_TYPE('buffer',
                                   ['Buffer',
                                    'TypedArray',
                                    'DataView',
                                    'string'],
                                   buffer);
  }

  offset = offset >>> 0;
  length = length >>> 0;
  if (offset > buffer.byteLength) {
    throw new ERR_BUFFER_OUT_OF_BOUNDS('offset');
  }

  if (offset + length > buffer.byteLength) {
    throw new ERR_BUFFER_OUT_OF_BOUNDS('length');
  }

  return Buffer.from(buffer.buffer, buffer.byteOffset + offset, length);
}


function fixBufferList(list) {
  const newlist = new Array(list.length);

  for (let i = 0, l = list.length; i < l; i++) {
    const buf = list[i];
    if (typeof buf === 'string')
      newlist[i] = Buffer.from(buf);
    else if (!isArrayBufferView(buf))
      return null;
    else
      newlist[i] = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
  }

  return newlist;
}


function enqueue(self, toEnqueue) {
  const state = self[kStateSymbol];

  // If the send queue hasn't been initialized yet, do it, and install an
  // event handler that flushes the send queue after binding is done.
  if (state.queue === undefined) {
    state.queue = [];
    self.once(EventEmitter.errorMonitor, onListenError);
    self.once('listening', onListenSuccess);
  }
  ArrayPrototypePush(state.queue, toEnqueue);
}


function onListenSuccess() {
  this.removeListener(EventEmitter.errorMonitor, onListenError);
  FunctionPrototypeCall(clearQueue, this);
}


function onListenError(err) {
  this.removeListener('listening', onListenSuccess);
  this[kStateSymbol].queue = undefined;
}


function clearQueue() {
  const state = this[kStateSymbol];
  const queue = state.queue;
  state.queue = undefined;

  // Flush the send queue.
  for (const queueEntry of queue)
    queueEntry();
}

// valid combinations
// For connectionless sockets
// send(buffer, offset, length, port, address, callback)
// send(buffer, offset, length, port, address)
// send(buffer, offset, length, port, callback)
// send(buffer, offset, length, port)
// send(bufferOrList, port, address, callback)
// send(bufferOrList, port, address)
// send(bufferOrList, port, callback)
// send(bufferOrList, port)
// For connected sockets
// send(buffer, offset, length, callback)
// send(buffer, offset, length)
// send(bufferOrList, callback)
// send(bufferOrList)
Socket.prototype.send = function(buffer,
                                 offset,
                                 length,
                                 port,
                                 address,
                                 callback) {

  let list;
  const state = this[kStateSymbol];
  const connected = state.connectState === CONNECT_STATE_CONNECTED;
  if (!connected) {
    if (address || (port && typeof port !== 'function')) {
      buffer = sliceBuffer(buffer, offset, length);
    } else {
      callback = port;
      port = offset;
      address = length;
    }
  } else {
    if (typeof length === 'number') {
      buffer = sliceBuffer(buffer, offset, length);
      if (typeof port === 'function') {
        callback = port;
        port = null;
      }
    } else {
      callback = offset;
    }

    if (port || address)
      throw new ERR_SOCKET_DGRAM_IS_CONNECTED();
  }

  if (!ArrayIsArray(buffer)) {
    if (typeof buffer === 'string') {
      list = [ Buffer.from(buffer) ];
    } else if (!isArrayBufferView(buffer)) {
      throw new ERR_INVALID_ARG_TYPE('buffer',
                                     ['Buffer',
                                      'TypedArray',
                                      'DataView',
                                      'string'],
                                     buffer);
    } else {
      list = [ buffer ];
    }
  } else if (!(list = fixBufferList(buffer))) {
    throw new ERR_INVALID_ARG_TYPE('buffer list arguments',
                                   ['Buffer',
                                    'TypedArray',
                                    'DataView',
                                    'string'],
                                   buffer);
  }

  if (!connected)
    port = validatePort(port, 'Port', false);

  // Normalize callback so it's either a function or undefined but not anything
  // else.
  if (typeof callback !== 'function')
    callback = undefined;

  if (typeof address === 'function') {
    callback = address;
    address = undefined;
  } else if (address != null) {
    validateString(address, 'address');
  }

  healthCheck(this);

  if (state.bindState === BIND_STATE_UNBOUND)
    this.bind({ port: 0, exclusive: true }, null);

  if (list.length === 0)
    ArrayPrototypePush(list, Buffer.alloc(0));

  // If the socket hasn't been bound yet, push the outbound packet onto the
  // send queue and send after binding is complete.
  if (state.bindState !== BIND_STATE_BOUND) {
    enqueue(this, FunctionPrototypeBind(this.send, this,
                                        list, port, address, callback));
    return;
  }

  const afterDns = (ex, ip) => {
    defaultTriggerAsyncIdScope(
      this[async_id_symbol],
      doSend,
      ex, this, ip, list, address, port, callback,
    );
  };

  if (!connected) {
    state.handle.lookup(address, afterDns);
  } else {
    afterDns(null, null);
  }
};

function doSend(ex, self, ip, list, address, port, callback) {
  const state = self[kStateSymbol];

  if (ex) {
    if (typeof callback === 'function') {
      process.nextTick(callback, ex);
      return;
    }

    process.nextTick(() => self.emit('error', ex));
    return;
  } else if (!state.handle) {
    return;
  }

  const req = new SendWrap();
  req.list = list;  // Keep reference alive.
  req.address = address;
  req.port = port;
  if (callback) {
    req.callback = callback;
    req.oncomplete = afterSend;
  }

  let err;
  if (port)
    err = state.handle.send(req, list, list.length, port, ip, !!callback);
  else
    err = state.handle.send(req, list, list.length, !!callback);

  if (err >= 1) {
    // Synchronous finish. The return code is msg_length + 1 so that we can
    // distinguish between synchronous success and asynchronous success.
    if (callback)
      process.nextTick(callback, null, err - 1);
    return;
  }

  if (err && callback) {
    // Don't emit as error, dgram_legacy.js compatibility
    const ex = exceptionWithHostPort(err, 'send', address, port);
    process.nextTick(callback, ex);
  }
}

function afterSend(err, sent) {
  if (err) {
    err = exceptionWithHostPort(err, 'send', this.address, this.port);
  } else {
    err = null;
  }

  this.callback(err, sent);
}

Socket.prototype.close = function(callback) {
  const state = this[kStateSymbol];
  const queue = state.queue;

  if (typeof callback === 'function')
    this.on('close', callback);

  if (queue !== undefined) {
    ArrayPrototypePush(queue, FunctionPrototypeBind(this.close, this));
    return this;
  }

  healthCheck(this);
  stopReceiving(this);
  state.handle.close();
  state.handle = null;
  defaultTriggerAsyncIdScope(this[async_id_symbol],
                             process.nextTick,
                             socketCloseNT,
                             this);

  return this;
};

Socket.prototype[SymbolAsyncDispose] = async function() {
  if (!this[kStateSymbol].handle) {
    return;
  }
  return FunctionPrototypeCall(promisify(this.close), this);
};


function socketCloseNT(self) {
  self.emit('close');
}


Socket.prototype.address = function() {
  healthCheck(this);

  const out = {};
  const err = this[kStateSymbol].handle.getsockname(out);
  if (err) {
    throw errnoException(err, 'getsockname');
  }

  return out;
};

Socket.prototype.remoteAddress = function() {
  healthCheck(this);

  const state = this[kStateSymbol];
  if (state.connectState !== CONNECT_STATE_CONNECTED)
    throw new ERR_SOCKET_DGRAM_NOT_CONNECTED();

  const out = {};
  const err = state.handle.getpeername(out);
  if (err)
    throw errnoException(err, 'getpeername');

  return out;
};


Socket.prototype.setBroadcast = function(arg) {
  const err = this[kStateSymbol].handle.setBroadcast(arg ? 1 : 0);
  if (err) {
    throw errnoException(err, 'setBroadcast');
  }
};


Socket.prototype.setTTL = function(ttl) {
  validateNumber(ttl, 'ttl');

  const err = this[kStateSymbol].handle.setTTL(ttl);
  if (err) {
    throw errnoException(err, 'setTTL');
  }

  return ttl;
};


Socket.prototype.setMulticastTTL = function(ttl) {
  validateNumber(ttl, 'ttl');

  const err = this[kStateSymbol].handle.setMulticastTTL(ttl);
  if (err) {
    throw errnoException(err, 'setMulticastTTL');
  }

  return ttl;
};


Socket.prototype.setMulticastLoopback = function(arg) {
  const err = this[kStateSymbol].handle.setMulticastLoopback(arg ? 1 : 0);
  if (err) {
    throw errnoException(err, 'setMulticastLoopback');
  }

  return arg; // 0.4 compatibility
};


Socket.prototype.setMulticastInterface = function(interfaceAddress) {
  healthCheck(this);
  validateString(interfaceAddress, 'interfaceAddress');

  const err = this[kStateSymbol].handle.setMulticastInterface(interfaceAddress);
  if (err) {
    throw errnoException(err, 'setMulticastInterface');
  }
};

Socket.prototype.addMembership = function(multicastAddress,
                                          interfaceAddress) {
  healthCheck(this);

  if (!multicastAddress) {
    throw new ERR_MISSING_ARGS('multicastAddress');
  }

  const { handle } = this[kStateSymbol];
  const err = handle.addMembership(multicastAddress, interfaceAddress);
  if (err) {
    throw errnoException(err, 'addMembership');
  }
};


Socket.prototype.dropMembership = function(multicastAddress,
                                           interfaceAddress) {
  healthCheck(this);

  if (!multicastAddress) {
    throw new ERR_MISSING_ARGS('multicastAddress');
  }

  const { handle } = this[kStateSymbol];
  const err = handle.dropMembership(multicastAddress, interfaceAddress);
  if (err) {
    throw errnoException(err, 'dropMembership');
  }
};

Socket.prototype.addSourceSpecificMembership = function(sourceAddress,
                                                        groupAddress,
                                                        interfaceAddress) {
  healthCheck(this);

  validateString(sourceAddress, 'sourceAddress');
  validateString(groupAddress, 'groupAddress');

  const err =
    this[kStateSymbol].handle.addSourceSpecificMembership(sourceAddress,
                                                          groupAddress,
                                                          interfaceAddress);
  if (err) {
    throw errnoException(err, 'addSourceSpecificMembership');
  }
};


Socket.prototype.dropSourceSpecificMembership = function(sourceAddress,
                                                         groupAddress,
                                                         interfaceAddress) {
  healthCheck(this);

  validateString(sourceAddress, 'sourceAddress');
  validateString(groupAddress, 'groupAddress');

  const err =
    this[kStateSymbol].handle.dropSourceSpecificMembership(sourceAddress,
                                                           groupAddress,
                                                           interfaceAddress);
  if (err) {
    throw errnoException(err, 'dropSourceSpecificMembership');
  }
};


function healthCheck(socket) {
  if (!socket[kStateSymbol].handle) {
    // Error message from dgram_legacy.js.
    throw new ERR_SOCKET_DGRAM_NOT_RUNNING();
  }
}


function stopReceiving(socket) {
  const state = socket[kStateSymbol];

  if (!state.receiving)
    return;

  state.handle.recvStop();
  state.receiving = false;
}


function onMessage(nread, handle, buf, rinfo) {
  const self = handle[owner_symbol];
  if (nread < 0) {
    return self.emit('error', errnoException(nread, 'recvmsg'));
  }
  rinfo.size = buf.length; // compatibility
  self.emit('message', buf, rinfo);
}


function onError(nread, handle, error) {
  const self = handle[owner_symbol];
  return self.emit('error', error);
}


Socket.prototype.ref = function() {
  const handle = this[kStateSymbol].handle;

  if (handle)
    handle.ref();

  return this;
};


Socket.prototype.unref = function() {
  const handle = this[kStateSymbol].handle;

  if (handle)
    handle.unref();

  return this;
};


Socket.prototype.setRecvBufferSize = function(size) {
  bufferSize(this, size, RECV_BUFFER);
};


Socket.prototype.setSendBufferSize = function(size) {
  bufferSize(this, size, SEND_BUFFER);
};


Socket.prototype.getRecvBufferSize = function() {
  return bufferSize(this, 0, RECV_BUFFER);
};


Socket.prototype.getSendBufferSize = function() {
  return bufferSize(this, 0, SEND_BUFFER);
};

Socket.prototype.getSendQueueSize = function() {
  return this[kStateSymbol].handle.getSendQueueSize();
};

Socket.prototype.getSendQueueCount = function() {
  return this[kStateSymbol].handle.getSendQueueCount();
};

// Deprecated private APIs.
ObjectDefineProperty(Socket.prototype, '_handle', {
  __proto__: null,
  get: deprecate(function() {
    return this[kStateSymbol].handle;
  }, 'Socket.prototype._handle is deprecated', 'DEP0112'),
  set: deprecate(function(val) {
    this[kStateSymbol].handle = val;
  }, 'Socket.prototype._handle is deprecated', 'DEP0112'),
});


ObjectDefineProperty(Socket.prototype, '_receiving', {
  __proto__: null,
  get: deprecate(function() {
    return this[kStateSymbol].receiving;
  }, 'Socket.prototype._receiving is deprecated', 'DEP0112'),
  set: deprecate(function(val) {
    this[kStateSymbol].receiving = val;
  }, 'Socket.prototype._receiving is deprecated', 'DEP0112'),
});


ObjectDefineProperty(Socket.prototype, '_bindState', {
  __proto__: null,
  get: deprecate(function() {
    return this[kStateSymbol].bindState;
  }, 'Socket.prototype._bindState is deprecated', 'DEP0112'),
  set: deprecate(function(val) {
    this[kStateSymbol].bindState = val;
  }, 'Socket.prototype._bindState is deprecated', 'DEP0112'),
});


ObjectDefineProperty(Socket.prototype, '_queue', {
  __proto__: null,
  get: deprecate(function() {
    return this[kStateSymbol].queue;
  }, 'Socket.prototype._queue is deprecated', 'DEP0112'),
  set: deprecate(function(val) {
    this[kStateSymbol].queue = val;
  }, 'Socket.prototype._queue is deprecated', 'DEP0112'),
});


ObjectDefineProperty(Socket.prototype, '_reuseAddr', {
  __proto__: null,
  get: deprecate(function() {
    return this[kStateSymbol].reuseAddr;
  }, 'Socket.prototype._reuseAddr is deprecated', 'DEP0112'),
  set: deprecate(function(val) {
    this[kStateSymbol].reuseAddr = val;
  }, 'Socket.prototype._reuseAddr is deprecated', 'DEP0112'),
});


Socket.prototype._healthCheck = deprecate(function() {
  healthCheck(this);
}, 'Socket.prototype._healthCheck() is deprecated', 'DEP0112');


Socket.prototype._stopReceiving = deprecate(function() {
  stopReceiving(this);
}, 'Socket.prototype._stopReceiving() is deprecated', 'DEP0112');


// Legacy alias on the C++ wrapper object. This is not public API, so we may
// want to runtime-deprecate it at some point. There's no hurry, though.
ObjectDefineProperty(UDP.prototype, 'owner', {
  __proto__: null,
  get() { return this[owner_symbol]; },
  set(v) { return this[owner_symbol] = v; },
});


module.exports = {
  _createSocketHandle: deprecate(
    _createSocketHandle,
    'dgram._createSocketHandle() is deprecated',
    'DEP0112',
  ),
  createSocket,
  Socket,
};
                               // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// Note: In 0.8 and before, crypto functions all defaulted to using
// binary-encoded strings rather than buffers.

'use strict';

const {
  ObjectDefineProperty,
  ObjectDefineProperties,
} = primordials;

const {
  assertCrypto,
  deprecate,
} = require('internal/util');
assertCrypto();

const {
  ERR_CRYPTO_FIPS_FORCED,
} = require('internal/errors').codes;
const constants = internalBinding('constants').crypto;
const { getOptionValue } = require('internal/options');
const {
  getFipsCrypto,
  setFipsCrypto,
  timingSafeEqual,
} = internalBinding('crypto');
const {
  checkPrime,
  checkPrimeSync,
  generatePrime,
  generatePrimeSync,
  randomBytes,
  randomFill,
  randomFillSync,
  randomInt,
  randomUUID,
} = require('internal/crypto/random');
const {
  pbkdf2,
  pbkdf2Sync,
} = require('internal/crypto/pbkdf2');
const {
  scrypt,
  scryptSync,
} = require('internal/crypto/scrypt');
const {
  hkdf,
  hkdfSync,
} = require('internal/crypto/hkdf');
const {
  generateKeyPair,
  generateKeyPairSync,
  generateKey,
  generateKeySync,
} = require('internal/crypto/keygen');
const {
  createSecretKey,
  createPublicKey,
  createPrivateKey,
  KeyObject,
} = require('internal/crypto/keys');
const {
  DiffieHellman,
  DiffieHellmanGroup,
  ECDH,
  diffieHellman,
} = require('internal/crypto/diffiehellman');
const {
  Cipher,
  Cipheriv,
  Decipher,
  Decipheriv,
  privateDecrypt,
  privateEncrypt,
  publicDecrypt,
  publicEncrypt,
  getCipherInfo,
} = require('internal/crypto/cipher');
const {
  Sign,
  signOneShot,
  Verify,
  verifyOneShot,
} = require('internal/crypto/sig');
const {
  Hash,
  Hmac,
} = require('internal/crypto/hash');
const {
  X509Certificate,
} = require('internal/crypto/x509');
const {
  getCiphers,
  getCurves,
  getDefaultEncoding,
  getHashes,
  setDefaultEncoding,
  setEngine,
  secureHeapUsed,
} = require('internal/crypto/util');
const Certificate = require('internal/crypto/certificate');

let webcrypto;
function lazyWebCrypto() {
  webcrypto ??= require('internal/crypto/webcrypto');
  return webcrypto;
}

// These helper functions are needed because the constructors can
// use new, in which case V8 cannot inline the recursive constructor call
function createHash(algorithm, options) {
  return new Hash(algorithm, options);
}

function createCipher(cipher, password, options) {
  return new Cipher(cipher, password, options);
}

function createCipheriv(cipher, key, iv, options) {
  return new Cipheriv(cipher, key, iv, options);
}

function createDecipher(cipher, password, options) {
  return new Decipher(cipher, password, options);
}

function createDecipheriv(cipher, key, iv, options) {
  return new Decipheriv(cipher, key, iv, options);
}

function createDiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
  return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding);
}

function createDiffieHellmanGroup(name) {
  return new DiffieHellmanGroup(name);
}

function createECDH(curve) {
  return new ECDH(curve);
}

function createHmac(hmac, key, options) {
  return new Hmac(hmac, key, options);
}

function createSign(algorithm, options) {
  return new Sign(algorithm, options);
}

function createVerify(algorithm, options) {
  return new Verify(algorithm, options);
}

module.exports = {
  // Methods
  checkPrime,
  checkPrimeSync,
  createCipheriv,
  createDecipheriv,
  createDiffieHellman,
  createDiffieHellmanGroup,
  createECDH,
  createHash,
  createHmac,
  createPrivateKey,
  createPublicKey,
  createSecretKey,
  createSign,
  createVerify,
  diffieHellman,
  generatePrime,
  generatePrimeSync,
  getCiphers,
  getCipherInfo,
  getCurves,
  getDiffieHellman: createDiffieHellmanGroup,
  getHashes,
  hkdf,
  hkdfSync,
  pbkdf2,
  pbkdf2Sync,
  generateKeyPair,
  generateKeyPairSync,
  generateKey,
  generateKeySync,
  privateDecrypt,
  privateEncrypt,
  publicDecrypt,
  publicEncrypt,
  randomBytes,
  randomFill,
  randomFillSync,
  randomInt,
  randomUUID,
  scrypt,
  scryptSync,
  sign: signOneShot,
  setEngine,
  timingSafeEqual,
  getFips,
  setFips,
  verify: verifyOneShot,

  // Classes
  Certificate,
  Cipher,
  Cipheriv,
  Decipher,
  Decipheriv,
  DiffieHellman,
  DiffieHellmanGroup,
  ECDH,
  Hash,
  Hmac,
  KeyObject,
  Sign,
  Verify,
  X509Certificate,
  secureHeapUsed,
};

function getFips() {
  return getOptionValue('--force-fips') ? 1 : getFipsCrypto();
}

function setFips(val) {
  if (getOptionValue('--force-fips')) {
    if (val) return;
    throw new ERR_CRYPTO_FIPS_FORCED();
  } else {
    setFipsCrypto(val);
  }
}

function getRandomValues(array) {
  return lazyWebCrypto().crypto.getRandomValues(array);
}

ObjectDefineProperty(constants, 'defaultCipherList', {
  __proto__: null,
  get() {
    const value = getOptionValue('--tls-cipher-list');
    ObjectDefineProperty(this, 'defaultCipherList', {
      __proto__: null,
      writable: true,
      configurable: true,
      enumerable: true,
      value,
    });
    return value;
  },
  set(val) {
    ObjectDefineProperty(this, 'defaultCipherList', {
      __proto__: null,
      writable: true,
      configurable: true,
      enumerable: true,
      value: val,
    });
  },
  configurable: true,
  enumerable: true,
});

function getRandomBytesAlias(key) {
  return {
    enumerable: false,
    configurable: true,
    get() {
      let value;
      if (getOptionValue('--pending-deprecation')) {
        value = deprecate(
          randomBytes,
          `crypto.${key} is deprecated.`,
          'DEP0115');
      } else {
        value = randomBytes;
      }
      ObjectDefineProperty(
        this,
        key,
        {
          __proto__: null,
          enumerable: false,
          configurable: true,
          writable: true,
          value: value,
        },
      );
      return value;
    },
    set(value) {
      ObjectDefineProperty(
        this,
        key,
        {
          __proto__: null,
          enumerable: true,
          configurable: true,
          writable: true,
          value,
        },
      );
    },
  };
}

ObjectDefineProperties(module.exports, {
  createCipher: {
    __proto__: null,
    enumerable: false,
    value: deprecate(createCipher,
                     'crypto.createCipher is deprecated.', 'DEP0106'),
  },
  createDecipher: {
    __proto__: null,
    enumerable: false,
    value: deprecate(createDecipher,
                     'crypto.createDecipher is deprecated.', 'DEP0106'),
  },
  // crypto.fips is deprecated. DEP0093. Use crypto.getFips()/crypto.setFips()
  fips: {
    __proto__: null,
    get: getFips,
    set: setFips,
  },
  DEFAULT_ENCODING: {
    __proto__: null,
    enumerable: false,
    configurable: true,
    get: deprecate(getDefaultEncoding,
                   'crypto.DEFAULT_ENCODING is deprecated.', 'DEP0091'),
    set: deprecate(setDefaultEncoding,
                   'crypto.DEFAULT_ENCODING is deprecated.', 'DEP0091'),
  },
  constants: {
    __proto__: null,
    configurable: false,
    enumerable: true,
    value: constants,
  },

  webcrypto: {
    __proto__: null,
    configurable: false,
    enumerable: true,
    get() { return lazyWebCrypto().crypto; },
    set: undefined,
  },

  subtle: {
    __proto__: null,
    configurable: false,
    enumerable: true,
    get() { return lazyWebCrypto().crypto.subtle; },
    set: undefined,
  },

  getRandomValues: {
    __proto__: null,
    configurable: false,
    enumerable: true,
    get: () => getRandomValues,
    set: undefined,
  },

  // Aliases for randomBytes are deprecated.
  // The ecosystem needs those to exist for backwards compatibility.
  prng: getRandomBytesAlias('prng'),
  pseudoRandomBytes: getRandomBytesAlias('pseudoRandomBytes'),
  rng: getRandomBytesAlias('rng'),
});
                 // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ObjectAssign,
  ObjectFreeze,
} = primordials;

// This module is deprecated in documentation only. Users should be directed
// towards using the specific constants exposed by the individual modules on
// which they are most relevant.
// Deprecation Code: DEP0008
const constants = internalBinding('constants');
ObjectAssign(exports,
             constants.os.dlopen,
             constants.os.errno,
             constants.os.priority,
             constants.os.signals,
             constants.fs,
             constants.crypto);
ObjectFreeze(exports);
               // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

module.exports = require('internal/console/global');
              // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ObjectPrototypeHasOwnProperty: ObjectHasOwn,
} = primordials;

const childOrPrimary = ObjectHasOwn(process.env, 'NODE_UNIQUE_ID') ? 'child' : 'primary';
module.exports = require(`internal/cluster/${childOrPrimary}`);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ArrayIsArray,
  ArrayPrototypeFilter,
  ArrayPrototypeIncludes,
  ArrayPrototypeJoin,
  ArrayPrototypeLastIndexOf,
  ArrayPrototypePush,
  ArrayPrototypeSlice,
  ArrayPrototypeSort,
  ArrayPrototypeSplice,
  ArrayPrototypeUnshift,
  ArrayPrototypePushApply,
  NumberIsInteger,
  ObjectAssign,
  ObjectDefineProperty,
  ObjectPrototypeHasOwnProperty,
  RegExpPrototypeExec,
  SafeSet,
  StringPrototypeIncludes,
  StringPrototypeSlice,
  StringPrototypeToUpperCase,
  SymbolDispose,
} = primordials;

const {
  convertToValidSignal,
  createDeferredPromise,
  getSystemErrorName,
  kEmptyObject,
  promisify,
} = require('internal/util');
const { isArrayBufferView } = require('internal/util/types');
let debug = require('internal/util/debuglog').debuglog(
  'child_process',
  (fn) => {
    debug = fn;
  },
);
const { Buffer } = require('buffer');
const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap');

const {
  AbortError,
  codes: errorCodes,
  genericNodeError,
} = require('internal/errors');
const {
  ERR_INVALID_ARG_VALUE,
  ERR_CHILD_PROCESS_IPC_REQUIRED,
  ERR_CHILD_PROCESS_STDIO_MAXBUFFER,
  ERR_INVALID_ARG_TYPE,
  ERR_OUT_OF_RANGE,
} = errorCodes;
const { clearTimeout, setTimeout } = require('timers');
const { getValidatedPath } = require('internal/fs/utils');
const {
  isInt32,
  validateAbortSignal,
  validateArray,
  validateBoolean,
  validateFunction,
  validateObject,
  validateString,
} = require('internal/validators');
const child_process = require('internal/child_process');
const {
  getValidStdio,
  setupChannel,
  ChildProcess,
  stdioStringToArray,
} = child_process;

const MAX_BUFFER = 1024 * 1024;

const isZOS = process.platform === 'os390';
let addAbortListener;

/**
 * Spawns a new Node.js process + fork.
 * @param {string|URL} modulePath
 * @param {string[]} [args]
 * @param {{
 *   cwd?: string | URL;
 *   detached?: boolean;
 *   env?: Record<string, string>;
 *   execPath?: string;
 *   execArgv?: string[];
 *   gid?: number;
 *   serialization?: string;
 *   signal?: AbortSignal;
 *   killSignal?: string | number;
 *   silent?: boolean;
 *   stdio?: Array | string;
 *   uid?: number;
 *   windowsVerbatimArguments?: boolean;
 *   timeout?: number;
 *   }} [options]
 * @returns {ChildProcess}
 */
function fork(modulePath, args = [], options) {
  modulePath = getValidatedPath(modulePath, 'modulePath');

  // Get options and args arguments.
  let execArgv;

  if (args == null) {
    args = [];
  } else if (typeof args === 'object' && !ArrayIsArray(args)) {
    options = args;
    args = [];
  } else {
    validateArray(args, 'args');
  }

  if (options != null) {
    validateObject(options, 'options');
  }
  options = { __proto__: null, ...options, shell: false };
  options.execPath = options.execPath || process.execPath;
  validateArgumentNullCheck(options.execPath, 'options.execPath');

  // Prepare arguments for fork:
  execArgv = options.execArgv || process.execArgv;
  validateArgumentsNullCheck(execArgv, 'options.execArgv');

  if (execArgv === process.execArgv && process._eval != null) {
    const index = ArrayPrototypeLastIndexOf(execArgv, process._eval);
    if (index > 0) {
      // Remove the -e switch to avoid fork bombing ourselves.
      execArgv = ArrayPrototypeSlice(execArgv);
      ArrayPrototypeSplice(execArgv, index - 1, 2);
    }
  }

  args = [...execArgv, modulePath, ...args];

  if (typeof options.stdio === 'string') {
    options.stdio = stdioStringToArray(options.stdio, 'ipc');
  } else if (!ArrayIsArray(options.stdio)) {
    // Use a separate fd=3 for the IPC channel. Inherit stdin, stdout,
    // and stderr from the parent if silent isn't set.
    options.stdio = stdioStringToArray(
      options.silent ? 'pipe' : 'inherit',
      'ipc');
  } else if (!ArrayPrototypeIncludes(options.stdio, 'ipc')) {
    throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio');
  }

  return spawn(options.execPath, args, options);
}

function _forkChild(fd, serializationMode) {
  // set process.send()
  const p = new Pipe(PipeConstants.IPC);
  p.open(fd);
  p.unref();
  const control = setupChannel(process, p, serializationMode);
  process.on('newListener', function onNewListener(name) {
    if (name === 'message' || name === 'disconnect') control.refCounted();
  });
  process.on('removeListener', function onRemoveListener(name) {
    if (name === 'message' || name === 'disconnect') control.unrefCounted();
  });
}

function normalizeExecArgs(command, options, callback) {
  validateString(command, 'command');
  validateArgumentNullCheck(command, 'command');

  if (typeof options === 'function') {
    callback = options;
    options = undefined;
  }

  // Make a shallow copy so we don't clobber the user's options object.
  options = { __proto__: null, ...options };
  options.shell = typeof options.shell === 'string' ? options.shell : true;

  return {
    file: command,
    options: options,
    callback: callback,
  };
}

/**
 * Spawns a shell executing the given command.
 * @param {string} command
 * @param {{
 *   cmd?: string;
 *   env?: Record<string, string>;
 *   encoding?: string;
 *   shell?: string;
 *   signal?: AbortSignal;
 *   timeout?: number;
 *   maxBuffer?: number;
 *   killSignal?: string | number;
 *   uid?: number;
 *   gid?: number;
 *   windowsHide?: boolean;
 *   }} [options]
 * @param {(
 *   error?: Error,
 *   stdout?: string | Buffer,
 *   stderr?: string | Buffer
 *   ) => any} [callback]
 * @returns {ChildProcess}
 */
function exec(command, options, callback) {
  const opts = normalizeExecArgs(command, options, callback);
  return module.exports.execFile(opts.file,
                                 opts.options,
                                 opts.callback);
}

const customPromiseExecFunction = (orig) => {
  return (...args) => {
    const { promise, resolve, reject } = createDeferredPromise();

    promise.child = orig(...args, (err, stdout, stderr) => {
      if (err !== null) {
        err.stdout = stdout;
        err.stderr = stderr;
        reject(err);
      } else {
        resolve({ stdout, stderr });
      }
    });

    return promise;
  };
};

ObjectDefineProperty(exec, promisify.custom, {
  __proto__: null,
  enumerable: false,
  value: customPromiseExecFunction(exec),
});

function normalizeExecFileArgs(file, args, options, callback) {
  if (ArrayIsArray(args)) {
    args = ArrayPrototypeSlice(args);
  } else if (args != null && typeof args === 'object') {
    callback = options;
    options = args;
    args = null;
  } else if (typeof args === 'function') {
    callback = args;
    options = null;
    args = null;
  }

  if (args == null) {
    args = [];
  }

  if (typeof options === 'function') {
    callback = options;
  } else if (options != null) {
    validateObject(options, 'options');
  }

  if (options == null) {
    options = kEmptyObject;
  }

  if (callback != null) {
    validateFunction(callback, 'callback');
  }

  // Validate argv0, if present.
  if (options.argv0 != null) {
    validateString(options.argv0, 'options.argv0');
    validateArgumentNullCheck(options.argv0, 'options.argv0');
  }

  return { file, args, options, callback };
}

/**
 * Spawns the specified file as a shell.
 * @param {string} file
 * @param {string[]} [args]
 * @param {{
 *   cwd?: string | URL;
 *   env?: Record<string, string>;
 *   encoding?: string;
 *   timeout?: number;
 *   maxBuffer?: number;
 *   killSignal?: string | number;
 *   uid?: number;
 *   gid?: number;
 *   windowsHide?: boolean;
 *   windowsVerbatimArguments?: boolean;
 *   shell?: boolean | string;
 *   signal?: AbortSignal;
 *   }} [options]
 * @param {(
 *   error?: Error,
 *   stdout?: string | Buffer,
 *   stderr?: string | Buffer
 *   ) => any} [callback]
 * @returns {ChildProcess}
 */
function execFile(file, args, options, callback) {
  ({ file, args, options, callback } = normalizeExecFileArgs(file, args, options, callback));

  options = {
    __proto__: null,
    encoding: 'utf8',
    timeout: 0,
    maxBuffer: MAX_BUFFER,
    killSignal: 'SIGTERM',
    cwd: null,
    env: null,
    shell: false,
    ...options,
  };

  // Validate the timeout, if present.
  validateTimeout(options.timeout);

  // Validate maxBuffer, if present.
  validateMaxBuffer(options.maxBuffer);

  options.killSignal = sanitizeKillSignal(options.killSignal);

  const child = spawn(file, args, {
    cwd: options.cwd,
    env: options.env,
    gid: options.gid,
    shell: options.shell,
    signal: options.signal,
    uid: options.uid,
    windowsHide: !!options.windowsHide,
    windowsVerbatimArguments: !!options.windowsVerbatimArguments,
  });

  let encoding;
  const _stdout = [];
  const _stderr = [];
  if (options.encoding !== 'buffer' && Buffer.isEncoding(options.encoding)) {
    encoding = options.encoding;
  } else {
    encoding = null;
  }
  let stdoutLen = 0;
  let stderrLen = 0;
  let killed = false;
  let exited = false;
  let timeoutId;

  let ex = null;

  let cmd = file;

  function exithandler(code, signal) {
    if (exited) return;
    exited = true;

    if (timeoutId) {
      clearTimeout(timeoutId);
      timeoutId = null;
    }

    if (!callback) return;

    // merge chunks
    let stdout;
    let stderr;
    if (encoding ||
      (
        child.stdout &&
        child.stdout.readableEncoding
      )) {
      stdout = ArrayPrototypeJoin(_stdout, '');
    } else {
      stdout = Buffer.concat(_stdout);
    }
    if (encoding ||
      (
        child.stderr &&
        child.stderr.readableEncoding
      )) {
      stderr = ArrayPrototypeJoin(_stderr, '');
    } else {
      stderr = Buffer.concat(_stderr);
    }

    if (!ex && code === 0 && signal === null) {
      callback(null, stdout, stderr);
      return;
    }

    if (args?.length)
      cmd += ` ${ArrayPrototypeJoin(args, ' ')}`;

    if (!ex) {
      ex = genericNodeError(`Command failed: ${cmd}\n${stderr}`, {
        code: code < 0 ? getSystemErrorName(code) : code,
        killed: child.killed || killed,
        signal: signal,
      });
    }

    ex.cmd = cmd;
    callback(ex, stdout, stderr);
  }

  function errorhandler(e) {
    ex = e;

    if (child.stdout)
      child.stdout.destroy();

    if (child.stderr)
      child.stderr.destroy();

    exithandler();
  }

  function kill() {
    if (child.stdout)
      child.stdout.destroy();

    if (child.stderr)
      child.stderr.destroy();

    killed = true;
    try {
      child.kill(options.killSignal);
    } catch (e) {
      ex = e;
      exithandler();
    }
  }

  if (options.timeout > 0) {
    timeoutId = setTimeout(function delayedKill() {
      kill();
      timeoutId = null;
    }, options.timeout);
  }

  if (child.stdout) {
    if (encoding)
      child.stdout.setEncoding(encoding);

    child.stdout.on('data', function onChildStdout(chunk) {
      // Do not need to count the length
      if (options.maxBuffer === Infinity) {
        ArrayPrototypePush(_stdout, chunk);
        return;
      }
      const encoding = child.stdout.readableEncoding;
      const length = encoding ?
        Buffer.byteLength(chunk, encoding) :
        chunk.length;
      const slice = encoding ? StringPrototypeSlice :
        (buf, ...args) => buf.slice(...args);
      stdoutLen += length;

      if (stdoutLen > options.maxBuffer) {
        const truncatedLen = options.maxBuffer - (stdoutLen - length);
        ArrayPrototypePush(_stdout, slice(chunk, 0, truncatedLen));

        ex = new ERR_CHILD_PROCESS_STDIO_MAXBUFFER('stdout');
        kill();
      } else {
        ArrayPrototypePush(_stdout, chunk);
      }
    });
  }

  if (child.stderr) {
    if (encoding)
      child.stderr.setEncoding(encoding);

    child.stderr.on('data', function onChildStderr(chunk) {
      // Do not need to count the length
      if (options.maxBuffer === Infinity) {
        ArrayPrototypePush(_stderr, chunk);
        return;
      }
      const encoding = child.stderr.readableEncoding;
      const length = encoding ?
        Buffer.byteLength(chunk, encoding) :
        chunk.length;
      stderrLen += length;

      if (stderrLen > options.maxBuffer) {
        const truncatedLen = options.maxBuffer - (stderrLen - length);
        ArrayPrototypePush(_stderr,
                           chunk.slice(0, truncatedLen));

        ex = new ERR_CHILD_PROCESS_STDIO_MAXBUFFER('stderr');
        kill();
      } else {
        ArrayPrototypePush(_stderr, chunk);
      }
    });
  }

  child.addListener('close', exithandler);
  child.addListener('error', errorhandler);

  return child;
}

ObjectDefineProperty(execFile, promisify.custom, {
  __proto__: null,
  enumerable: false,
  value: customPromiseExecFunction(execFile),
});

function copyProcessEnvToEnv(env, name, optionEnv) {
  if (process.env[name] &&
      (!optionEnv ||
       !ObjectPrototypeHasOwnProperty(optionEnv, name))) {
    env[name] = process.env[name];
  }
}

function normalizeSpawnArguments(file, args, options) {
  validateString(file, 'file');
  validateArgumentNullCheck(file, 'file');

  if (file.length === 0)
    throw new ERR_INVALID_ARG_VALUE('file', file, 'cannot be empty');

  if (ArrayIsArray(args)) {
    args = ArrayPrototypeSlice(args);
  } else if (args == null) {
    args = [];
  } else if (typeof args !== 'object') {
    throw new ERR_INVALID_ARG_TYPE('args', 'object', args);
  } else {
    options = args;
    args = [];
  }

  validateArgumentsNullCheck(args, 'args');

  if (options === undefined)
    options = kEmptyObject;
  else
    validateObject(options, 'options');

  let cwd = options.cwd;

  // Validate the cwd, if present.
  if (cwd != null) {
    cwd = getValidatedPath(cwd, 'options.cwd');
  }

  // Validate detached, if present.
  if (options.detached != null) {
    validateBoolean(options.detached, 'options.detached');
  }

  // Validate the uid, if present.
  if (options.uid != null && !isInt32(options.uid)) {
    throw new ERR_INVALID_ARG_TYPE('options.uid', 'int32', options.uid);
  }

  // Validate the gid, if present.
  if (options.gid != null && !isInt32(options.gid)) {
    throw new ERR_INVALID_ARG_TYPE('options.gid', 'int32', options.gid);
  }

  // Validate the shell, if present.
  if (options.shell != null &&
      typeof options.shell !== 'boolean' &&
      typeof options.shell !== 'string') {
    throw new ERR_INVALID_ARG_TYPE('options.shell',
                                   ['boolean', 'string'], options.shell);
  }

  // Validate argv0, if present.
  if (options.argv0 != null) {
    validateString(options.argv0, 'options.argv0');
    validateArgumentNullCheck(options.argv0, 'options.argv0');
  }

  // Validate windowsHide, if present.
  if (options.windowsHide != null) {
    validateBoolean(options.windowsHide, 'options.windowsHide');
  }

  // Validate windowsVerbatimArguments, if present.
  let { windowsVerbatimArguments } = options;
  if (windowsVerbatimArguments != null) {
    validateBoolean(windowsVerbatimArguments,
                    'options.windowsVerbatimArguments');
  }

  if (options.shell) {
    validateArgumentNullCheck(options.shell, 'options.shell');
    const command = ArrayPrototypeJoin([file, ...args], ' ');
    // Set the shell, switches, and commands.
    if (process.platform === 'win32') {
      if (typeof options.shell === 'string')
        file = options.shell;
      else
        file = process.env.comspec || 'cmd.exe';
      // '/d /s /c' is used only for cmd.exe.
      if (RegExpPrototypeExec(/^(?:.*\\)?cmd(?:\.exe)?$/i, file) !== null) {
        args = ['/d', '/s', '/c', `"${command}"`];
        windowsVerbatimArguments = true;
      } else {
        args = ['-c', command];
      }
    } else {
      if (typeof options.shell === 'string')
        file = options.shell;
      else if (process.platform === 'android')
        file = '/system/bin/sh';
      else
        file = '/bin/sh';
      args = ['-c', command];
    }
  }

  if (typeof options.argv0 === 'string') {
    ArrayPrototypeUnshift(args, options.argv0);
  } else {
    ArrayPrototypeUnshift(args, file);
  }

  const env = options.env || process.env;
  const envPairs = [];

  // process.env.NODE_V8_COVERAGE always propagates, making it possible to
  // collect coverage for programs that spawn with white-listed environment.
  copyProcessEnvToEnv(env, 'NODE_V8_COVERAGE', options.env);

  if (isZOS) {
    // The following environment variables must always propagate if set.
    copyProcessEnvToEnv(env, '_BPXK_AUTOCVT', options.env);
    copyProcessEnvToEnv(env, '_CEE_RUNOPTS', options.env);
    copyProcessEnvToEnv(env, '_TAG_REDIR_ERR', options.env);
    copyProcessEnvToEnv(env, '_TAG_REDIR_IN', options.env);
    copyProcessEnvToEnv(env, '_TAG_REDIR_OUT', options.env);
    copyProcessEnvToEnv(env, 'STEPLIB', options.env);
    copyProcessEnvToEnv(env, 'LIBPATH', options.env);
    copyProcessEnvToEnv(env, '_EDC_SIG_DFLT', options.env);
    copyProcessEnvToEnv(env, '_EDC_SUSV3', options.env);
  }

  let envKeys = [];
  // Prototype values are intentionally included.
  for (const key in env) {
    ArrayPrototypePush(envKeys, key);
  }

  if (process.platform === 'win32') {
    // On Windows env keys are case insensitive. Filter out duplicates,
    // keeping only the first one (in lexicographic order)
    const sawKey = new SafeSet();
    envKeys = ArrayPrototypeFilter(
      ArrayPrototypeSort(envKeys),
      (key) => {
        const uppercaseKey = StringPrototypeToUpperCase(key);
        if (sawKey.has(uppercaseKey)) {
          return false;
        }
        sawKey.add(uppercaseKey);
        return true;
      },
    );
  }

  for (const key of envKeys) {
    const value = env[key];
    if (value !== undefined) {
      validateArgumentNullCheck(key, `options.env['${key}']`);
      validateArgumentNullCheck(value, `options.env['${key}']`);
      ArrayPrototypePush(envPairs, `${key}=${value}`);
    }
  }

  return {
    // Make a shallow copy so we don't clobber the user's options object.
    __proto__: null,
    ...options,
    args,
    cwd,
    detached: !!options.detached,
    envPairs,
    file,
    windowsHide: !!options.windowsHide,
    windowsVerbatimArguments: !!windowsVerbatimArguments,
  };
}

function abortChildProcess(child, killSignal, reason) {
  if (!child)
    return;
  try {
    if (child.kill(killSignal)) {
      child.emit('error', new AbortError(undefined, { cause: reason }));
    }
  } catch (err) {
    child.emit('error', err);
  }
}

/**
 * Spawns a new process using the given `file`.
 * @param {string} file
 * @param {string[]} [args]
 * @param {{
 *   cwd?: string | URL;
 *   env?: Record<string, string>;
 *   argv0?: string;
 *   stdio?: Array | string;
 *   detached?: boolean;
 *   uid?: number;
 *   gid?: number;
 *   serialization?: string;
 *   shell?: boolean | string;
 *   windowsVerbatimArguments?: boolean;
 *   windowsHide?: boolean;
 *   signal?: AbortSignal;
 *   timeout?: number;
 *   killSignal?: string | number;
 *   }} [options]
 * @returns {ChildProcess}
 */
function spawn(file, args, options) {
  options = normalizeSpawnArguments(file, args, options);
  validateTimeout(options.timeout);
  validateAbortSignal(options.signal, 'options.signal');
  const killSignal = sanitizeKillSignal(options.killSignal);
  const child = new ChildProcess();

  debug('spawn', options);
  child.spawn(options);

  if (options.timeout > 0) {
    let timeoutId = setTimeout(() => {
      if (timeoutId) {
        try {
          child.kill(killSignal);
        } catch (err) {
          child.emit('error', err);
        }
        timeoutId = null;
      }
    }, options.timeout);

    child.once('exit', () => {
      if (timeoutId) {
        clearTimeout(timeoutId);
        timeoutId = null;
      }
    });
  }

  if (options.signal) {
    const signal = options.signal;
    if (signal.aborted) {
      process.nextTick(onAbortListener);
    } else {
      addAbortListener ??= require('events').addAbortListener;
      const disposable = addAbortListener(signal, onAbortListener);
      child.once('exit', disposable[SymbolDispose]);
    }

    function onAbortListener() {
      abortChildProcess(child, killSignal, options.signal.reason);
    }
  }

  return child;
}

/**
 * Spawns a new process synchronously using the given `file`.
 * @param {string} file
 * @param {string[]} [args]
 * @param {{
 *   cwd?: string | URL;
 *   input?: string | Buffer | TypedArray | DataView;
 *   argv0?: string;
 *   stdio?: string | Array;
 *   env?: Record<string, string>;
 *   uid?: number;
 *   gid?: number;
 *   timeout?: number;
 *   killSignal?: string | number;
 *   maxBuffer?: number;
 *   encoding?: string;
 *   shell?: boolean | string;
 *   windowsVerbatimArguments?: boolean;
 *   windowsHide?: boolean;
 *   }} [options]
 * @returns {{
 *   pid: number;
 *   output: Array;
 *   stdout: Buffer | string;
 *   stderr: Buffer | string;
 *   status: number | null;
 *   signal: string | null;
 *   error: Error;
 *   }}
 */
function spawnSync(file, args, options) {
  options = {
    __proto__: null,
    maxBuffer: MAX_BUFFER,
    ...normalizeSpawnArguments(file, args, options),
  };

  debug('spawnSync', options);

  // Validate the timeout, if present.
  validateTimeout(options.timeout);

  // Validate maxBuffer, if present.
  validateMaxBuffer(options.maxBuffer);

  // Validate and translate the kill signal, if present.
  options.killSignal = sanitizeKillSignal(options.killSignal);

  options.stdio = getValidStdio(options.stdio || 'pipe', true).stdio;

  if (options.input) {
    const stdin = options.stdio[0] = { ...options.stdio[0] };
    stdin.input = options.input;
  }

  // We may want to pass data in on any given fd, ensure it is a valid buffer
  for (let i = 0; i < options.stdio.length; i++) {
    const input = options.stdio[i] && options.stdio[i].input;
    if (input != null) {
      const pipe = options.stdio[i] = { ...options.stdio[i] };
      if (isArrayBufferView(input)) {
        pipe.input = input;
      } else if (typeof input === 'string') {
        pipe.input = Buffer.from(input, options.encoding);
      } else {
        throw new ERR_INVALID_ARG_TYPE(`options.stdio[${i}]`,
                                       ['Buffer',
                                        'TypedArray',
                                        'DataView',
                                        'string'],
                                       input);
      }
    }
  }

  return child_process.spawnSync(options);
}


function checkExecSyncError(ret, args, cmd) {
  let err;
  if (ret.error) {
    err = ret.error;
    ObjectAssign(err, ret);
  } else if (ret.status !== 0) {
    let msg = 'Command failed: ';
    msg += cmd || ArrayPrototypeJoin(args, ' ');
    if (ret.stderr && ret.stderr.length > 0)
      msg += `\n${ret.stderr.toString()}`;
    err = genericNodeError(msg, ret);
  }
  return err;
}

/**
 * Spawns a file as a shell synchronously.
 * @param {string} file
 * @param {string[]} [args]
 * @param {{
 *   cwd?: string | URL;
 *   input?: string | Buffer | TypedArray | DataView;
 *   stdio?: string | Array;
 *   env?: Record<string, string>;
 *   uid?: number;
 *   gid?: number;
 *   timeout?: number;
 *   killSignal?: string | number;
 *   maxBuffer?: number;
 *   encoding?: string;
 *   windowsHide?: boolean;
 *   shell?: boolean | string;
 *   }} [options]
 * @returns {Buffer | string}
 */
function execFileSync(file, args, options) {
  ({ file, args, options } = normalizeExecFileArgs(file, args, options));

  const inheritStderr = !options.stdio;
  const ret = spawnSync(file, args, options);

  if (inheritStderr && ret.stderr)
    process.stderr.write(ret.stderr);

  const errArgs = [options.argv0 || file];
  ArrayPrototypePushApply(errArgs, args);
  const err = checkExecSyncError(ret, errArgs);

  if (err)
    throw err;

  return ret.stdout;
}

/**
 * Spawns a shell executing the given `command` synchronously.
 * @param {string} command
 * @param {{
 *   cwd?: string | URL;
 *   input?: string | Buffer | TypedArray | DataView;
 *   stdio?: string | Array;
 *   env?: Record<string, string>;
 *   shell?: string;
 *   uid?: number;
 *   gid?: number;
 *   timeout?: number;
 *   killSignal?: string | number;
 *   maxBuffer?: number;
 *   encoding?: string;
 *   windowsHide?: boolean;
 *   }} [options]
 * @returns {Buffer | string}
 */
function execSync(command, options) {
  const opts = normalizeExecArgs(command, options, null);
  const inheritStderr = !opts.options.stdio;

  const ret = spawnSync(opts.file, opts.options);

  if (inheritStderr && ret.stderr)
    process.stderr.write(ret.stderr);

  const err = checkExecSyncError(ret, undefined, command);

  if (err)
    throw err;

  return ret.stdout;
}


function validateArgumentNullCheck(arg, propName) {
  if (typeof arg === 'string' && StringPrototypeIncludes(arg, '\u0000')) {
    throw new ERR_INVALID_ARG_VALUE(propName, arg, 'must be a string without null bytes');
  }
}


function validateArgumentsNullCheck(args, propName) {
  for (let i = 0; i < args.length; ++i) {
    validateArgumentNullCheck(args[i], `${propName}[${i}]`);
  }
}


function validateTimeout(timeout) {
  if (timeout != null && !(NumberIsInteger(timeout) && timeout >= 0)) {
    throw new ERR_OUT_OF_RANGE('timeout', 'an unsigned integer', timeout);
  }
}


function validateMaxBuffer(maxBuffer) {
  if (maxBuffer != null && !(typeof maxBuffer === 'number' && maxBuffer >= 0)) {
    throw new ERR_OUT_OF_RANGE('options.maxBuffer',
                               'a positive number',
                               maxBuffer);
  }
}


function sanitizeKillSignal(killSignal) {
  if (typeof killSignal === 'string' || typeof killSignal === 'number') {
    return convertToValidSignal(killSignal);
  } else if (killSignal != null) {
    throw new ERR_INVALID_ARG_TYPE('options.killSignal',
                                   ['string', 'number'],
                                   killSignal);
  }
}

module.exports = {
  _forkChild,
  ChildProcess,
  exec,
  execFile,
  execFileSync,
  execSync,
  fork,
  spawn,
  spawnSync,
};
  // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  Array,
  ArrayFrom,
  ArrayIsArray,
  ArrayPrototypeForEach,
  ArrayPrototypeIndexOf,
  MathFloor,
  MathMin,
  MathTrunc,
  NumberIsNaN,
  NumberMAX_SAFE_INTEGER,
  NumberMIN_SAFE_INTEGER,
  ObjectCreate,
  ObjectDefineProperties,
  ObjectDefineProperty,
  ObjectSetPrototypeOf,
  RegExpPrototypeSymbolReplace,
  StringPrototypeCharCodeAt,
  StringPrototypeSlice,
  StringPrototypeToLowerCase,
  StringPrototypeTrim,
  SymbolSpecies,
  SymbolToPrimitive,
  TypedArrayPrototypeGetBuffer,
  TypedArrayPrototypeGetByteLength,
  TypedArrayPrototypeGetByteOffset,
  TypedArrayPrototypeFill,
  TypedArrayPrototypeGetLength,
  TypedArrayPrototypeSet,
  TypedArrayPrototypeSlice,
  Uint8Array,
  Uint8ArrayPrototype,
} = primordials;

const {
  byteLengthUtf8,
  compare: _compare,
  compareOffset,
  createFromString,
  fill: bindingFill,
  isAscii: bindingIsAscii,
  isUtf8: bindingIsUtf8,
  indexOfBuffer,
  indexOfNumber,
  indexOfString,
  swap16: _swap16,
  swap32: _swap32,
  swap64: _swap64,
  kMaxLength,
  kStringMaxLength,
} = internalBinding('buffer');
const {
  constants: {
    ALL_PROPERTIES,
    ONLY_ENUMERABLE,
  },
  getOwnNonIndexProperties,
} = internalBinding('util');
const {
  customInspectSymbol,
  isInsideNodeModules,
  lazyDOMException,
  normalizeEncoding,
  kIsEncodingSymbol,
  defineLazyProperties,
} = require('internal/util');
const {
  isAnyArrayBuffer,
  isArrayBufferView,
  isUint8Array,
  isTypedArray,
} = require('internal/util/types');
const {
  inspect: utilInspect,
} = require('internal/util/inspect');
const { encodings } = internalBinding('string_decoder');

const {
  codes: {
    ERR_BUFFER_OUT_OF_BOUNDS,
    ERR_INVALID_ARG_TYPE,
    ERR_INVALID_ARG_VALUE,
    ERR_INVALID_BUFFER_SIZE,
    ERR_OUT_OF_RANGE,
    ERR_MISSING_ARGS,
    ERR_UNKNOWN_ENCODING,
  },
  genericNodeError,
  hideStackFrames,
} = require('internal/errors');
const {
  validateArray,
  validateBuffer,
  validateNumber,
  validateInteger,
  validateString,
} = require('internal/validators');
// Provide validateInteger() but with kMaxLength as the default maximum value.
const validateOffset = (value, name, min = 0, max = kMaxLength) =>
  validateInteger(value, name, min, max);

const {
  FastBuffer,
  markAsUntransferable,
  addBufferPrototypeMethods,
  createUnsafeBuffer,
} = require('internal/buffer');

FastBuffer.prototype.constructor = Buffer;
Buffer.prototype = FastBuffer.prototype;
addBufferPrototypeMethods(Buffer.prototype);

const constants = ObjectDefineProperties({}, {
  MAX_LENGTH: {
    __proto__: null,
    value: kMaxLength,
    writable: false,
    enumerable: true,
  },
  MAX_STRING_LENGTH: {
    __proto__: null,
    value: kStringMaxLength,
    writable: false,
    enumerable: true,
  },
});

Buffer.poolSize = 8 * 1024;
let poolSize, poolOffset, allocPool;

const encodingsMap = ObjectCreate(null);
for (let i = 0; i < encodings.length; ++i)
  encodingsMap[encodings[i]] = i;

function createPool() {
  poolSize = Buffer.poolSize;
  allocPool = createUnsafeBuffer(poolSize).buffer;
  markAsUntransferable(allocPool);
  poolOffset = 0;
}
createPool();

function alignPool() {
  // Ensure aligned slices
  if (poolOffset & 0x7) {
    poolOffset |= 0x7;
    poolOffset++;
  }
}

let bufferWarningAlreadyEmitted = false;
let nodeModulesCheckCounter = 0;
const bufferWarning = 'Buffer() is deprecated due to security and usability ' +
                      'issues. Please use the Buffer.alloc(), ' +
                      'Buffer.allocUnsafe(), or Buffer.from() methods instead.';

function showFlaggedDeprecation() {
  if (bufferWarningAlreadyEmitted ||
      ++nodeModulesCheckCounter > 10000 ||
      (!require('internal/options').getOptionValue('--pending-deprecation') &&
       isInsideNodeModules())) {
    // We don't emit a warning, because we either:
    // - Already did so, or
    // - Already checked too many times whether a call is coming
    //   from node_modules and want to stop slowing down things, or
    // - We aren't running with `--pending-deprecation` enabled,
    //   and the code is inside `node_modules`.
    return;
  }

  process.emitWarning(bufferWarning, 'DeprecationWarning', 'DEP0005');
  bufferWarningAlreadyEmitted = true;
}

function toInteger(n, defaultVal) {
  n = +n;
  if (!NumberIsNaN(n) &&
      n >= NumberMIN_SAFE_INTEGER &&
      n <= NumberMAX_SAFE_INTEGER) {
    return ((n % 1) === 0 ? n : MathFloor(n));
  }
  return defaultVal;
}

function _copy(source, target, targetStart, sourceStart, sourceEnd) {
  if (!isUint8Array(source))
    throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source);
  if (!isUint8Array(target))
    throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target);

  if (targetStart === undefined) {
    targetStart = 0;
  } else {
    targetStart = toInteger(targetStart, 0);
    if (targetStart < 0)
      throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart);
  }

  if (sourceStart === undefined) {
    sourceStart = 0;
  } else {
    sourceStart = toInteger(sourceStart, 0);
    if (sourceStart < 0 || sourceStart > source.length)
      throw new ERR_OUT_OF_RANGE('sourceStart', `>= 0 && <= ${source.length}`, sourceStart);
  }

  if (sourceEnd === undefined) {
    sourceEnd = source.length;
  } else {
    sourceEnd = toInteger(sourceEnd, 0);
    if (sourceEnd < 0)
      throw new ERR_OUT_OF_RANGE('sourceEnd', '>= 0', sourceEnd);
  }

  if (targetStart >= target.length || sourceStart >= sourceEnd)
    return 0;

  return _copyActual(source, target, targetStart, sourceStart, sourceEnd);
}

function _copyActual(source, target, targetStart, sourceStart, sourceEnd) {
  if (sourceEnd - sourceStart > target.length - targetStart)
    sourceEnd = sourceStart + target.length - targetStart;

  let nb = sourceEnd - sourceStart;
  const sourceLen = source.length - sourceStart;
  if (nb > sourceLen)
    nb = sourceLen;

  if (sourceStart !== 0 || sourceEnd < source.length)
    source = new Uint8Array(source.buffer, source.byteOffset + sourceStart, nb);

  TypedArrayPrototypeSet(target, source, targetStart);

  return nb;
}

/**
 * The Buffer() constructor is deprecated in documentation and should not be
 * used moving forward. Rather, developers should use one of the three new
 * factory APIs: Buffer.from(), Buffer.allocUnsafe() or Buffer.alloc() based on
 * their specific needs. There is no runtime deprecation because of the extent
 * to which the Buffer constructor is used in the ecosystem currently -- a
 * runtime deprecation would introduce too much breakage at this time. It's not
 * likely that the Buffer constructors would ever actually be removed.
 * Deprecation Code: DEP0005
 */
function Buffer(arg, encodingOrOffset, length) {
  showFlaggedDeprecation();
  // Common case.
  if (typeof arg === 'number') {
    if (typeof encodingOrOffset === 'string') {
      throw new ERR_INVALID_ARG_TYPE('string', 'string', arg);
    }
    return Buffer.alloc(arg);
  }
  return Buffer.from(arg, encodingOrOffset, length);
}

ObjectDefineProperty(Buffer, SymbolSpecies, {
  __proto__: null,
  enumerable: false,
  configurable: true,
  get() { return FastBuffer; },
});

/**
 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
 * if value is a number.
 * Buffer.from(str[, encoding])
 * Buffer.from(array)
 * Buffer.from(buffer)
 * Buffer.from(arrayBuffer[, byteOffset[, length]])
 */
Buffer.from = function from(value, encodingOrOffset, length) {
  if (typeof value === 'string')
    return fromString(value, encodingOrOffset);

  if (typeof value === 'object' && value !== null) {
    if (isAnyArrayBuffer(value))
      return fromArrayBuffer(value, encodingOrOffset, length);

    const valueOf = value.valueOf && value.valueOf();
    if (valueOf != null &&
        valueOf !== value &&
        (typeof valueOf === 'string' || typeof valueOf === 'object')) {
      return from(valueOf, encodingOrOffset, length);
    }

    const b = fromObject(value);
    if (b)
      return b;

    if (typeof value[SymbolToPrimitive] === 'function') {
      const primitive = value[SymbolToPrimitive]('string');
      if (typeof primitive === 'string') {
        return fromString(primitive, encodingOrOffset);
      }
    }
  }

  throw new ERR_INVALID_ARG_TYPE(
    'first argument',
    ['string', 'Buffer', 'ArrayBuffer', 'Array', 'Array-like Object'],
    value,
  );
};

/**
 * Creates the Buffer as a copy of the underlying ArrayBuffer of the view
 * rather than the contents of the view.
 * @param {TypedArray} view
 * @param {number} [offset]
 * @param {number} [length]
 * @returns {Buffer}
 */
Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
  if (!isTypedArray(view)) {
    throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view);
  }

  const viewLength = TypedArrayPrototypeGetLength(view);
  if (viewLength === 0) {
    return Buffer.alloc(0);
  }

  if (offset !== undefined || length !== undefined) {
    if (offset !== undefined) {
      validateInteger(offset, 'offset', 0);
      if (offset >= viewLength) return Buffer.alloc(0);
    } else {
      offset = 0;
    }
    let end;
    if (length !== undefined) {
      validateInteger(length, 'length', 0);
      end = offset + length;
    } else {
      end = viewLength;
    }

    view = TypedArrayPrototypeSlice(view, offset, end);
  }

  return fromArrayLike(new Uint8Array(
    TypedArrayPrototypeGetBuffer(view),
    TypedArrayPrototypeGetByteOffset(view),
    TypedArrayPrototypeGetByteLength(view)));
};

// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
// Buffer() constructor. Must use arrow function syntax to avoid automatically
// adding a `prototype` property and making the function a constructor.
//
// Refs: https://tc39.github.io/ecma262/#sec-%typedarray%.of
// Refs: https://esdiscuss.org/topic/isconstructor#content-11
const of = (...items) => {
  const newObj = createUnsafeBuffer(items.length);
  for (let k = 0; k < items.length; k++)
    newObj[k] = items[k];
  return newObj;
};
Buffer.of = of;

ObjectSetPrototypeOf(Buffer, Uint8Array);

// The 'assertSize' method will remove itself from the callstack when an error
// occurs. This is done simply to keep the internal details of the
// implementation from bleeding out to users.
const assertSize = hideStackFrames((size) => {
  validateNumber(size, 'size');
  if (!(size >= 0 && size <= kMaxLength)) {
    throw new ERR_INVALID_ARG_VALUE.RangeError('size', size);
  }
});

/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 */
Buffer.alloc = function alloc(size, fill, encoding) {
  assertSize(size);
  if (fill !== undefined && fill !== 0 && size > 0) {
    const buf = createUnsafeBuffer(size);
    return _fill(buf, fill, 0, buf.length, encoding);
  }
  return new FastBuffer(size);
};

/**
 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer
 * instance. If `--zero-fill-buffers` is set, will zero-fill the buffer.
 */
Buffer.allocUnsafe = function allocUnsafe(size) {
  assertSize(size);
  return allocate(size);
};

/**
 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled
 * Buffer instance that is not allocated off the pre-initialized pool.
 * If `--zero-fill-buffers` is set, will zero-fill the buffer.
 */
Buffer.allocUnsafeSlow = function allocUnsafeSlow(size) {
  assertSize(size);
  return createUnsafeBuffer(size);
};

// If --zero-fill-buffers command line argument is set, a zero-filled
// buffer is returned.
function SlowBuffer(length) {
  assertSize(length);
  return createUnsafeBuffer(length);
}

ObjectSetPrototypeOf(SlowBuffer.prototype, Uint8ArrayPrototype);
ObjectSetPrototypeOf(SlowBuffer, Uint8Array);

function allocate(size) {
  if (size <= 0) {
    return new FastBuffer();
  }
  if (size < (Buffer.poolSize >>> 1)) {
    if (size > (poolSize - poolOffset))
      createPool();
    const b = new FastBuffer(allocPool, poolOffset, size);
    poolOffset += size;
    alignPool();
    return b;
  }
  return createUnsafeBuffer(size);
}

function fromStringFast(string, ops) {
  const length = ops.byteLength(string);

  if (length >= (Buffer.poolSize >>> 1))
    return createFromString(string, ops.encodingVal);

  if (length > (poolSize - poolOffset))
    createPool();
  let b = new FastBuffer(allocPool, poolOffset, length);
  const actual = ops.write(b, string, 0, length);
  if (actual !== length) {
    // byteLength() may overestimate. That's a rare case, though.
    b = new FastBuffer(allocPool, poolOffset, actual);
  }
  poolOffset += actual;
  alignPool();
  return b;
}

function fromString(string, encoding) {
  let ops;
  if (typeof encoding !== 'string' || encoding.length === 0) {
    if (string.length === 0)
      return new FastBuffer();
    ops = encodingOps.utf8;
    encoding = undefined;
  } else {
    ops = getEncodingOps(encoding);
    if (ops === undefined)
      throw new ERR_UNKNOWN_ENCODING(encoding);
    if (string.length === 0)
      return new FastBuffer();
  }
  return fromStringFast(string, ops);
}

function fromArrayBuffer(obj, byteOffset, length) {
  // Convert byteOffset to integer
  if (byteOffset === undefined) {
    byteOffset = 0;
  } else {
    byteOffset = +byteOffset;
    if (NumberIsNaN(byteOffset))
      byteOffset = 0;
  }

  const maxLength = obj.byteLength - byteOffset;

  if (maxLength < 0)
    throw new ERR_BUFFER_OUT_OF_BOUNDS('offset');

  if (length === undefined) {
    length = maxLength;
  } else {
    // Convert length to non-negative integer.
    length = +length;
    if (length > 0) {
      if (length > maxLength)
        throw new ERR_BUFFER_OUT_OF_BOUNDS('length');
    } else {
      length = 0;
    }
  }

  return new FastBuffer(obj, byteOffset, length);
}

function fromArrayLike(obj) {
  if (obj.length <= 0)
    return new FastBuffer();
  if (obj.length < (Buffer.poolSize >>> 1)) {
    if (obj.length > (poolSize - poolOffset))
      createPool();
    const b = new FastBuffer(allocPool, poolOffset, obj.length);
    TypedArrayPrototypeSet(b, obj, 0);
    poolOffset += obj.length;
    alignPool();
    return b;
  }
  return new FastBuffer(obj);
}

function fromObject(obj) {
  if (obj.length !== undefined || isAnyArrayBuffer(obj.buffer)) {
    if (typeof obj.length !== 'number') {
      return new FastBuffer();
    }
    return fromArrayLike(obj);
  }

  if (obj.type === 'Buffer' && ArrayIsArray(obj.data)) {
    return fromArrayLike(obj.data);
  }
}

// Static methods

Buffer.isBuffer = function isBuffer(b) {
  return b instanceof Buffer;
};

Buffer.compare = function compare(buf1, buf2) {
  if (!isUint8Array(buf1)) {
    throw new ERR_INVALID_ARG_TYPE('buf1', ['Buffer', 'Uint8Array'], buf1);
  }

  if (!isUint8Array(buf2)) {
    throw new ERR_INVALID_ARG_TYPE('buf2', ['Buffer', 'Uint8Array'], buf2);
  }

  if (buf1 === buf2) {
    return 0;
  }

  return _compare(buf1, buf2);
};

Buffer.isEncoding = function isEncoding(encoding) {
  return typeof encoding === 'string' && encoding.length !== 0 &&
         normalizeEncoding(encoding) !== undefined;
};
Buffer[kIsEncodingSymbol] = Buffer.isEncoding;

Buffer.concat = function concat(list, length) {
  validateArray(list, 'list');

  if (list.length === 0)
    return new FastBuffer();

  if (length === undefined) {
    length = 0;
    for (let i = 0; i < list.length; i++) {
      if (list[i].length) {
        length += list[i].length;
      }
    }
  } else {
    validateOffset(length, 'length');
  }

  const buffer = Buffer.allocUnsafe(length);
  let pos = 0;
  for (let i = 0; i < list.length; i++) {
    const buf = list[i];
    if (!isUint8Array(buf)) {
      // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
      // Instead, find the proper error code for this.
      throw new ERR_INVALID_ARG_TYPE(
        `list[${i}]`, ['Buffer', 'Uint8Array'], list[i]);
    }
    pos += _copyActual(buf, buffer, pos, 0, buf.length);
  }

  // Note: `length` is always equal to `buffer.length` at this point
  if (pos < length) {
    // Zero-fill the remaining bytes if the specified `length` was more than
    // the actual total length, i.e. if we have some remaining allocated bytes
    // there were not initialized.
    TypedArrayPrototypeFill(buffer, 0, pos, length);
  }

  return buffer;
};

function base64ByteLength(str, bytes) {
  // Handle padding
  if (StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D)
    bytes--;
  if (bytes > 1 && StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D)
    bytes--;

  // Base64 ratio: 3/4
  return (bytes * 3) >>> 2;
}

const encodingOps = {
  utf8: {
    encoding: 'utf8',
    encodingVal: encodingsMap.utf8,
    byteLength: byteLengthUtf8,
    write: (buf, string, offset, len) => buf.utf8Write(string, offset, len),
    slice: (buf, start, end) => buf.utf8Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir),
  },
  ucs2: {
    encoding: 'ucs2',
    encodingVal: encodingsMap.utf16le,
    byteLength: (string) => string.length * 2,
    write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len),
    slice: (buf, start, end) => buf.ucs2Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir),
  },
  utf16le: {
    encoding: 'utf16le',
    encodingVal: encodingsMap.utf16le,
    byteLength: (string) => string.length * 2,
    write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len),
    slice: (buf, start, end) => buf.ucs2Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir),
  },
  latin1: {
    encoding: 'latin1',
    encodingVal: encodingsMap.latin1,
    byteLength: (string) => string.length,
    write: (buf, string, offset, len) => buf.latin1Write(string, offset, len),
    slice: (buf, start, end) => buf.latin1Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir),
  },
  ascii: {
    encoding: 'ascii',
    encodingVal: encodingsMap.ascii,
    byteLength: (string) => string.length,
    write: (buf, string, offset, len) => buf.asciiWrite(string, offset, len),
    slice: (buf, start, end) => buf.asciiSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.ascii),
                    byteOffset,
                    encodingsMap.ascii,
                    dir),
  },
  base64: {
    encoding: 'base64',
    encodingVal: encodingsMap.base64,
    byteLength: (string) => base64ByteLength(string, string.length),
    write: (buf, string, offset, len) => buf.base64Write(string, offset, len),
    slice: (buf, start, end) => buf.base64Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.base64),
                    byteOffset,
                    encodingsMap.base64,
                    dir),
  },
  base64url: {
    encoding: 'base64url',
    encodingVal: encodingsMap.base64url,
    byteLength: (string) => base64ByteLength(string, string.length),
    write: (buf, string, offset, len) =>
      buf.base64urlWrite(string, offset, len),
    slice: (buf, start, end) => buf.base64urlSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.base64url),
                    byteOffset,
                    encodingsMap.base64url,
                    dir),
  },
  hex: {
    encoding: 'hex',
    encodingVal: encodingsMap.hex,
    byteLength: (string) => string.length >>> 1,
    write: (buf, string, offset, len) => buf.hexWrite(string, offset, len),
    slice: (buf, start, end) => buf.hexSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.hex),
                    byteOffset,
                    encodingsMap.hex,
                    dir),
  },
};
function getEncodingOps(encoding) {
  encoding += '';
  switch (encoding.length) {
    case 4:
      if (encoding === 'utf8') return encodingOps.utf8;
      if (encoding === 'ucs2') return encodingOps.ucs2;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'utf8') return encodingOps.utf8;
      if (encoding === 'ucs2') return encodingOps.ucs2;
      break;
    case 5:
      if (encoding === 'utf-8') return encodingOps.utf8;
      if (encoding === 'ascii') return encodingOps.ascii;
      if (encoding === 'ucs-2') return encodingOps.ucs2;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'utf-8') return encodingOps.utf8;
      if (encoding === 'ascii') return encodingOps.ascii;
      if (encoding === 'ucs-2') return encodingOps.ucs2;
      break;
    case 7:
      if (encoding === 'utf16le' ||
          StringPrototypeToLowerCase(encoding) === 'utf16le')
        return encodingOps.utf16le;
      break;
    case 8:
      if (encoding === 'utf-16le' ||
          StringPrototypeToLowerCase(encoding) === 'utf-16le')
        return encodingOps.utf16le;
      break;
    case 6:
      if (encoding === 'latin1' || encoding === 'binary')
        return encodingOps.latin1;
      if (encoding === 'base64') return encodingOps.base64;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'latin1' || encoding === 'binary')
        return encodingOps.latin1;
      if (encoding === 'base64') return encodingOps.base64;
      break;
    case 3:
      if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex')
        return encodingOps.hex;
      break;
    case 9:
      if (encoding === 'base64url' ||
          StringPrototypeToLowerCase(encoding) === 'base64url')
        return encodingOps.base64url;
      break;
  }
}

function byteLength(string, encoding) {
  if (typeof string !== 'string') {
    if (isArrayBufferView(string) || isAnyArrayBuffer(string)) {
      return string.byteLength;
    }

    throw new ERR_INVALID_ARG_TYPE(
      'string', ['string', 'Buffer', 'ArrayBuffer'], string,
    );
  }

  const len = string.length;
  if (len === 0)
    return 0;

  if (encoding) {
    const ops = getEncodingOps(encoding);
    if (ops) {
      return ops.byteLength(string);
    }
  }
  return byteLengthUtf8(string);
}

Buffer.byteLength = byteLength;

// For backwards compatibility.
ObjectDefineProperty(Buffer.prototype, 'parent', {
  __proto__: null,
  enumerable: true,
  get() {
    if (!(this instanceof Buffer))
      return undefined;
    return this.buffer;
  },
});
ObjectDefineProperty(Buffer.prototype, 'offset', {
  __proto__: null,
  enumerable: true,
  get() {
    if (!(this instanceof Buffer))
      return undefined;
    return this.byteOffset;
  },
});

Buffer.prototype.copy =
  function copy(target, targetStart, sourceStart, sourceEnd) {
    return _copy(this, target, targetStart, sourceStart, sourceEnd);
  };

// No need to verify that "buf.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
Buffer.prototype.toString = function toString(encoding, start, end) {
  if (arguments.length === 0) {
    return this.utf8Slice(0, this.length);
  }

  const len = this.length;

  if (start <= 0)
    start = 0;
  else if (start >= len)
    return '';
  else
    start |= 0;

  if (end === undefined || end > len)
    end = len;
  else
    end |= 0;

  if (end <= start)
    return '';

  if (encoding === undefined)
    return this.utf8Slice(start, end);

  const ops = getEncodingOps(encoding);
  if (ops === undefined)
    throw new ERR_UNKNOWN_ENCODING(encoding);

  return ops.slice(this, start, end);
};

Buffer.prototype.equals = function equals(otherBuffer) {
  if (!isUint8Array(otherBuffer)) {
    throw new ERR_INVALID_ARG_TYPE(
      'otherBuffer', ['Buffer', 'Uint8Array'], otherBuffer);
  }

  if (this === otherBuffer)
    return true;

  if (this.byteLength !== otherBuffer.byteLength)
    return false;

  return this.byteLength === 0 || _compare(this, otherBuffer) === 0;
};

let INSPECT_MAX_BYTES = 50;
// Override how buffers are presented by util.inspect().
Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) {
  const max = INSPECT_MAX_BYTES;
  const actualMax = MathMin(max, this.length);
  const remaining = this.length - max;
  let str = StringPrototypeTrim(RegExpPrototypeSymbolReplace(
    /(.{2})/g, this.hexSlice(0, actualMax), '$1 '));
  if (remaining > 0)
    str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`;
  // Inspect special properties as well, if possible.
  if (ctx) {
    let extras = false;
    const filter = ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE;
    const obj = ObjectCreate(null);
    ArrayPrototypeForEach(getOwnNonIndexProperties(this, filter),
                          (key) => {
                            extras = true;
                            obj[key] = this[key];
                          });
    if (extras) {
      if (this.length !== 0)
        str += ', ';
      // '[Object: null prototype] {'.length === 26
      // This is guarded with a test.
      str += StringPrototypeSlice(utilInspect(obj, {
        ...ctx,
        breakLength: Infinity,
        compact: true,
      }), 27, -2);
    }
  }
  return `<${this.constructor.name} ${str}>`;
};
Buffer.prototype.inspect = Buffer.prototype[customInspectSymbol];

Buffer.prototype.compare = function compare(target,
                                            targetStart,
                                            targetEnd,
                                            sourceStart,
                                            sourceEnd) {
  if (!isUint8Array(target)) {
    throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target);
  }
  if (arguments.length === 1)
    return _compare(this, target);

  if (targetStart === undefined)
    targetStart = 0;
  else
    validateOffset(targetStart, 'targetStart');

  if (targetEnd === undefined)
    targetEnd = target.length;
  else
    validateOffset(targetEnd, 'targetEnd', 0, target.length);

  if (sourceStart === undefined)
    sourceStart = 0;
  else
    validateOffset(sourceStart, 'sourceStart');

  if (sourceEnd === undefined)
    sourceEnd = this.length;
  else
    validateOffset(sourceEnd, 'sourceEnd', 0, this.length);

  if (sourceStart >= sourceEnd)
    return (targetStart >= targetEnd ? 0 : -1);
  if (targetStart >= targetEnd)
    return 1;

  return compareOffset(this, target, targetStart, sourceStart, targetEnd,
                       sourceEnd);
};

// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant if val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
  validateBuffer(buffer);

  if (typeof byteOffset === 'string') {
    encoding = byteOffset;
    byteOffset = undefined;
  } else if (byteOffset > 0x7fffffff) {
    byteOffset = 0x7fffffff;
  } else if (byteOffset < -0x80000000) {
    byteOffset = -0x80000000;
  }
  // Coerce to Number. Values like null and [] become 0.
  byteOffset = +byteOffset;
  // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer.
  if (NumberIsNaN(byteOffset)) {
    byteOffset = dir ? 0 : (buffer.length || buffer.byteLength);
  }
  dir = !!dir;  // Cast to bool.

  if (typeof val === 'number')
    return indexOfNumber(buffer, val >>> 0, byteOffset, dir);

  let ops;
  if (encoding === undefined)
    ops = encodingOps.utf8;
  else
    ops = getEncodingOps(encoding);

  if (typeof val === 'string') {
    if (ops === undefined)
      throw new ERR_UNKNOWN_ENCODING(encoding);
    return ops.indexOf(buffer, val, byteOffset, dir);
  }

  if (isUint8Array(val)) {
    const encodingVal =
      (ops === undefined ? encodingsMap.utf8 : ops.encodingVal);
    return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir);
  }

  throw new ERR_INVALID_ARG_TYPE(
    'value', ['number', 'string', 'Buffer', 'Uint8Array'], val,
  );
}

Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
};

Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
};

Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
  return this.indexOf(val, byteOffset, encoding) !== -1;
};

// Usage:
//    buffer.fill(number[, offset[, end]])
//    buffer.fill(buffer[, offset[, end]])
//    buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill(value, offset, end, encoding) {
  return _fill(this, value, offset, end, encoding);
};

function _fill(buf, value, offset, end, encoding) {
  if (typeof value === 'string') {
    if (offset === undefined || typeof offset === 'string') {
      encoding = offset;
      offset = 0;
      end = buf.length;
    } else if (typeof end === 'string') {
      encoding = end;
      end = buf.length;
    }

    const normalizedEncoding = normalizeEncoding(encoding);
    if (normalizedEncoding === undefined) {
      validateString(encoding, 'encoding');
      throw new ERR_UNKNOWN_ENCODING(encoding);
    }

    if (value.length === 0) {
      // If value === '' default to zero.
      value = 0;
    } else if (value.length === 1) {
      // Fast path: If `value` fits into a single byte, use that numeric value.
      if (normalizedEncoding === 'utf8') {
        const code = StringPrototypeCharCodeAt(value, 0);
        if (code < 128) {
          value = code;
        }
      } else if (normalizedEncoding === 'latin1') {
        value = StringPrototypeCharCodeAt(value, 0);
      }
    }
  } else {
    encoding = undefined;
  }

  if (offset === undefined) {
    offset = 0;
    end = buf.length;
  } else {
    validateOffset(offset, 'offset');
    // Invalid ranges are not set to a default, so can range check early.
    if (end === undefined) {
      end = buf.length;
    } else {
      validateOffset(end, 'end', 0, buf.length);
    }
    if (offset >= end)
      return buf;
  }


  if (typeof value === 'number') {
    // OOB check
    const byteLen = TypedArrayPrototypeGetByteLength(buf);
    const fillLength = end - offset;
    if (offset > end || fillLength + offset > byteLen)
      throw new ERR_BUFFER_OUT_OF_BOUNDS();

    TypedArrayPrototypeFill(buf, value, offset, end);
  } else {
    const res = bindingFill(buf, value, offset, end, encoding);
    if (res < 0) {
      if (res === -1)
        throw new ERR_INVALID_ARG_VALUE('value', value);
      throw new ERR_BUFFER_OUT_OF_BOUNDS();
    }
  }

  return buf;
}

Buffer.prototype.write = function write(string, offset, length, encoding) {
  // Buffer#write(string);
  if (offset === undefined) {
    return this.utf8Write(string, 0, this.length);
  }
  // Buffer#write(string, encoding)
  if (length === undefined && typeof offset === 'string') {
    encoding = offset;
    length = this.length;
    offset = 0;

  // Buffer#write(string, offset[, length][, encoding])
  } else {
    validateOffset(offset, 'offset', 0, this.length);

    const remaining = this.length - offset;

    if (length === undefined) {
      length = remaining;
    } else if (typeof length === 'string') {
      encoding = length;
      length = remaining;
    } else {
      validateOffset(length, 'length', 0, this.length);
      if (length > remaining)
        length = remaining;
    }
  }

  if (!encoding)
    return this.utf8Write(string, offset, length);

  const ops = getEncodingOps(encoding);
  if (ops === undefined)
    throw new ERR_UNKNOWN_ENCODING(encoding);
  return ops.write(this, string, offset, length);
};

Buffer.prototype.toJSON = function toJSON() {
  if (this.length > 0) {
    const data = new Array(this.length);
    for (let i = 0; i < this.length; ++i)
      data[i] = this[i];
    return { type: 'Buffer', data };
  }
  return { type: 'Buffer', data: [] };
};

function adjustOffset(offset, length) {
  // Use Math.trunc() to convert offset to an integer value that can be larger
  // than an Int32. Hence, don't use offset | 0 or similar techniques.
  offset = MathTrunc(offset);
  if (offset === 0) {
    return 0;
  }
  if (offset < 0) {
    offset += length;
    return offset > 0 ? offset : 0;
  }
  if (offset < length) {
    return offset;
  }
  return NumberIsNaN(offset) ? 0 : length;
}

Buffer.prototype.subarray = function subarray(start, end) {
  const srcLength = this.length;
  start = adjustOffset(start, srcLength);
  end = end !== undefined ? adjustOffset(end, srcLength) : srcLength;
  const newLength = end > start ? end - start : 0;
  return new FastBuffer(this.buffer, this.byteOffset + start, newLength);
};

Buffer.prototype.slice = function slice(start, end) {
  return this.subarray(start, end);
};

function swap(b, n, m) {
  const i = b[n];
  b[n] = b[m];
  b[m] = i;
}

Buffer.prototype.swap16 = function swap16() {
  // For Buffer.length < 128, it's generally faster to
  // do the swap in javascript. For larger buffers,
  // dropping down to the native code is faster.
  const len = this.length;
  if (len % 2 !== 0)
    throw new ERR_INVALID_BUFFER_SIZE('16-bits');
  if (len < 128) {
    for (let i = 0; i < len; i += 2)
      swap(this, i, i + 1);
    return this;
  }
  return _swap16(this);
};

Buffer.prototype.swap32 = function swap32() {
  // For Buffer.length < 192, it's generally faster to
  // do the swap in javascript. For larger buffers,
  // dropping down to the native code is faster.
  const len = this.length;
  if (len % 4 !== 0)
    throw new ERR_INVALID_BUFFER_SIZE('32-bits');
  if (len < 192) {
    for (let i = 0; i < len; i += 4) {
      swap(this, i, i + 3);
      swap(this, i + 1, i + 2);
    }
    return this;
  }
  return _swap32(this);
};

Buffer.prototype.swap64 = function swap64() {
  // For Buffer.length < 192, it's generally faster to
  // do the swap in javascript. For larger buffers,
  // dropping down to the native code is faster.
  const len = this.length;
  if (len % 8 !== 0)
    throw new ERR_INVALID_BUFFER_SIZE('64-bits');
  if (len < 192) {
    for (let i = 0; i < len; i += 8) {
      swap(this, i, i + 7);
      swap(this, i + 1, i + 6);
      swap(this, i + 2, i + 5);
      swap(this, i + 3, i + 4);
    }
    return this;
  }
  return _swap64(this);
};

Buffer.prototype.toLocaleString = Buffer.prototype.toString;

let transcode;
if (internalBinding('config').hasIntl) {
  const {
    icuErrName,
    transcode: _transcode,
  } = internalBinding('icu');

  // Transcodes the Buffer from one encoding to another, returning a new
  // Buffer instance.
  transcode = function transcode(source, fromEncoding, toEncoding) {
    if (!isUint8Array(source)) {
      throw new ERR_INVALID_ARG_TYPE('source',
                                     ['Buffer', 'Uint8Array'], source);
    }
    if (source.length === 0) return Buffer.alloc(0);

    fromEncoding = normalizeEncoding(fromEncoding) || fromEncoding;
    toEncoding = normalizeEncoding(toEncoding) || toEncoding;
    const result = _transcode(source, fromEncoding, toEncoding);
    if (typeof result !== 'number')
      return result;

    const code = icuErrName(result);
    const err = genericNodeError(
      `Unable to transcode Buffer [${code}]`,
      { code: code, errno: result },
    );
    throw err;
  };
}

function btoa(input) {
  // The implementation here has not been performance optimized in any way and
  // should not be.
  // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932
  if (arguments.length === 0) {
    throw new ERR_MISSING_ARGS('input');
  }
  input = `${input}`;
  for (let n = 0; n < input.length; n++) {
    if (input[n].charCodeAt(0) > 0xff)
      throw lazyDOMException('Invalid character', 'InvalidCharacterError');
  }
  const buf = Buffer.from(input, 'latin1');
  return buf.toString('base64');
}

// Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
const kForgivingBase64AllowedChars = [
  // ASCII whitespace
  // Refs: https://infra.spec.whatwg.org/#ascii-whitespace
  0x09, 0x0A, 0x0C, 0x0D, 0x20,

  // Uppercase letters
  ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('A') + i),

  // Lowercase letters
  ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('a') + i),

  // Decimal digits
  ...ArrayFrom({ length: 10 }, (_, i) => StringPrototypeCharCodeAt('0') + i),

  0x2B, // +
  0x2F, // /
  0x3D, // =
];
const kEqualSignIndex = ArrayPrototypeIndexOf(kForgivingBase64AllowedChars,
                                              0x3D);

function atob(input) {
  // The implementation here has not been performance optimized in any way and
  // should not be.
  // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932
  if (arguments.length === 0) {
    throw new ERR_MISSING_ARGS('input');
  }

  input = `${input}`;
  let nonAsciiWhitespaceCharCount = 0;
  let equalCharCount = 0;

  for (let n = 0; n < input.length; n++) {
    const index = ArrayPrototypeIndexOf(
      kForgivingBase64AllowedChars,
      StringPrototypeCharCodeAt(input, n));

    if (index > 4) {
      // The first 5 elements of `kForgivingBase64AllowedChars` are
      // ASCII whitespace char codes.
      nonAsciiWhitespaceCharCount++;

      if (index === kEqualSignIndex) {
        equalCharCount++;
      } else if (equalCharCount) {
        // The `=` char is only allowed at the end.
        throw lazyDOMException('Invalid character', 'InvalidCharacterError');
      }

      if (equalCharCount > 2) {
        // Only one more `=` is permitted after the first equal sign.
        throw lazyDOMException('Invalid character', 'InvalidCharacterError');
      }
    } else if (index === -1) {
      throw lazyDOMException('Invalid character', 'InvalidCharacterError');
    }
  }

  let reminder = nonAsciiWhitespaceCharCount % 4;

  // See #2, #3, #4 - https://infra.spec.whatwg.org/#forgiving-base64
  if (!reminder) {
    // Remove all trailing `=` characters and get the new reminder.
    reminder = (nonAsciiWhitespaceCharCount - equalCharCount) % 4;
  } else if (equalCharCount) {
    // `=` should not in the input if there's a reminder.
    throw lazyDOMException('Invalid character', 'InvalidCharacterError');
  }

  // See #3 - https://infra.spec.whatwg.org/#forgiving-base64
  if (reminder === 1) {
    throw lazyDOMException(
      'The string to be decoded is not correctly encoded.',
      'InvalidCharacterError');
  }

  return Buffer.from(input, 'base64').toString('latin1');
}

function isUtf8(input) {
  if (isTypedArray(input) || isAnyArrayBuffer(input)) {
    return bindingIsUtf8(input);
  }

  throw new ERR_INVALID_ARG_TYPE('input', ['TypedArray', 'Buffer'], input);
}

function isAscii(input) {
  if (isTypedArray(input) || isAnyArrayBuffer(input)) {
    return bindingIsAscii(input);
  }

  throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input);
}

module.exports = {
  Buffer,
  SlowBuffer,
  transcode,
  isUtf8,
  isAscii,

  // Legacy
  kMaxLength,
  kStringMaxLength,
  btoa,
  atob,
};

ObjectDefineProperties(module.exports, {
  constants: {
    __proto__: null,
    configurable: false,
    enumerable: true,
    value: constants,
  },
  INSPECT_MAX_BYTES: {
    __proto__: null,
    configurable: true,
    enumerable: true,
    get() { return INSPECT_MAX_BYTES; },
    set(val) { INSPECT_MAX_BYTES = val; },
  },
});

defineLazyProperties(
  module.exports,
  'internal/blob',
  ['Blob', 'resolveObjectURL'],
);
defineLazyProperties(
  module.exports,
  'internal/file',
  ['File'],
);
        'use strict';

const {
  ArrayPrototypeIncludes,
  ArrayPrototypeIndexOf,
  ArrayPrototypePush,
  ArrayPrototypeSplice,
  ArrayPrototypeUnshift,
  FunctionPrototypeBind,
  NumberIsSafeInteger,
  ObjectDefineProperties,
  ObjectIs,
  ReflectApply,
  Symbol,
  ObjectFreeze,
} = primordials;

const {
  ERR_ASYNC_CALLBACK,
  ERR_ASYNC_TYPE,
  ERR_INVALID_ASYNC_ID,
} = require('internal/errors').codes;
const { kEmptyObject } = require('internal/util');
const {
  validateFunction,
  validateString,
} = require('internal/validators');
const internal_async_hooks = require('internal/async_hooks');

// Get functions
// For userland AsyncResources, make sure to emit a destroy event when the
// resource gets gced.
const { registerDestroyHook } = internal_async_hooks;
const {
  asyncWrap,
  executionAsyncId,
  triggerAsyncId,
  // Private API
  hasAsyncIdStack,
  getHookArrays,
  enableHooks,
  disableHooks,
  updatePromiseHookMode,
  executionAsyncResource,
  // Internal Embedder API
  newAsyncId,
  getDefaultTriggerAsyncId,
  emitInit,
  emitBefore,
  emitAfter,
  emitDestroy,
  enabledHooksExist,
  initHooksExist,
  destroyHooksExist,
} = internal_async_hooks;

// Get symbols
const {
  async_id_symbol, trigger_async_id_symbol,
  init_symbol, before_symbol, after_symbol, destroy_symbol,
  promise_resolve_symbol,
} = internal_async_hooks.symbols;

// Get constants
const {
  kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve,
} = internal_async_hooks.constants;

// Listener API //

class AsyncHook {
  constructor({ init, before, after, destroy, promiseResolve }) {
    if (init !== undefined && typeof init !== 'function')
      throw new ERR_ASYNC_CALLBACK('hook.init');
    if (before !== undefined && typeof before !== 'function')
      throw new ERR_ASYNC_CALLBACK('hook.before');
    if (after !== undefined && typeof after !== 'function')
      throw new ERR_ASYNC_CALLBACK('hook.after');
    if (destroy !== undefined && typeof destroy !== 'function')
      throw new ERR_ASYNC_CALLBACK('hook.destroy');
    if (promiseResolve !== undefined && typeof promiseResolve !== 'function')
      throw new ERR_ASYNC_CALLBACK('hook.promiseResolve');

    this[init_symbol] = init;
    this[before_symbol] = before;
    this[after_symbol] = after;
    this[destroy_symbol] = destroy;
    this[promise_resolve_symbol] = promiseResolve;
  }

  enable() {
    // The set of callbacks for a hook should be the same regardless of whether
    // enable()/disable() are run during their execution. The following
    // references are reassigned to the tmp arrays if a hook is currently being
    // processed.
    const { 0: hooks_array, 1: hook_fields } = getHookArrays();

    // Each hook is only allowed to be added once.
    if (ArrayPrototypeIncludes(hooks_array, this))
      return this;

    const prev_kTotals = hook_fields[kTotals];

    // createHook() has already enforced that the callbacks are all functions,
    // so here simply increment the count of whether each callbacks exists or
    // not.
    hook_fields[kTotals] = hook_fields[kInit] += +!!this[init_symbol];
    hook_fields[kTotals] += hook_fields[kBefore] += +!!this[before_symbol];
    hook_fields[kTotals] += hook_fields[kAfter] += +!!this[after_symbol];
    hook_fields[kTotals] += hook_fields[kDestroy] += +!!this[destroy_symbol];
    hook_fields[kTotals] +=
        hook_fields[kPromiseResolve] += +!!this[promise_resolve_symbol];
    ArrayPrototypePush(hooks_array, this);

    if (prev_kTotals === 0 && hook_fields[kTotals] > 0) {
      enableHooks();
    }

    updatePromiseHookMode();

    return this;
  }

  disable() {
    const { 0: hooks_array, 1: hook_fields } = getHookArrays();

    const index = ArrayPrototypeIndexOf(hooks_array, this);
    if (index === -1)
      return this;

    const prev_kTotals = hook_fields[kTotals];

    hook_fields[kTotals] = hook_fields[kInit] -= +!!this[init_symbol];
    hook_fields[kTotals] += hook_fields[kBefore] -= +!!this[before_symbol];
    hook_fields[kTotals] += hook_fields[kAfter] -= +!!this[after_symbol];
    hook_fields[kTotals] += hook_fields[kDestroy] -= +!!this[destroy_symbol];
    hook_fields[kTotals] +=
        hook_fields[kPromiseResolve] -= +!!this[promise_resolve_symbol];
    ArrayPrototypeSplice(hooks_array, index, 1);

    if (prev_kTotals > 0 && hook_fields[kTotals] === 0) {
      disableHooks();
    }

    return this;
  }
}


function createHook(fns) {
  return new AsyncHook(fns);
}


// Embedder API //

const destroyedSymbol = Symbol('destroyed');

class AsyncResource {
  constructor(type, opts = kEmptyObject) {
    validateString(type, 'type');

    let triggerAsyncId = opts;
    let requireManualDestroy = false;
    if (typeof opts !== 'number') {
      triggerAsyncId = opts.triggerAsyncId === undefined ?
        getDefaultTriggerAsyncId() : opts.triggerAsyncId;
      requireManualDestroy = !!opts.requireManualDestroy;
    }

    // Unlike emitInitScript, AsyncResource doesn't supports null as the
    // triggerAsyncId.
    if (!NumberIsSafeInteger(triggerAsyncId) || triggerAsyncId < -1) {
      throw new ERR_INVALID_ASYNC_ID('triggerAsyncId', triggerAsyncId);
    }

    const asyncId = newAsyncId();
    this[async_id_symbol] = asyncId;
    this[trigger_async_id_symbol] = triggerAsyncId;

    if (initHooksExist()) {
      if (enabledHooksExist() && type.length === 0) {
        throw new ERR_ASYNC_TYPE(type);
      }

      emitInit(asyncId, type, triggerAsyncId, this);
    }

    if (!requireManualDestroy && destroyHooksExist()) {
      // This prop name (destroyed) has to be synchronized with C++
      const destroyed = { destroyed: false };
      this[destroyedSymbol] = destroyed;
      registerDestroyHook(this, asyncId, destroyed);
    }
  }

  runInAsyncScope(fn, thisArg, ...args) {
    const asyncId = this[async_id_symbol];
    emitBefore(asyncId, this[trigger_async_id_symbol], this);

    try {
      const ret =
        ReflectApply(fn, thisArg, args);

      return ret;
    } finally {
      if (hasAsyncIdStack())
        emitAfter(asyncId);
    }
  }

  emitDestroy() {
    if (this[destroyedSymbol] !== undefined) {
      this[destroyedSymbol].destroyed = true;
    }
    emitDestroy(this[async_id_symbol]);
    return this;
  }

  asyncId() {
    return this[async_id_symbol];
  }

  triggerAsyncId() {
    return this[trigger_async_id_symbol];
  }

  bind(fn, thisArg) {
    validateFunction(fn, 'fn');
    let bound;
    if (thisArg === undefined) {
      const resource = this;
      bound = function(...args) {
        ArrayPrototypeUnshift(args, fn, this);
        return ReflectApply(resource.runInAsyncScope, resource, args);
      };
    } else {
      bound = FunctionPrototypeBind(this.runInAsyncScope, this, fn, thisArg);
    }
    ObjectDefineProperties(bound, {
      'length': {
        __proto__: null,
        configurable: true,
        enumerable: false,
        value: fn.length,
        writable: false,
      },
      'asyncResource': {
        __proto__: null,
        configurable: true,
        enumerable: true,
        value: this,
        writable: true,
      },
    });
    return bound;
  }

  static bind(fn, type, thisArg) {
    type = type || fn.name;
    return (new AsyncResource(type || 'bound-anonymous-fn')).bind(fn, thisArg);
  }
}

const storageList = [];
const storageHook = createHook({
  init(asyncId, type, triggerAsyncId, resource) {
    const currentResource = executionAsyncResource();
    // Value of currentResource is always a non null object
    for (let i = 0; i < storageList.length; ++i) {
      storageList[i]._propagate(resource, currentResource, type);
    }
  },
});

class AsyncLocalStorage {
  constructor() {
    this.kResourceStore = Symbol('kResourceStore');
    this.enabled = false;
  }

  static bind(fn) {
    return AsyncResource.bind(fn);
  }

  static snapshot() {
    return AsyncLocalStorage.bind((cb, ...args) => cb(...args));
  }

  disable() {
    if (this.enabled) {
      this.enabled = false;
      // If this.enabled, the instance must be in storageList
      ArrayPrototypeSplice(storageList,
                           ArrayPrototypeIndexOf(storageList, this), 1);
      if (storageList.length === 0) {
        storageHook.disable();
      }
    }
  }

  _enable() {
    if (!this.enabled) {
      this.enabled = true;
      ArrayPrototypePush(storageList, this);
      storageHook.enable();
    }
  }

  // Propagate the context from a parent resource to a child one
  _propagate(resource, triggerResource, type) {
    const store = triggerResource[this.kResourceStore];
    if (this.enabled) {
      resource[this.kResourceStore] = store;
    }
  }

  enterWith(store) {
    this._enable();
    const resource = executionAsyncResource();
    resource[this.kResourceStore] = store;
  }

  run(store, callback, ...args) {
    // Avoid creation of an AsyncResource if store is already active
    if (ObjectIs(store, this.getStore())) {
      return ReflectApply(callback, null, args);
    }

    this._enable();

    const resource = executionAsyncResource();
    const oldStore = resource[this.kResourceStore];

    resource[this.kResourceStore] = store;

    try {
      return ReflectApply(callback, null, args);
    } finally {
      resource[this.kResourceStore] = oldStore;
    }
  }

  exit(callback, ...args) {
    if (!this.enabled) {
      return ReflectApply(callback, null, args);
    }
    this.disable();
    try {
      return ReflectApply(callback, null, args);
    } finally {
      this._enable();
    }
  }

  getStore() {
    if (this.enabled) {
      const resource = executionAsyncResource();
      return resource[this.kResourceStore];
    }
  }
}

// Placing all exports down here because the exported classes won't export
// otherwise.
module.exports = {
  // Public API
  AsyncLocalStorage,
  createHook,
  executionAsyncId,
  triggerAsyncId,
  executionAsyncResource,
  asyncWrapProviders: ObjectFreeze({ __proto__: null, ...asyncWrap.Providers }),
  // Embedder API
  AsyncResource,
};
     'use strict';

module.exports = require('assert').strict;
      // Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ArrayPrototypeIndexOf,
  ArrayPrototypeJoin,
  ArrayPrototypePush,
  ArrayPrototypeShift,
  ArrayPrototypeSlice,
  Error,
  ErrorCaptureStackTrace,
  FunctionPrototypeBind,
  NumberIsNaN,
  ObjectAssign,
  ObjectIs,
  ObjectKeys,
  ObjectPrototypeIsPrototypeOf,
  ReflectApply,
  RegExpPrototypeExec,
  RegExpPrototypeSymbolReplace,
  SafeMap,
  String,
  StringPrototypeCharCodeAt,
  StringPrototypeIncludes,
  StringPrototypeIndexOf,
  StringPrototypeReplace,
  StringPrototypeSlice,
  StringPrototypeSplit,
  StringPrototypeStartsWith,
} = primordials;

const { Buffer } = require('buffer');
const {
  codes: {
    ERR_AMBIGUOUS_ARGUMENT,
    ERR_INVALID_ARG_TYPE,
    ERR_INVALID_ARG_VALUE,
    ERR_INVALID_RETURN_VALUE,
    ERR_MISSING_ARGS,
  },
  isErrorStackTraceLimitWritable,
  overrideStackTrace,
} = require('internal/errors');
const AssertionError = require('internal/assert/assertion_error');
const { openSync, closeSync, readSync } = require('fs');
const { inspect } = require('internal/util/inspect');
const { isPromise, isRegExp } = require('internal/util/types');
const { EOL } = require('internal/constants');
const { BuiltinModule } = require('internal/bootstrap/realm');
const { isError } = require('internal/util');

const errorCache = new SafeMap();
const CallTracker = require('internal/assert/calltracker');
const {
  validateFunction,
} = require('internal/validators');

let isDeepEqual;
let isDeepStrictEqual;
let parseExpressionAt;
let findNodeAround;
let tokenizer;
let decoder;

function lazyLoadComparison() {
  const comparison = require('internal/util/comparisons');
  isDeepEqual = comparison.isDeepEqual;
  isDeepStrictEqual = comparison.isDeepStrictEqual;
}

// Escape control characters but not \n and \t to keep the line breaks and
// indentation intact.
// eslint-disable-next-line no-control-regex
const escapeSequencesRegExp = /[\x00-\x08\x0b\x0c\x0e-\x1f]/g;
const meta = [
  '\\u0000', '\\u0001', '\\u0002', '\\u0003', '\\u0004',
  '\\u0005', '\\u0006', '\\u0007', '\\b', '',
  '', '\\u000b', '\\f', '', '\\u000e',
  '\\u000f', '\\u0010', '\\u0011', '\\u0012', '\\u0013',
  '\\u0014', '\\u0015', '\\u0016', '\\u0017', '\\u0018',
  '\\u0019', '\\u001a', '\\u001b', '\\u001c', '\\u001d',
  '\\u001e', '\\u001f',
];

const escapeFn = (str) => meta[StringPrototypeCharCodeAt(str, 0)];

let warned = false;

// The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

const assert = module.exports = ok;

const NO_EXCEPTION_SENTINEL = {};

// All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided. All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function innerFail(obj) {
  if (obj.message instanceof Error) throw obj.message;

  throw new AssertionError(obj);
}

/**
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @param {string} [operator]
 * @param {Function} [stackStartFn]
 */
function fail(actual, expected, message, operator, stackStartFn) {
  const argsLen = arguments.length;

  let internalMessage = false;
  if (actual == null && argsLen <= 1) {
    internalMessage = true;
    message = 'Failed';
  } else if (argsLen === 1) {
    message = actual;
    actual = undefined;
  } else {
    if (warned === false) {
      warned = true;
      process.emitWarning(
        'assert.fail() with more than one argument is deprecated. ' +
          'Please use assert.strictEqual() instead or only pass a message.',
        'DeprecationWarning',
        'DEP0094',
      );
    }
    if (argsLen === 2)
      operator = '!=';
  }

  if (message instanceof Error) throw message;

  const errArgs = {
    actual,
    expected,
    operator: operator === undefined ? 'fail' : operator,
    stackStartFn: stackStartFn || fail,
    message,
  };
  const err = new AssertionError(errArgs);
  if (internalMessage) {
    err.generatedMessage = true;
  }
  throw err;
}

assert.fail = fail;

// The AssertionError is defined in internal/error.
assert.AssertionError = AssertionError;

function findColumn(fd, column, code) {
  if (code.length > column + 100) {
    try {
      return parseCode(code, column);
    } catch {
      // End recursion in case no code could be parsed. The expression should
      // have been found after 2500 characters, so stop trying.
      if (code.length - column > 2500) {
        // eslint-disable-next-line no-throw-literal
        throw null;
      }
    }
  }
  // Read up to 2500 bytes more than necessary in columns. That way we address
  // multi byte characters and read enough data to parse the code.
  const bytesToRead = column - code.length + 2500;
  const buffer = Buffer.allocUnsafe(bytesToRead);
  const bytesRead = readSync(fd, buffer, 0, bytesToRead);
  code += decoder.write(buffer.slice(0, bytesRead));
  // EOF: fast path.
  if (bytesRead < bytesToRead) {
    return parseCode(code, column);
  }
  // Read potentially missing code.
  return findColumn(fd, column, code);
}

function getCode(fd, line, column) {
  let bytesRead = 0;
  if (line === 0) {
    // Special handle line number one. This is more efficient and simplifies the
    // rest of the algorithm. Read more than the regular column number in bytes
    // to prevent multiple reads in case multi byte characters are used.
    return findColumn(fd, column, '');
  }
  let lines = 0;
  // Prevent blocking the event loop by limiting the maximum amount of
  // data that may be read.
  let maxReads = 32; // bytesPerRead * maxReads = 512 KiB
  const bytesPerRead = 16384;
  // Use a single buffer up front that is reused until the call site is found.
  let buffer = Buffer.allocUnsafe(bytesPerRead);
  while (maxReads-- !== 0) {
    // Only allocate a new buffer in case the needed line is found. All data
    // before that can be discarded.
    buffer = lines < line ? buffer : Buffer.allocUnsafe(bytesPerRead);
    bytesRead = readSync(fd, buffer, 0, bytesPerRead);
    // Read the buffer until the required code line is found.
    for (let i = 0; i < bytesRead; i++) {
      if (buffer[i] === 10 && ++lines === line) {
        // If the end of file is reached, directly parse the code and return.
        if (bytesRead < bytesPerRead) {
          return parseCode(buffer.toString('utf8', i + 1, bytesRead), column);
        }
        // Check if the read code is sufficient or read more until the whole
        // expression is read. Make sure multi byte characters are preserved
        // properly by using the decoder.
        const code = decoder.write(buffer.slice(i + 1, bytesRead));
        return findColumn(fd, column, code);
      }
    }
  }
}

function parseCode(code, offset) {
  // Lazy load acorn.
  if (parseExpressionAt === undefined) {
    const Parser = require('internal/deps/acorn/acorn/dist/acorn').Parser;
    ({ findNodeAround } = require('internal/deps/acorn/acorn-walk/dist/walk'));

    parseExpressionAt = FunctionPrototypeBind(Parser.parseExpressionAt, Parser);
    tokenizer = FunctionPrototypeBind(Parser.tokenizer, Parser);
  }
  let node;
  let start;
  // Parse the read code until the correct expression is found.
  for (const token of tokenizer(code, { ecmaVersion: 'latest' })) {
    start = token.start;
    if (start > offset) {
      // No matching expression found. This could happen if the assert
      // expression is bigger than the provided buffer.
      break;
    }
    try {
      node = parseExpressionAt(code, start, { ecmaVersion: 'latest' });
      // Find the CallExpression in the tree.
      node = findNodeAround(node, offset, 'CallExpression');
      if (node?.node.end >= offset) {
        return [
          node.node.start,
          StringPrototypeReplace(StringPrototypeSlice(code,
                                                      node.node.start, node.node.end),
                                 escapeSequencesRegExp, escapeFn),
        ];
      }
    // eslint-disable-next-line no-unused-vars
    } catch (err) {
      continue;
    }
  }
  // eslint-disable-next-line no-throw-literal
  throw null;
}

function getErrMessage(message, fn) {
  const tmpLimit = Error.stackTraceLimit;
  const errorStackTraceLimitIsWritable = isErrorStackTraceLimitWritable();
  // Make sure the limit is set to 1. Otherwise it could fail (<= 0) or it
  // does to much work.
  if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 1;
  // We only need the stack trace. To minimize the overhead use an object
  // instead of an error.
  const err = {};
  ErrorCaptureStackTrace(err, fn);
  if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit;

  overrideStackTrace.set(err, (_, stack) => stack);
  const call = err.stack[0];

  const filename = call.getFileName();
  const line = call.getLineNumber() - 1;
  let column = call.getColumnNumber() - 1;
  let identifier;
  let code;

  if (filename) {
    identifier = `${filename}${line}${column}`;

    // Skip Node.js modules!
    if (StringPrototypeStartsWith(filename, 'node:') &&
        BuiltinModule.exists(StringPrototypeSlice(filename, 5))) {
      errorCache.set(identifier, undefined);
      return;
    }
  } else {
    return message;
  }

  if (errorCache.has(identifier)) {
    return errorCache.get(identifier);
  }

  let fd;
  try {
    // Set the stack trace limit to zero. This makes sure unexpected token
    // errors are handled faster.
    if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 0;

    if (filename) {
      if (decoder === undefined) {
        const { StringDecoder } = require('string_decoder');
        decoder = new StringDecoder('utf8');
      }
      fd = openSync(filename, 'r', 0o666);
      // Reset column and message.
      ({ 0: column, 1: message } = getCode(fd, line, column));
      // Flush unfinished multi byte characters.
      decoder.end();
    } else {
      for (let i = 0; i < line; i++) {
        code = StringPrototypeSlice(code,
                                    StringPrototypeIndexOf(code, '\n') + 1);
      }
      ({ 0: column, 1: message } = parseCode(code, column));
    }
    // Always normalize indentation, otherwise the message could look weird.
    if (StringPrototypeIncludes(message, '\n')) {
      if (EOL === '\r\n') {
        message = RegExpPrototypeSymbolReplace(/\r\n/g, message, '\n');
      }
      const frames = StringPrototypeSplit(message, '\n');
      message = ArrayPrototypeShift(frames);
      for (const frame of frames) {
        let pos = 0;
        while (pos < column && (frame[pos] === ' ' || frame[pos] === '\t')) {
          pos++;
        }
        message += `\n  ${StringPrototypeSlice(frame, pos)}`;
      }
    }
    message = `The expression evaluated to a falsy value:\n\n  ${message}\n`;
    // Make sure to always set the cache! No matter if the message is
    // undefined or not
    errorCache.set(identifier, message);

    return message;
  } catch {
    // Invalidate cache to prevent trying to read this part again.
    errorCache.set(identifier, undefined);
  } finally {
    // Reset limit.
    if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit;
    if (fd !== undefined)
      closeSync(fd);
  }
}

function innerOk(fn, argLen, value, message) {
  if (!value) {
    let generatedMessage = false;

    if (argLen === 0) {
      generatedMessage = true;
      message = 'No value argument passed to `assert.ok()`';
    } else if (message == null) {
      generatedMessage = true;
      message = getErrMessage(message, fn);
    } else if (message instanceof Error) {
      throw message;
    }

    const err = new AssertionError({
      actual: value,
      expected: true,
      message,
      operator: '==',
      stackStartFn: fn,
    });
    err.generatedMessage = generatedMessage;
    throw err;
  }
}

/**
 * Pure assertion tests whether a value is truthy, as determined
 * by !!value.
 * @param {...any} args
 * @returns {void}
 */
function ok(...args) {
  innerOk(ok, args.length, ...args);
}
assert.ok = ok;

/**
 * The equality assertion tests shallow, coercive equality with ==.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
/* eslint-disable no-restricted-properties */
assert.equal = function equal(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  // eslint-disable-next-line eqeqeq
  if (actual != expected && (!NumberIsNaN(actual) || !NumberIsNaN(expected))) {
    innerFail({
      actual,
      expected,
      message,
      operator: '==',
      stackStartFn: equal,
    });
  }
};

/**
 * The non-equality assertion tests for whether two objects are not
 * equal with !=.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.notEqual = function notEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  // eslint-disable-next-line eqeqeq
  if (actual == expected || (NumberIsNaN(actual) && NumberIsNaN(expected))) {
    innerFail({
      actual,
      expected,
      message,
      operator: '!=',
      stackStartFn: notEqual,
    });
  }
};

/**
 * The deep equivalence assertion tests a deep equality relation.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.deepEqual = function deepEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  if (isDeepEqual === undefined) lazyLoadComparison();
  if (!isDeepEqual(actual, expected)) {
    innerFail({
      actual,
      expected,
      message,
      operator: 'deepEqual',
      stackStartFn: deepEqual,
    });
  }
};

/**
 * The deep non-equivalence assertion tests for any deep inequality.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  if (isDeepEqual === undefined) lazyLoadComparison();
  if (isDeepEqual(actual, expected)) {
    innerFail({
      actual,
      expected,
      message,
      operator: 'notDeepEqual',
      stackStartFn: notDeepEqual,
    });
  }
};
/* eslint-enable */

/**
 * The deep strict equivalence assertion tests a deep strict equality
 * relation.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  if (isDeepEqual === undefined) lazyLoadComparison();
  if (!isDeepStrictEqual(actual, expected)) {
    innerFail({
      actual,
      expected,
      message,
      operator: 'deepStrictEqual',
      stackStartFn: deepStrictEqual,
    });
  }
};

/**
 * The deep strict non-equivalence assertion tests for any deep strict
 * inequality.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.notDeepStrictEqual = notDeepStrictEqual;
function notDeepStrictEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  if (isDeepEqual === undefined) lazyLoadComparison();
  if (isDeepStrictEqual(actual, expected)) {
    innerFail({
      actual,
      expected,
      message,
      operator: 'notDeepStrictEqual',
      stackStartFn: notDeepStrictEqual,
    });
  }
}

/**
 * The strict equivalence assertion tests a strict equality relation.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.strictEqual = function strictEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  if (!ObjectIs(actual, expected)) {
    innerFail({
      actual,
      expected,
      message,
      operator: 'strictEqual',
      stackStartFn: strictEqual,
    });
  }
};

/**
 * The strict non-equivalence assertion tests for any strict inequality.
 * @param {any} actual
 * @param {any} expected
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
  if (arguments.length < 2) {
    throw new ERR_MISSING_ARGS('actual', 'expected');
  }
  if (ObjectIs(actual, expected)) {
    innerFail({
      actual,
      expected,
      message,
      operator: 'notStrictEqual',
      stackStartFn: notStrictEqual,
    });
  }
};

class Comparison {
  constructor(obj, keys, actual) {
    for (const key of keys) {
      if (key in obj) {
        if (actual !== undefined &&
            typeof actual[key] === 'string' &&
            isRegExp(obj[key]) &&
            RegExpPrototypeExec(obj[key], actual[key]) !== null) {
          this[key] = actual[key];
        } else {
          this[key] = obj[key];
        }
      }
    }
  }
}

function compareExceptionKey(actual, expected, key, message, keys, fn) {
  if (!(key in actual) || !isDeepStrictEqual(actual[key], expected[key])) {
    if (!message) {
      // Create placeholder objects to create a nice output.
      const a = new Comparison(actual, keys);
      const b = new Comparison(expected, keys, actual);

      const err = new AssertionError({
        actual: a,
        expected: b,
        operator: 'deepStrictEqual',
        stackStartFn: fn,
      });
      err.actual = actual;
      err.expected = expected;
      err.operator = fn.name;
      throw err;
    }
    innerFail({
      actual,
      expected,
      message,
      operator: fn.name,
      stackStartFn: fn,
    });
  }
}

function expectedException(actual, expected, message, fn) {
  let generatedMessage = false;
  let throwError = false;

  if (typeof expected !== 'function') {
    // Handle regular expressions.
    if (isRegExp(expected)) {
      const str = String(actual);
      if (RegExpPrototypeExec(expected, str) !== null)
        return;

      if (!message) {
        generatedMessage = true;
        message = 'The input did not match the regular expression ' +
                  `${inspect(expected)}. Input:\n\n${inspect(str)}\n`;
      }
      throwError = true;
      // Handle primitives properly.
    } else if (typeof actual !== 'object' || actual === null) {
      const err = new AssertionError({
        actual,
        expected,
        message,
        operator: 'deepStrictEqual',
        stackStartFn: fn,
      });
      err.operator = fn.name;
      throw err;
    } else {
      // Handle validation objects.
      const keys = ObjectKeys(expected);
      // Special handle errors to make sure the name and the message are
      // compared as well.
      if (expected instanceof Error) {
        ArrayPrototypePush(keys, 'name', 'message');
      } else if (keys.length === 0) {
        throw new ERR_INVALID_ARG_VALUE('error',
                                        expected, 'may not be an empty object');
      }
      if (isDeepEqual === undefined) lazyLoadComparison();
      for (const key of keys) {
        if (typeof actual[key] === 'string' &&
            isRegExp(expected[key]) &&
            RegExpPrototypeExec(expected[key], actual[key]) !== null) {
          continue;
        }
        compareExceptionKey(actual, expected, key, message, keys, fn);
      }
      return;
    }
  // Guard instanceof against arrow functions as they don't have a prototype.
  // Check for matching Error classes.
  } else if (expected.prototype !== undefined && actual instanceof expected) {
    return;
  } else if (ObjectPrototypeIsPrototypeOf(Error, expected)) {
    if (!message) {
      generatedMessage = true;
      message = 'The error is expected to be an instance of ' +
        `"${expected.name}". Received `;
      if (isError(actual)) {
        const name = (actual.constructor && actual.constructor.name) ||
                     actual.name;
        if (expected.name === name) {
          message += 'an error with identical name but a different prototype.';
        } else {
          message += `"${name}"`;
        }
        if (actual.message) {
          message += `\n\nError message:\n\n${actual.message}`;
        }
      } else {
        message += `"${inspect(actual, { depth: -1 })}"`;
      }
    }
    throwError = true;
  } else {
    // Check validation functions return value.
    const res = ReflectApply(expected, {}, [actual]);
    if (res !== true) {
      if (!message) {
        generatedMessage = true;
        const name = expected.name ? `"${expected.name}" ` : '';
        message = `The ${name}validation function is expected to return` +
          ` "true". Received ${inspect(res)}`;

        if (isError(actual)) {
          message += `\n\nCaught error:\n\n${actual}`;
        }
      }
      throwError = true;
    }
  }

  if (throwError) {
    const err = new AssertionError({
      actual,
      expected,
      message,
      operator: fn.name,
      stackStartFn: fn,
    });
    err.generatedMessage = generatedMessage;
    throw err;
  }
}

function getActual(fn) {
  validateFunction(fn, 'fn');
  try {
    fn();
  } catch (e) {
    return e;
  }
  return NO_EXCEPTION_SENTINEL;
}

function checkIsPromise(obj) {
  // Accept native ES6 promises and promises that are implemented in a similar
  // way. Do not accept thenables that use a function as `obj` and that have no
  // `catch` handler.
  return isPromise(obj) ||
    (obj !== null && typeof obj === 'object' &&
    typeof obj.then === 'function' &&
    typeof obj.catch === 'function');
}

async function waitForActual(promiseFn) {
  let resultPromise;
  if (typeof promiseFn === 'function') {
    // Return a rejected promise if `promiseFn` throws synchronously.
    resultPromise = promiseFn();
    // Fail in case no promise is returned.
    if (!checkIsPromise(resultPromise)) {
      throw new ERR_INVALID_RETURN_VALUE('instance of Promise',
                                         'promiseFn', resultPromise);
    }
  } else if (checkIsPromise(promiseFn)) {
    resultPromise = promiseFn;
  } else {
    throw new ERR_INVALID_ARG_TYPE(
      'promiseFn', ['Function', 'Promise'], promiseFn);
  }

  try {
    await resultPromise;
  } catch (e) {
    return e;
  }
  return NO_EXCEPTION_SENTINEL;
}

function expectsError(stackStartFn, actual, error, message) {
  if (typeof error === 'string') {
    if (arguments.length === 4) {
      throw new ERR_INVALID_ARG_TYPE('error',
                                     ['Object', 'Error', 'Function', 'RegExp'],
                                     error);
    }
    if (typeof actual === 'object' && actual !== null) {
      if (actual.message === error) {
        throw new ERR_AMBIGUOUS_ARGUMENT(
          'error/message',
          `The error message "${actual.message}" is identical to the message.`,
        );
      }
    } else if (actual === error) {
      throw new ERR_AMBIGUOUS_ARGUMENT(
        'error/message',
        `The error "${actual}" is identical to the message.`,
      );
    }
    message = error;
    error = undefined;
  } else if (error != null &&
             typeof error !== 'object' &&
             typeof error !== 'function') {
    throw new ERR_INVALID_ARG_TYPE('error',
                                   ['Object', 'Error', 'Function', 'RegExp'],
                                   error);
  }

  if (actual === NO_EXCEPTION_SENTINEL) {
    let details = '';
    if (error && error.name) {
      details += ` (${error.name})`;
    }
    details += message ? `: ${message}` : '.';
    const fnType = stackStartFn === assert.rejects ? 'rejection' : 'exception';
    innerFail({
      actual: undefined,
      expected: error,
      operator: stackStartFn.name,
      message: `Missing expected ${fnType}${details}`,
      stackStartFn,
    });
  }

  if (!error)
    return;

  expectedException(actual, error, message, stackStartFn);
}

function hasMatchingError(actual, expected) {
  if (typeof expected !== 'function') {
    if (isRegExp(expected)) {
      const str = String(actual);
      return RegExpPrototypeExec(expected, str) !== null;
    }
    throw new ERR_INVALID_ARG_TYPE(
      'expected', ['Function', 'RegExp'], expected,
    );
  }
  // Guard instanceof against arrow functions as they don't have a prototype.
  if (expected.prototype !== undefined && actual instanceof expected) {
    return true;
  }
  if (ObjectPrototypeIsPrototypeOf(Error, expected)) {
    return false;
  }
  return ReflectApply(expected, {}, [actual]) === true;
}

function expectsNoError(stackStartFn, actual, error, message) {
  if (actual === NO_EXCEPTION_SENTINEL)
    return;

  if (typeof error === 'string') {
    message = error;
    error = undefined;
  }

  if (!error || hasMatchingError(actual, error)) {
    const details = message ? `: ${message}` : '.';
    const fnType = stackStartFn === assert.doesNotReject ?
      'rejection' : 'exception';
    innerFail({
      actual,
      expected: error,
      operator: stackStartFn.name,
      message: `Got unwanted ${fnType}${details}\n` +
               `Actual message: "${actual && actual.message}"`,
      stackStartFn,
    });
  }
  throw actual;
}

/**
 * Expects the function `promiseFn` to throw an error.
 * @param {() => any} promiseFn
 * @param {...any} [args]
 * @returns {void}
 */
assert.throws = function throws(promiseFn, ...args) {
  expectsError(throws, getActual(promiseFn), ...args);
};

/**
 * Expects `promiseFn` function or its value to reject.
 * @param {() => Promise<any>} promiseFn
 * @param {...any} [args]
 * @returns {Promise<void>}
 */
assert.rejects = async function rejects(promiseFn, ...args) {
  expectsError(rejects, await waitForActual(promiseFn), ...args);
};

/**
 * Asserts that the function `fn` does not throw an error.
 * @param {() => any} fn
 * @param {...any} [args]
 * @returns {void}
 */
assert.doesNotThrow = function doesNotThrow(fn, ...args) {
  expectsNoError(doesNotThrow, getActual(fn), ...args);
};

/**
 * Expects `fn` or its value to not reject.
 * @param {() => Promise<any>} fn
 * @param {...any} [args]
 * @returns {Promise<void>}
 */
assert.doesNotReject = async function doesNotReject(fn, ...args) {
  expectsNoError(doesNotReject, await waitForActual(fn), ...args);
};

/**
 * Throws `value` if the value is not `null` or `undefined`.
 * @param {any} err
 * @returns {void}
 */
assert.ifError = function ifError(err) {
  if (err !== null && err !== undefined) {
    let message = 'ifError got unwanted exception: ';
    if (typeof err === 'object' && typeof err.message === 'string') {
      if (err.message.length === 0 && err.constructor) {
        message += err.constructor.name;
      } else {
        message += err.message;
      }
    } else {
      message += inspect(err);
    }

    const newErr = new AssertionError({
      actual: err,
      expected: null,
      operator: 'ifError',
      message,
      stackStartFn: ifError,
    });

    // Make sure we actually have a stack trace!
    const origStack = err.stack;

    if (typeof origStack === 'string') {
      // This will remove any duplicated frames from the error frames taken
      // from within `ifError` and add the original error frames to the newly
      // created ones.
      const origStackStart = StringPrototypeIndexOf(origStack, '\n    at');
      if (origStackStart !== -1) {
        const originalFrames = StringPrototypeSplit(
          StringPrototypeSlice(origStack, origStackStart + 1),
          '\n',
        );
        // Filter all frames existing in err.stack.
        let newFrames = StringPrototypeSplit(newErr.stack, '\n');
        for (const errFrame of originalFrames) {
          // Find the first occurrence of the frame.
          const pos = ArrayPrototypeIndexOf(newFrames, errFrame);
          if (pos !== -1) {
            // Only keep new frames.
            newFrames = ArrayPrototypeSlice(newFrames, 0, pos);
            break;
          }
        }
        const stackStart = ArrayPrototypeJoin(newFrames, '\n');
        const stackEnd = ArrayPrototypeJoin(originalFrames, '\n');
        newErr.stack = `${stackStart}\n${stackEnd}`;
      }
    }

    throw newErr;
  }
};

function internalMatch(string, regexp, message, fn) {
  if (!isRegExp(regexp)) {
    throw new ERR_INVALID_ARG_TYPE(
      'regexp', 'RegExp', regexp,
    );
  }
  const match = fn === assert.match;
  if (typeof string !== 'string' ||
      RegExpPrototypeExec(regexp, string) !== null !== match) {
    if (message instanceof Error) {
      throw message;
    }

    const generatedMessage = !message;

    // 'The input was expected to not match the regular expression ' +
    message = message || (typeof string !== 'string' ?
      'The "string" argument must be of type string. Received type ' +
        `${typeof string} (${inspect(string)})` :
      (match ?
        'The input did not match the regular expression ' :
        'The input was expected to not match the regular expression ') +
          `${inspect(regexp)}. Input:\n\n${inspect(string)}\n`);
    const err = new AssertionError({
      actual: string,
      expected: regexp,
      message,
      operator: fn.name,
      stackStartFn: fn,
    });
    err.generatedMessage = generatedMessage;
    throw err;
  }
}

/**
 * Expects the `string` input to match the regular expression.
 * @param {string} string
 * @param {RegExp} regexp
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.match = function match(string, regexp, message) {
  internalMatch(string, regexp, message, match);
};

/**
 * Expects the `string` input not to match the regular expression.
 * @param {string} string
 * @param {RegExp} regexp
 * @param {string | Error} [message]
 * @returns {void}
 */
assert.doesNotMatch = function doesNotMatch(string, regexp, message) {
  internalMatch(string, regexp, message, doesNotMatch);
};

assert.CallTracker = CallTracker;

/**
 * Expose a strict only variant of assert.
 * @param {...any} args
 * @returns {void}
 */
function strict(...args) {
  innerOk(strict, args.length, ...args);
}

assert.strict = ObjectAssign(strict, assert, {
  equal: assert.strictEqual,
  deepEqual: assert.deepStrictEqual,
  notEqual: assert.notStrictEqual,
  notDeepEqual: assert.notDeepStrictEqual,
});

assert.strict.strict = assert.strict;
                               // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ArrayPrototypeForEach,
  ArrayPrototypeJoin,
  ArrayPrototypePush,
  FunctionPrototype,
  ObjectAssign,
  ObjectDefineProperty,
  ObjectSetPrototypeOf,
  ReflectApply,
  RegExp,
  RegExpPrototypeExec,
  RegExpPrototypeSymbolReplace,
  StringPrototypeReplaceAll,
  StringPrototypeSlice,
  Symbol,
  SymbolFor,
} = primordials;

const {
  assertCrypto,
  deprecate,
  kEmptyObject,
} = require('internal/util');

assertCrypto();

const { setImmediate } = require('timers');
const assert = require('internal/assert');
const crypto = require('crypto');
const EE = require('events');
const net = require('net');
const tls = require('tls');
const common = require('_tls_common');
const { kReinitializeHandle } = require('internal/net');
const JSStreamSocket = require('internal/js_stream_socket');
const { Buffer } = require('buffer');
let debug = require('internal/util/debuglog').debuglog('tls', (fn) => {
  debug = fn;
});
const { TCP, constants: TCPConstants } = internalBinding('tcp_wrap');
const tls_wrap = internalBinding('tls_wrap');
const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap');
const { owner_symbol } = require('internal/async_hooks').symbols;
const { isArrayBufferView } = require('internal/util/types');
const { SecureContext: NativeSecureContext } = internalBinding('crypto');
const { connResetException, codes } = require('internal/errors');
const {
  ERR_INVALID_ARG_TYPE,
  ERR_INVALID_ARG_VALUE,
  ERR_MULTIPLE_CALLBACK,
  ERR_SOCKET_CLOSED,
  ERR_TLS_ALPN_CALLBACK_INVALID_RESULT,
  ERR_TLS_ALPN_CALLBACK_WITH_PROTOCOLS,
  ERR_TLS_DH_PARAM_SIZE,
  ERR_TLS_HANDSHAKE_TIMEOUT,
  ERR_TLS_INVALID_CONTEXT,
  ERR_TLS_RENEGOTIATION_DISABLED,
  ERR_TLS_REQUIRED_SERVER_NAME,
  ERR_TLS_SESSION_ATTACK,
  ERR_TLS_SNI_FROM_SERVER,
  ERR_TLS_INVALID_STATE,
} = codes;
const { onpskexchange: kOnPskExchange } = internalBinding('symbols');
const {
  getOptionValue,
  getAllowUnauthorized,
} = require('internal/options');
const {
  validateBoolean,
  validateBuffer,
  validateFunction,
  validateInt32,
  validateNumber,
  validateObject,
  validateString,
  validateUint32,
} = require('internal/validators');
const {
  InternalX509Certificate,
} = require('internal/crypto/x509');
const traceTls = getOptionValue('--trace-tls');
const tlsKeylog = getOptionValue('--tls-keylog');
const { appendFile } = require('fs');
const kConnectOptions = Symbol('connect-options');
const kDisableRenegotiation = Symbol('disable-renegotiation');
const kErrorEmitted = Symbol('error-emitted');
const kHandshakeTimeout = Symbol('handshake-timeout');
const kRes = Symbol('res');
const kSNICallback = Symbol('snicallback');
const kALPNCallback = Symbol('alpncallback');
const kEnableTrace = Symbol('enableTrace');
const kPskCallback = Symbol('pskcallback');
const kPskIdentityHint = Symbol('pskidentityhint');
const kPendingSession = Symbol('pendingSession');
const kIsVerified = Symbol('verified');

const noop = FunctionPrototype;

let ipServernameWarned = false;
let tlsTracingWarned = false;

// Server side times how long a handshake is taking to protect against slow
// handshakes being used for DoS.
function onhandshakestart(now) {
  debug('server onhandshakestart');

  const { lastHandshakeTime } = this;
  assert(now >= lastHandshakeTime,
         `now (${now}) < lastHandshakeTime (${lastHandshakeTime})`);

  this.lastHandshakeTime = now;

  // If this is the first handshake we can skip the rest of the checks.
  if (lastHandshakeTime === 0)
    return;

  if ((now - lastHandshakeTime) >= tls.CLIENT_RENEG_WINDOW * 1000)
    this.handshakes = 1;
  else
    this.handshakes++;

  const owner = this[owner_symbol];

  assert(owner._tlsOptions.isServer);

  if (this.handshakes > tls.CLIENT_RENEG_LIMIT) {
    owner._emitTLSError(new ERR_TLS_SESSION_ATTACK());
    return;
  }

  if (owner[kDisableRenegotiation])
    owner._emitTLSError(new ERR_TLS_RENEGOTIATION_DISABLED());
}

function onhandshakedone() {
  debug('server onhandshakedone');

  const owner = this[owner_symbol];
  assert(owner._tlsOptions.isServer);

  // `newSession` callback wasn't called yet
  if (owner._newSessionPending) {
    owner._securePending = true;
    return;
  }

  owner._finishInit();
}


function loadSession(hello) {
  debug('server onclienthello',
        'sessionid.len', hello.sessionId.length,
        'ticket?', hello.tlsTicket,
  );
  const owner = this[owner_symbol];

  let once = false;
  function onSession(err, session) {
    debug('server resumeSession callback(err %j, sess? %s)', err, !!session);
    if (once)
      return owner.destroy(new ERR_MULTIPLE_CALLBACK());
    once = true;

    if (err)
      return owner.destroy(err);

    if (owner._handle === null)
      return owner.destroy(new ERR_SOCKET_CLOSED());

    owner._handle.loadSession(session);
    // Session is loaded. End the parser to allow handshaking to continue.
    owner._handle.endParser();
  }

  if (hello.sessionId.length <= 0 ||
      hello.tlsTicket ||
      (owner.server &&
      !owner.server.emit('resumeSession', hello.sessionId, onSession))) {
    // Sessions without identifiers can't be resumed.
    // Sessions with tickets can be resumed directly from the ticket, no server
    // session storage is necessary.
    // Without a call to a resumeSession listener, a session will never be
    // loaded, so end the parser to allow handshaking to continue.
    owner._handle.endParser();
  }
}


function loadSNI(info) {
  const owner = this[owner_symbol];
  const servername = info.servername;
  if (!servername || !owner._SNICallback)
    return requestOCSP(owner, info);

  let once = false;
  owner._SNICallback(servername, (err, context) => {
    if (once)
      return owner.destroy(new ERR_MULTIPLE_CALLBACK());
    once = true;

    if (err)
      return owner.destroy(err);

    if (owner._handle === null)
      return owner.destroy(new ERR_SOCKET_CLOSED());

    // TODO(indutny): eventually disallow raw `SecureContext`
    if (context)
      owner._handle.sni_context = context.context || context;

    requestOCSP(owner, info);
  });
}


function callALPNCallback(protocolsBuffer) {
  const handle = this;
  const socket = handle[owner_symbol];

  const servername = handle.getServername();

  // Collect all the protocols from the given buffer:
  const protocols = [];
  let offset = 0;
  while (offset < protocolsBuffer.length) {
    const protocolLen = protocolsBuffer[offset];
    offset += 1;

    const protocol = protocolsBuffer.slice(offset, offset + protocolLen);
    offset += protocolLen;

    protocols.push(protocol.toString('ascii'));
  }

  const selectedProtocol = socket[kALPNCallback]({
    servername,
    protocols,
  });

  // Undefined -> all proposed protocols rejected
  if (selectedProtocol === undefined) return undefined;

  const protocolIndex = protocols.indexOf(selectedProtocol);
  if (protocolIndex === -1) {
    throw new ERR_TLS_ALPN_CALLBACK_INVALID_RESULT(selectedProtocol, protocols);
  }
  let protocolOffset = 0;
  for (let i = 0; i < protocolIndex; i++) {
    protocolOffset += 1 + protocols[i].length;
  }

  return protocolOffset;
}

function requestOCSP(socket, info) {
  if (!info.OCSPRequest || !socket.server)
    return requestOCSPDone(socket);

  let ctx = socket._handle.sni_context;

  if (!ctx) {
    ctx = socket.server._sharedCreds;

    // TLS socket is using a `net.Server` instead of a tls.TLSServer.
    // Some TLS properties like `server._sharedCreds` will not be present
    if (!ctx)
      return requestOCSPDone(socket);
  }

  // TODO(indutny): eventually disallow raw `SecureContext`
  if (ctx.context)
    ctx = ctx.context;

  if (socket.server.listenerCount('OCSPRequest') === 0) {
    return requestOCSPDone(socket);
  }

  let once = false;
  const onOCSP = (err, response) => {
    debug('server OCSPRequest done', 'handle?', !!socket._handle, 'once?', once,
          'response?', !!response, 'err?', err);
    if (once)
      return socket.destroy(new ERR_MULTIPLE_CALLBACK());
    once = true;

    if (err)
      return socket.destroy(err);

    if (socket._handle === null)
      return socket.destroy(new ERR_SOCKET_CLOSED());

    if (response)
      socket._handle.setOCSPResponse(response);
    requestOCSPDone(socket);
  };

  debug('server oncertcb emit OCSPRequest');
  socket.server.emit('OCSPRequest',
                     ctx.getCertificate(),
                     ctx.getIssuer(),
                     onOCSP);
}

function requestOCSPDone(socket) {
  debug('server certcb done');
  try {
    socket._handle.certCbDone();
  } catch (e) {
    debug('server certcb done errored', e);
    socket.destroy(e);
  }
}

function onnewsessionclient(sessionId, session) {
  debug('client emit session');
  const owner = this[owner_symbol];
  if (owner[kIsVerified]) {
    owner.emit('session', session);
  } else {
    owner[kPendingSession] = session;
  }
}

function onnewsession(sessionId, session) {
  debug('onnewsession');
  const owner = this[owner_symbol];

  // TODO(@sam-github) no server to emit the event on, but handshake won't
  // continue unless newSessionDone() is called, should it be, or is that
  // situation unreachable, or only occurring during shutdown?
  if (!owner.server)
    return;

  let once = false;
  const done = () => {
    debug('onnewsession done');
    if (once)
      return;
    once = true;

    if (owner._handle === null)
      return owner.destroy(new ERR_SOCKET_CLOSED());

    this.newSessionDone();

    owner._newSessionPending = false;
    if (owner._securePending)
      owner._finishInit();
    owner._securePending = false;
  };

  owner._newSessionPending = true;
  if (!owner.server.emit('newSession', sessionId, session, done))
    done();
}

function onPskServerCallback(identity, maxPskLen) {
  const owner = this[owner_symbol];
  const ret = owner[kPskCallback](owner, identity);
  if (ret == null)
    return undefined;

  let psk;
  if (isArrayBufferView(ret)) {
    psk = ret;
  } else {
    if (typeof ret !== 'object') {
      throw new ERR_INVALID_ARG_TYPE(
        'ret',
        ['Object', 'Buffer', 'TypedArray', 'DataView'],
        ret,
      );
    }
    psk = ret.psk;
    validateBuffer(psk, 'psk');
  }

  if (psk.length > maxPskLen) {
    throw new ERR_INVALID_ARG_VALUE(
      'psk',
      psk,
      `Pre-shared key exceeds ${maxPskLen} bytes`,
    );
  }

  return psk;
}

function onPskClientCallback(hint, maxPskLen, maxIdentityLen) {
  const owner = this[owner_symbol];
  const ret = owner[kPskCallback](hint);
  if (ret == null)
    return undefined;

  validateObject(ret, 'ret');

  validateBuffer(ret.psk, 'psk');
  if (ret.psk.length > maxPskLen) {
    throw new ERR_INVALID_ARG_VALUE(
      'psk',
      ret.psk,
      `Pre-shared key exceeds ${maxPskLen} bytes`,
    );
  }

  validateString(ret.identity, 'identity');
  if (Buffer.byteLength(ret.identity) > maxIdentityLen) {
    throw new ERR_INVALID_ARG_VALUE(
      'identity',
      ret.identity,
      `PSK identity exceeds ${maxIdentityLen} bytes`,
    );
  }

  return { psk: ret.psk, identity: ret.identity };
}

function onkeylog(line) {
  debug('onkeylog');
  this[owner_symbol].emit('keylog', line);
}

function onocspresponse(resp) {
  debug('client onocspresponse');
  this[owner_symbol].emit('OCSPResponse', resp);
}

function onerror(err) {
  const owner = this[owner_symbol];
  debug('%s onerror %s had? %j',
        (typeof owner._tlsOptions === 'object' && owner._tlsOptions !== null) ?
          owner._tlsOptions.isServer ? 'server' : 'client' :
          'unknown',
        err, owner._hadError);

  if (owner._hadError)
    return;

  owner._hadError = true;

  // Destroy socket if error happened before handshake's finish
  if (!owner._secureEstablished) {
    // When handshake fails control is not yet released,
    // so self._tlsError will return null instead of actual error

    // Set closing the socket after emitting an event since the socket needs to
    // be accessible when the `tlsClientError` event is emitted.
    owner._closeAfterHandlingError = true;
    owner.destroy(err);
  } else if (owner._tlsOptions?.isServer &&
             owner._rejectUnauthorized &&
             RegExpPrototypeExec(/peer did not return a certificate/,
                                 err.message) !== null) {
    // Ignore server's authorization errors
    owner.destroy();
  } else {
    // Emit error
    owner._emitTLSError(err);
  }
}

// Used by both client and server TLSSockets to start data flowing from _handle,
// read(0) causes a StreamBase::ReadStart, via Socket._read.
function initRead(tlsSocket, socket) {
  debug('%s initRead',
        tlsSocket._tlsOptions.isServer ? 'server' : 'client',
        'handle?', !!tlsSocket._handle,
        'buffered?', !!socket && socket.readableLength,
  );
  // If we were destroyed already don't bother reading
  if (!tlsSocket._handle)
    return;

  // Socket already has some buffered data - emulate receiving it
  if (socket && socket.readableLength) {
    let buf;
    while ((buf = socket.read()) !== null)
      tlsSocket._handle.receive(buf);
  }

  tlsSocket.read(0);
}

/**
 * Provides a wrap of socket stream to do encrypted communication.
 */

function TLSSocket(socket, opts) {
  const tlsOptions = { ...opts };
  let enableTrace = tlsOptions.enableTrace;

  if (enableTrace == null) {
    enableTrace = traceTls;

    if (enableTrace && !tlsTracingWarned) {
      tlsTracingWarned = true;
      process.emitWarning('Enabling --trace-tls can expose sensitive data in ' +
                          'the resulting log.');
    }
  } else {
    validateBoolean(enableTrace, 'options.enableTrace');
  }

  if (tlsOptions.ALPNProtocols)
    tls.convertALPNProtocols(tlsOptions.ALPNProtocols, tlsOptions);

  this._tlsOptions = tlsOptions;
  this._secureEstablished = false;
  this._securePending = false;
  this._newSessionPending = false;
  this._controlReleased = false;
  this.secureConnecting = true;
  this._SNICallback = null;
  this[kALPNCallback] = null;
  this.servername = null;
  this.alpnProtocol = null;
  this.authorized = false;
  this.authorizationError = null;
  this[kRes] = null;
  this[kIsVerified] = false;
  this[kPendingSession] = null;

  let wrap;
  let handle;
  let wrapHasActiveWriteFromPrevOwner;

  if (socket) {
    if (socket instanceof net.Socket && socket._handle) {
      // 1. connected socket
      wrap = socket;
    } else {
      // 2. socket has no handle so it is js not c++
      // 3. unconnected sockets are wrapped
      // TLS expects to interact from C++ with a net.Socket that has a C++ stream
      // handle, but a JS stream doesn't have one. Wrap it up to make it look like
      // a socket.
      wrap = new JSStreamSocket(socket);
    }

    handle = wrap._handle;
    wrapHasActiveWriteFromPrevOwner = wrap.writableLength > 0;
  } else {
    // 4. no socket, one will be created with net.Socket().connect
    wrap = null;
    wrapHasActiveWriteFromPrevOwner = false;
  }

  // Just a documented property to make secure sockets
  // distinguishable from regular ones.
  this.encrypted = true;

  ReflectApply(net.Socket, this, [{
    handle: this._wrapHandle(wrap, handle, wrapHasActiveWriteFromPrevOwner),
    allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen,
    pauseOnCreate: tlsOptions.pauseOnConnect,
    manualStart: true,
    highWaterMark: tlsOptions.highWaterMark,
    onread: !socket ? tlsOptions.onread : null,
    signal: tlsOptions.signal,
  }]);

  // Proxy for API compatibility
  this.ssl = this._handle;  // C++ TLSWrap object

  this.on('error', this._tlsError);

  this._init(socket, wrap);

  if (enableTrace && this._handle)
    this._handle.enableTrace();

  if (wrapHasActiveWriteFromPrevOwner) {
    // `wrap` is a streams.Writable in JS. This empty write will be queued
    // and hence finish after all existing writes, which is the timing
    // we want to start to send any tls data to `wrap`.
    wrap.write('', (err) => {
      if (err) {
        debug('error got before writing any tls data to the underlying stream');
        this.destroy(err);
        return;
      }

      this._handle.writesIssuedByPrevListenerDone();
    });
  }

  // Read on next tick so the caller has a chance to setup listeners
  process.nextTick(initRead, this, socket);
}
ObjectSetPrototypeOf(TLSSocket.prototype, net.Socket.prototype);
ObjectSetPrototypeOf(TLSSocket, net.Socket);
exports.TLSSocket = TLSSocket;

const proxiedMethods = [
  'ref', 'unref', 'open', 'bind', 'listen', 'connect', 'bind6',
  'connect6', 'getsockname', 'getpeername', 'setNoDelay', 'setKeepAlive',
  'setSimultaneousAccepts', 'setBlocking',

  // PipeWrap
  'setPendingInstances',
];

// Proxy HandleWrap, PipeWrap and TCPWrap methods
function makeMethodProxy(name) {
  return function methodProxy(...args) {
    if (this._parent[name])
      return ReflectApply(this._parent[name], this._parent, args);
  };
}
for (const proxiedMethod of proxiedMethods) {
  tls_wrap.TLSWrap.prototype[proxiedMethod] =
    makeMethodProxy(proxiedMethod);
}

tls_wrap.TLSWrap.prototype.close = function close(cb) {
  let ssl;
  if (this[owner_symbol]) {
    ssl = this[owner_symbol].ssl;
    this[owner_symbol].ssl = null;
  }

  // Invoke `destroySSL` on close to clean up possibly pending write requests
  // that may self-reference TLSWrap, leading to leak
  const done = () => {
    if (ssl) {
      ssl.destroySSL();
      if (ssl._secureContext.singleUse) {
        ssl._secureContext.context.close();
        ssl._secureContext.context = null;
      }
    }
    if (cb)
      cb();
  };

  if (this._parentWrap && this._parentWrap._handle === this._parent) {
    this._parentWrap.once('close', done);
    return this._parentWrap.destroy();
  }
  return this._parent.close(done);
};

TLSSocket.prototype.disableRenegotiation = function disableRenegotiation() {
  this[kDisableRenegotiation] = true;
};

/**
 *
 * @param {null|net.Socket} wrap
 * @param {null|object} handle
 * @param {boolean} wrapHasActiveWriteFromPrevOwner
 * @returns {object}
 */
TLSSocket.prototype._wrapHandle = function(wrap, handle, wrapHasActiveWriteFromPrevOwner) {
  const options = this._tlsOptions;
  if (!handle) {
    handle = options.pipe ?
      new Pipe(PipeConstants.SOCKET) :
      new TCP(TCPConstants.SOCKET);
    handle[owner_symbol] = this;
  }

  // Wrap socket's handle
  const context = options.secureContext ||
                  options.credentials ||
                  tls.createSecureContext(options);
  assert(handle.isStreamBase, 'handle must be a StreamBase');
  if (!(context.context instanceof NativeSecureContext)) {
    throw new ERR_TLS_INVALID_CONTEXT('context');
  }

  const res = tls_wrap.wrap(handle, context.context,
                            !!options.isServer,
                            wrapHasActiveWriteFromPrevOwner);
  res._parent = handle;  // C++ "wrap" object: TCPWrap, JSStream, ...
  res._parentWrap = wrap;  // JS object: net.Socket, JSStreamSocket, ...
  res._secureContext = context;
  res.reading = handle.reading;
  this[kRes] = res;
  defineHandleReading(this, handle);

  this.on('close', onSocketCloseDestroySSL);

  return res;
};

TLSSocket.prototype[kReinitializeHandle] = function reinitializeHandle(handle) {
  const originalServername = this.ssl ? this._handle.getServername() : null;
  const originalSession = this.ssl ? this._handle.getSession() : null;

  this.handle = this._wrapHandle(null, handle, false);
  this.ssl = this._handle;

  net.Socket.prototype[kReinitializeHandle].call(this, this.handle);
  this._init();

  if (this._tlsOptions.enableTrace) {
    this._handle.enableTrace();
  }

  if (originalSession) {
    this.setSession(originalSession);
  }

  if (originalServername) {
    this.setServername(originalServername);
  }
};

// This eliminates a cyclic reference to TLSWrap
// Ref: https://github.com/nodejs/node/commit/f7620fb96d339f704932f9bb9a0dceb9952df2d4
function defineHandleReading(socket, handle) {
  ObjectDefineProperty(handle, 'reading', {
    __proto__: null,
    get: () => {
      return socket[kRes].reading;
    },
    set: (value) => {
      socket[kRes].reading = value;
    },
  });
}

function onSocketCloseDestroySSL() {
  // Make sure we are not doing it on OpenSSL's stack
  setImmediate(destroySSL, this);
  this[kRes] = null;
}

function destroySSL(self) {
  self._destroySSL();
}

TLSSocket.prototype._destroySSL = function _destroySSL() {
  if (!this.ssl) return;
  this.ssl.destroySSL();
  if (this.ssl._secureContext.singleUse) {
    this.ssl._secureContext.context.close();
    this.ssl._secureContext.context = null;
  }
  this.ssl = null;
  this[kPendingSession] = null;
  this[kIsVerified] = false;
};

function keylogNewListener(event) {
  if (event !== 'keylog')
    return;

  // Guard against enableKeylogCallback after destroy
  if (!this._handle) return;
  this._handle.enableKeylogCallback();

  // Remove this listener since it's no longer needed.
  this.removeListener('newListener', keylogNewListener);
}

function newListener(event) {
  if (event !== 'session')
    return;

  // Guard against enableSessionCallbacks after destroy
  if (!this._handle) return;
  this._handle.enableSessionCallbacks();

  // Remove this listener since it's no longer needed.
  this.removeListener('newListener', newListener);
}

// Constructor guts, arbitrarily factored out.
let warnOnTlsKeylog = true;
let warnOnTlsKeylogError = true;
TLSSocket.prototype._init = function(socket, wrap) {
  const options = this._tlsOptions;
  const ssl = this._handle;
  this.server = options.server;

  debug('%s _init',
        options.isServer ? 'server' : 'client',
        'handle?', !!ssl,
  );

  // Clients (!isServer) always request a cert, servers request a client cert
  // only on explicit configuration.
  const requestCert = !!options.requestCert || !options.isServer;
  const rejectUnauthorized = !!options.rejectUnauthorized;

  this._requestCert = requestCert;
  this._rejectUnauthorized = rejectUnauthorized;
  if (requestCert || rejectUnauthorized)
    ssl.setVerifyMode(requestCert, rejectUnauthorized);

  // Only call .onkeylog if there is a keylog listener.
  ssl.onkeylog = onkeylog;

  if (this.listenerCount('newListener', keylogNewListener) === 0) {
    this.on('newListener', keylogNewListener);
  }

  if (options.isServer) {
    ssl.onhandshakestart = onhandshakestart;
    ssl.onhandshakedone = onhandshakedone;
    ssl.onclienthello = loadSession;
    ssl.oncertcb = loadSNI;
    ssl.onnewsession = onnewsession;
    ssl.lastHandshakeTime = 0;
    ssl.handshakes = 0;

    if (options.ALPNCallback) {
      if (typeof options.ALPNCallback !== 'function') {
        throw new ERR_INVALID_ARG_TYPE('options.ALPNCallback', 'Function', options.ALPNCallback);
      }
      assert(typeof options.ALPNCallback === 'function');
      this[kALPNCallback] = options.ALPNCallback;
      ssl.ALPNCallback = callALPNCallback;
      ssl.enableALPNCb();
    }

    if (this.server) {
      if (this.server.listenerCount('resumeSession') > 0 ||
          this.server.listenerCount('newSession') > 0) {
        // Also starts the client hello parser as a side effect.
        ssl.enableSessionCallbacks();
      }
      if (this.server.listenerCount('OCSPRequest') > 0)
        ssl.enableCertCb();
    }
  } else {
    ssl.onhandshakestart = noop;
    ssl.onhandshakedone = () => {
      debug('client onhandshakedone');
      this._finishInit();
    };
    ssl.onocspresponse = onocspresponse;

    if (options.session)
      ssl.setSession(options.session);

    ssl.onnewsession = onnewsessionclient;

    // Only call .onnewsession if there is a session listener.
    if (this.listenerCount('newListener', newListener) === 0) {
      this.on('newListener', newListener);
    }
  }

  if (tlsKeylog) {
    if (warnOnTlsKeylog) {
      warnOnTlsKeylog = false;
      process.emitWarning('Using --tls-keylog makes TLS connections insecure ' +
        'by writing secret key material to file ' + tlsKeylog);
    }
    this.on('keylog', (line) => {
      appendFile(tlsKeylog, line, { mode: 0o600 }, (err) => {
        if (err && warnOnTlsKeylogError) {
          warnOnTlsKeylogError = false;
          process.emitWarning('Failed to write TLS keylog (this warning ' +
            'will not be repeated): ' + err);
        }
      });
    });
  }

  ssl.onerror = onerror;

  // If custom SNICallback was given, or if
  // there're SNI contexts to perform match against -
  // set `.onsniselect` callback.
  if (options.isServer &&
      options.SNICallback &&
      (options.SNICallback !== SNICallback ||
       (options.server && options.server._contexts.length))) {
    assert(typeof options.SNICallback === 'function');
    this._SNICallback = options.SNICallback;
    ssl.enableCertCb();
  }

  if (options.ALPNProtocols)
    ssl.setALPNProtocols(options.ALPNProtocols);

  if (options.pskCallback && ssl.enablePskCallback) {
    validateFunction(options.pskCallback, 'pskCallback');

    ssl[kOnPskExchange] = options.isServer ?
      onPskServerCallback : onPskClientCallback;

    this[kPskCallback] = options.pskCallback;
    ssl.enablePskCallback();

    if (options.pskIdentityHint) {
      validateString(options.pskIdentityHint, 'options.pskIdentityHint');
      ssl.setPskIdentityHint(options.pskIdentityHint);
    }
  }

  // We can only come here via [kWrapConnectedHandle]() call that happens
  // if the connection is established with `autoSelectFamily` set to `true`.
  const connectOptions = this[kConnectOptions];
  if (!options.isServer && connectOptions) {
    if (connectOptions.servername) {
      this.setServername(connectOptions.servername);
    }
  }

  if (options.handshakeTimeout > 0)
    this.setTimeout(options.handshakeTimeout, this._handleTimeout);

  if (socket instanceof net.Socket) {
    this._parent = socket;

    // To prevent assertion in afterConnect() and properly kick off readStart
    this.connecting = socket.connecting || !socket._handle;
    socket.once('connect', () => {
      this.connecting = false;
      this.emit('connect');
    });
  }

  // Assume `tls.connect()`
  if (wrap) {
    wrap.on('error', (err) => this._emitTLSError(err));
  } else {
    assert(!socket);
    this.connecting = true;
  }
};

TLSSocket.prototype.renegotiate = function(options, callback) {
  validateObject(options, 'options');
  if (callback !== undefined) {
    validateFunction(callback, 'callback');
  }

  debug('%s renegotiate()',
        this._tlsOptions.isServer ? 'server' : 'client',
        'destroyed?', this.destroyed,
  );

  if (this.destroyed)
    return;

  let requestCert = !!this._requestCert;
  let rejectUnauthorized = !!this._rejectUnauthorized;

  if (options.requestCert !== undefined)
    requestCert = !!options.requestCert;
  if (options.rejectUnauthorized !== undefined)
    rejectUnauthorized = !!options.rejectUnauthorized;

  if (requestCert !== this._requestCert ||
      rejectUnauthorized !== this._rejectUnauthorized) {
    this._handle.setVerifyMode(requestCert, rejectUnauthorized);
    this._requestCert = requestCert;
    this._rejectUnauthorized = rejectUnauthorized;
  }
  // Ensure that we'll cycle through internal openssl's state
  this.write('');

  try {
    this._handle.renegotiate();
  } catch (err) {
    if (callback) {
      process.nextTick(callback, err);
    }
    return false;
  }

  // Ensure that we'll cycle through internal openssl's state
  this.write('');

  if (callback) {
    this.once('secure', () => callback(null));
  }

  return true;
};

TLSSocket.prototype.exportKeyingMaterial = function(length, label, context) {
  validateUint32(length, 'length', true);
  validateString(label, 'label');
  if (context !== undefined)
    validateBuffer(context, 'context');

  if (!this._secureEstablished)
    throw new ERR_TLS_INVALID_STATE();

  return this._handle.exportKeyingMaterial(length, label, context);
};

TLSSocket.prototype.setMaxSendFragment = function setMaxSendFragment(size) {
  validateInt32(size, 'size');
  return this._handle.setMaxSendFragment(size) === 1;
};

TLSSocket.prototype._handleTimeout = function() {
  this._emitTLSError(new ERR_TLS_HANDSHAKE_TIMEOUT());
};

TLSSocket.prototype._emitTLSError = function(err) {
  const e = this._tlsError(err);
  if (e)
    this.emit('error', e);
};

TLSSocket.prototype._tlsError = function(err) {
  this.emit('_tlsError', err);
  if (this._controlReleased)
    return err;
  return null;
};

TLSSocket.prototype._releaseControl = function() {
  if (this._controlReleased)
    return false;
  this._controlReleased = true;
  this.removeListener('error', this._tlsError);
  return true;
};

TLSSocket.prototype._finishInit = function() {
  // Guard against getting onhandshakedone() after .destroy().
  // * 1.2: If destroy() during onocspresponse(), then write of next handshake
  // record fails, the handshake done info callbacks does not occur, and the
  // socket closes.
  // * 1.3: The OCSP response comes in the same record that finishes handshake,
  // so even after .destroy(), the handshake done info callback occurs
  // immediately after onocspresponse(). Ignore it.
  if (!this._handle)
    return;

  this.alpnProtocol = this._handle.getALPNNegotiatedProtocol();
  // The servername could be set by TLSWrap::SelectSNIContextCallback().
  if (this.servername === null) {
    this.servername = this._handle.getServername();
  }

  debug('%s _finishInit',
        this._tlsOptions.isServer ? 'server' : 'client',
        'handle?', !!this._handle,
        'alpn', this.alpnProtocol,
        'servername', this.servername);

  this._secureEstablished = true;
  if (this._tlsOptions.handshakeTimeout > 0)
    this.setTimeout(0, this._handleTimeout);
  this.emit('secure');
};

TLSSocket.prototype._start = function() {
  debug('%s _start',
        this._tlsOptions.isServer ? 'server' : 'client',
        'handle?', !!this._handle,
        'connecting?', this.connecting,
        'requestOCSP?', !!this._tlsOptions.requestOCSP,
  );
  if (this.connecting) {
    this.once('connect', this._start);
    return;
  }

  // Socket was destroyed before the connection was established
  if (!this._handle)
    return;

  if (this._tlsOptions.requestOCSP)
    this._handle.requestOCSP();
  this._handle.start();
};

TLSSocket.prototype.setServername = function(name) {
  validateString(name, 'name');

  if (this._tlsOptions.isServer) {
    throw new ERR_TLS_SNI_FROM_SERVER();
  }

  this._handle.setServername(name);
};

TLSSocket.prototype.setSession = function(session) {
  if (typeof session === 'string')
    session = Buffer.from(session, 'latin1');
  this._handle.setSession(session);
};

TLSSocket.prototype.getPeerCertificate = function(detailed) {
  if (this._handle) {
    return common.translatePeerCertificate(
      this._handle.getPeerCertificate(detailed)) || {};
  }

  return null;
};

TLSSocket.prototype.getCertificate = function() {
  if (this._handle) {
    // It's not a peer cert, but the formatting is identical.
    return common.translatePeerCertificate(
      this._handle.getCertificate()) || {};
  }

  return null;
};

TLSSocket.prototype.getPeerX509Certificate = function(detailed) {
  const cert = this._handle?.getPeerX509Certificate();
  return cert ? new InternalX509Certificate(cert) : undefined;
};

TLSSocket.prototype.getX509Certificate = function() {
  const cert = this._handle?.getX509Certificate();
  return cert ? new InternalX509Certificate(cert) : undefined;
};

// Proxy TLSSocket handle methods
function makeSocketMethodProxy(name) {
  return function socketMethodProxy(...args) {
    if (this._handle)
      return ReflectApply(this._handle[name], this._handle, args);
    return null;
  };
}

ArrayPrototypeForEach([
  'getCipher',
  'getSharedSigalgs',
  'getEphemeralKeyInfo',
  'getFinished',
  'getPeerFinished',
  'getProtocol',
  'getSession',
  'getTLSTicket',
  'isSessionReused',
  'enableTrace',
], (method) => {
  TLSSocket.prototype[method] = makeSocketMethodProxy(method);
});

// TODO: support anonymous (nocert)


function onServerSocketSecure() {
  if (this._requestCert) {
    const verifyError = this._handle.verifyError();
    if (verifyError) {
      this.authorizationError = verifyError.code;

      if (this._rejectUnauthorized)
        this.destroy();
    } else {
      this.authorized = true;
    }
  }

  if (!this.destroyed && this._releaseControl()) {
    debug('server emit secureConnection');
    this.secureConnecting = false;
    this._tlsOptions.server.emit('secureConnection', this);
  }
}

function onSocketTLSError(err) {
  if (!this._controlReleased && !this[kErrorEmitted]) {
    this[kErrorEmitted] = true;
    debug('server emit tlsClientError:', err);
    this._tlsOptions.server.emit('tlsClientError', err, this);
  }
}

function onSocketKeylog(line) {
  this._tlsOptions.server.emit('keylog', line, this);
}

function onSocketClose(err) {
  // Closed because of error - no need to emit it twice
  if (err)
    return;

  // Emit ECONNRESET
  if (!this._controlReleased && !this[kErrorEmitted]) {
    this[kErrorEmitted] = true;
    const connReset = connResetException('socket hang up');
    this._tlsOptions.server.emit('tlsClientError', connReset, this);
  }
}

function tlsConnectionListener(rawSocket) {
  debug('net.Server.on(connection): new TLSSocket');
  const socket = new TLSSocket(rawSocket, {
    secureContext: this._sharedCreds,
    isServer: true,
    server: this,
    requestCert: this.requestCert,
    rejectUnauthorized: this.rejectUnauthorized,
    handshakeTimeout: this[kHandshakeTimeout],
    ALPNProtocols: this.ALPNProtocols,
    ALPNCallback: this.ALPNCallback,
    SNICallback: this[kSNICallback] || SNICallback,
    enableTrace: this[kEnableTrace],
    pauseOnConnect: this.pauseOnConnect,
    pskCallback: this[kPskCallback],
    pskIdentityHint: this[kPskIdentityHint],
  });

  socket.on('secure', onServerSocketSecure);

  if (this.listenerCount('keylog') > 0)
    socket.on('keylog', onSocketKeylog);

  socket[kErrorEmitted] = false;
  socket.on('close', onSocketClose);
  socket.on('_tlsError', onSocketTLSError);
}

// AUTHENTICATION MODES
//
// There are several levels of authentication that TLS/SSL supports.
// Read more about this in "man SSL_set_verify".
//
// 1. The server sends a certificate to the client but does not request a
// cert from the client. This is common for most HTTPS servers. The browser
// can verify the identity of the server, but the server does not know who
// the client is. Authenticating the client is usually done over HTTP using
// login boxes and cookies and stuff.
//
// 2. The server sends a cert to the client and requests that the client
// also send it a cert. The client knows who the server is and the server is
// requesting the client also identify themselves. There are several
// outcomes:
//
//   A) verifyError returns null meaning the client's certificate is signed
//   by one of the server's CAs. The server now knows the client's identity
//   and the client is authorized.
//
//   B) For some reason the client's certificate is not acceptable -
//   verifyError returns a string indicating the problem. The server can
//   either (i) reject the client or (ii) allow the client to connect as an
//   unauthorized connection.
//
// The mode is controlled by two boolean variables.
//
// requestCert
//   If true the server requests a certificate from client connections. For
//   the common HTTPS case, users will want this to be false, which is what
//   it defaults to.
//
// rejectUnauthorized
//   If true clients whose certificates are invalid for any reason will not
//   be allowed to make connections. If false, they will simply be marked as
//   unauthorized but secure communication will continue. By default this is
//   true.
//
//
//
// Options:
// - requestCert. Send verify request. Default to false.
// - rejectUnauthorized. Boolean, default to true.
// - key. string.
// - cert: string.
// - clientCertEngine: string.
// - ca: string or array of strings.
// - sessionTimeout: integer.
//
// emit 'secureConnection'
//   function (tlsSocket) { }
//
//   "UNABLE_TO_GET_ISSUER_CERT", "UNABLE_TO_GET_CRL",
//   "UNABLE_TO_DECRYPT_CERT_SIGNATURE", "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
//   "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY", "CERT_SIGNATURE_FAILURE",
//   "CRL_SIGNATURE_FAILURE", "CERT_NOT_YET_VALID" "CERT_HAS_EXPIRED",
//   "CRL_NOT_YET_VALID", "CRL_HAS_EXPIRED" "ERROR_IN_CERT_NOT_BEFORE_FIELD",
//   "ERROR_IN_CERT_NOT_AFTER_FIELD", "ERROR_IN_CRL_LAST_UPDATE_FIELD",
//   "ERROR_IN_CRL_NEXT_UPDATE_FIELD", "OUT_OF_MEM",
//   "DEPTH_ZERO_SELF_SIGNED_CERT", "SELF_SIGNED_CERT_IN_CHAIN",
//   "UNABLE_TO_GET_ISSUER_CERT_LOCALLY", "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
//   "CERT_CHAIN_TOO_LONG", "CERT_REVOKED" "INVALID_CA",
//   "PATH_LENGTH_EXCEEDED", "INVALID_PURPOSE" "CERT_UNTRUSTED",
//   "CERT_REJECTED"
//
function Server(options, listener) {
  if (!(this instanceof Server))
    return new Server(options, listener);

  if (typeof options === 'function') {
    listener = options;
    options = kEmptyObject;
  } else if (options == null || typeof options === 'object') {
    options = options ?? kEmptyObject;
  } else {
    throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
  }

  this._contexts = [];
  this.requestCert = options.requestCert === true;
  this.rejectUnauthorized = options.rejectUnauthorized !== false;

  this.ALPNCallback = options.ALPNCallback;
  if (this.ALPNCallback && options.ALPNProtocols) {
    throw new ERR_TLS_ALPN_CALLBACK_WITH_PROTOCOLS();
  }

  if (options.sessionTimeout)
    this.sessionTimeout = options.sessionTimeout;

  if (options.ticketKeys)
    this.ticketKeys = options.ticketKeys;

  if (options.ALPNProtocols)
    tls.convertALPNProtocols(options.ALPNProtocols, this);

  this.setSecureContext(options);

  this[kHandshakeTimeout] = options.handshakeTimeout || (120 * 1000);
  this[kSNICallback] = options.SNICallback;
  this[kPskCallback] = options.pskCallback;
  this[kPskIdentityHint] = options.pskIdentityHint;

  validateNumber(this[kHandshakeTimeout], 'options.handshakeTimeout');

  if (this[kSNICallback]) {
    validateFunction(this[kSNICallback], 'options.SNICallback');
  }

  if (this[kPskCallback]) {
    validateFunction(this[kPskCallback], 'options.pskCallback');
  }

  if (this[kPskIdentityHint]) {
    validateString(this[kPskIdentityHint], 'options.pskIdentityHint');
  }

  // constructor call
  ReflectApply(net.Server, this, [options, tlsConnectionListener]);

  if (listener) {
    this.on('secureConnection', listener);
  }

  this[kEnableTrace] = options.enableTrace;
}

ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
ObjectSetPrototypeOf(Server, net.Server);
exports.Server = Server;
exports.createServer = function createServer(options, listener) {
  return new Server(options, listener);
};


Server.prototype.setSecureContext = function(options) {
  validateObject(options, 'options');

  if (options.pfx)
    this.pfx = options.pfx;
  else
    this.pfx = undefined;

  if (options.key)
    this.key = options.key;
  else
    this.key = undefined;

  if (options.passphrase)
    this.passphrase = options.passphrase;
  else
    this.passphrase = undefined;

  if (options.cert)
    this.cert = options.cert;
  else
    this.cert = undefined;

  if (options.clientCertEngine)
    this.clientCertEngine = options.clientCertEngine;
  else
    this.clientCertEngine = undefined;

  if (options.ca)
    this.ca = options.ca;
  else
    this.ca = undefined;

  if (options.minVersion)
    this.minVersion = options.minVersion;
  else
    this.minVersion = undefined;

  if (options.maxVersion)
    this.maxVersion = options.maxVersion;
  else
    this.maxVersion = undefined;

  if (options.secureProtocol)
    this.secureProtocol = options.secureProtocol;
  else
    this.secureProtocol = undefined;

  if (options.crl)
    this.crl = options.crl;
  else
    this.crl = undefined;

  this.sigalgs = options.sigalgs;

  if (options.ciphers)
    this.ciphers = options.ciphers;
  else
    this.ciphers = undefined;

  this.ecdhCurve = options.ecdhCurve;

  if (options.dhparam)
    this.dhparam = options.dhparam;
  else
    this.dhparam = undefined;

  if (options.honorCipherOrder !== undefined)
    this.honorCipherOrder = !!options.honorCipherOrder;
  else
    this.honorCipherOrder = true;

  const secureOptions = options.secureOptions || 0;

  if (secureOptions)
    this.secureOptions = secureOptions;
  else
    this.secureOptions = undefined;

  if (options.sessionIdContext) {
    this.sessionIdContext = options.sessionIdContext;
  } else {
    this.sessionIdContext = StringPrototypeSlice(
      crypto.createHash('sha1')
        .update(ArrayPrototypeJoin(process.argv, ' '))
        .digest('hex'), 0, 32);
  }

  if (options.sessionTimeout)
    this.sessionTimeout = options.sessionTimeout;

  if (options.ticketKeys)
    this.ticketKeys = options.ticketKeys;

  this.privateKeyIdentifier = options.privateKeyIdentifier;
  this.privateKeyEngine = options.privateKeyEngine;

  this._sharedCreds = tls.createSecureContext({
    pfx: this.pfx,
    key: this.key,
    passphrase: this.passphrase,
    cert: this.cert,
    clientCertEngine: this.clientCertEngine,
    ca: this.ca,
    ciphers: this.ciphers,
    sigalgs: this.sigalgs,
    ecdhCurve: this.ecdhCurve,
    dhparam: this.dhparam,
    minVersion: this.minVersion,
    maxVersion: this.maxVersion,
    secureProtocol: this.secureProtocol,
    secureOptions: this.secureOptions,
    honorCipherOrder: this.honorCipherOrder,
    crl: this.crl,
    sessionIdContext: this.sessionIdContext,
    ticketKeys: this.ticketKeys,
    sessionTimeout: this.sessionTimeout,
    privateKeyIdentifier: this.privateKeyIdentifier,
    privateKeyEngine: this.privateKeyEngine,
  });
};


Server.prototype._getServerData = function() {
  return {
    ticketKeys: this.getTicketKeys().toString('hex'),
  };
};


Server.prototype._setServerData = function(data) {
  this.setTicketKeys(Buffer.from(data.ticketKeys, 'hex'));
};


Server.prototype.getTicketKeys = function getTicketKeys() {
  return this._sharedCreds.context.getTicketKeys();
};


Server.prototype.setTicketKeys = function setTicketKeys(keys) {
  validateBuffer(keys);
  assert(keys.byteLength === 48,
         'Session ticket keys must be a 48-byte buffer');
  this._sharedCreds.context.setTicketKeys(keys);
};


Server.prototype.setOptions = deprecate(function(options) {
  this.requestCert = options.requestCert === true;
  this.rejectUnauthorized = options.rejectUnauthorized !== false;

  if (options.pfx) this.pfx = options.pfx;
  if (options.key) this.key = options.key;
  if (options.passphrase) this.passphrase = options.passphrase;
  if (options.cert) this.cert = options.cert;
  if (options.clientCertEngine)
    this.clientCertEngine = options.clientCertEngine;
  if (options.ca) this.ca = options.ca;
  if (options.minVersion) this.minVersion = options.minVersion;
  if (options.maxVersion) this.maxVersion = options.maxVersion;
  if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
  if (options.crl) this.crl = options.crl;
  if (options.ciphers) this.ciphers = options.ciphers;
  if (options.ecdhCurve !== undefined)
    this.ecdhCurve = options.ecdhCurve;
  if (options.dhparam) this.dhparam = options.dhparam;
  if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
  if (options.ticketKeys) this.ticketKeys = options.ticketKeys;
  const secureOptions = options.secureOptions || 0;
  if (options.honorCipherOrder !== undefined)
    this.honorCipherOrder = !!options.honorCipherOrder;
  else
    this.honorCipherOrder = true;
  if (secureOptions) this.secureOptions = secureOptions;
  if (options.ALPNProtocols)
    tls.convertALPNProtocols(options.ALPNProtocols, this);
  if (options.sessionIdContext) {
    this.sessionIdContext = options.sessionIdContext;
  } else {
    this.sessionIdContext = StringPrototypeSlice(
      crypto.createHash('sha1')
        .update(ArrayPrototypeJoin(process.argv, ' '))
        .digest('hex'), 0, 32);
  }
  if (options.pskCallback) this[kPskCallback] = options.pskCallback;
  if (options.pskIdentityHint) this[kPskIdentityHint] = options.pskIdentityHint;
  if (options.sigalgs) this.sigalgs = options.sigalgs;
  if (options.privateKeyIdentifier !== undefined)
    this.privateKeyIdentifier = options.privateKeyIdentifier;
  if (options.privateKeyEngine !== undefined)
    this.privateKeyEngine = options.privateKeyEngine;
}, 'Server.prototype.setOptions() is deprecated', 'DEP0122');

// SNI Contexts High-Level API
Server.prototype.addContext = function(servername, context) {
  if (!servername) {
    throw new ERR_TLS_REQUIRED_SERVER_NAME();
  }

  const re = new RegExp('^' + StringPrototypeReplaceAll(
    RegExpPrototypeSymbolReplace(/([.^$+?\-\\[\]{}])/g, servername, '\\$1'),
    '*', '[^.]*',
  ) + '$');

  const secureContext =
    context instanceof common.SecureContext ? context : tls.createSecureContext(context);
  ArrayPrototypePush(this._contexts, [re, secureContext.context]);
};

Server.prototype[EE.captureRejectionSymbol] = function(
  err, event, sock) {

  switch (event) {
    case 'secureConnection':
      sock.destroy(err);
      break;
    default:
      ReflectApply(net.Server.prototype[SymbolFor('nodejs.rejection')], this,
                   [err, event, sock]);
  }
};

function SNICallback(servername, callback) {
  const contexts = this.server._contexts;

  for (let i = contexts.length - 1; i >= 0; --i) {
    const elem = contexts[i];
    if (RegExpPrototypeExec(elem[0], servername) !== null) {
      callback(null, elem[1]);
      return;
    }
  }

  callback(null, undefined);
}


// Target API:
//
//  let s = tls.connect({port: 8000, host: "google.com"}, function() {
//    if (!s.authorized) {
//      s.destroy();
//      return;
//    }
//
//    // s.socket;
//
//    s.end("hello world\n");
//  });
//
//
function normalizeConnectArgs(listArgs) {
  const args = net._normalizeArgs(listArgs);
  const options = args[0];
  const cb = args[1];

  // If args[0] was options, then normalize dealt with it.
  // If args[0] is port, or args[0], args[1] is host, port, we need to
  // find the options and merge them in, normalize's options has only
  // the host/port/path args that it knows about, not the tls options.
  // This means that options.host overrides a host arg.
  if (listArgs[1] !== null && typeof listArgs[1] === 'object') {
    ObjectAssign(options, listArgs[1]);
  } else if (listArgs[2] !== null && typeof listArgs[2] === 'object') {
    ObjectAssign(options, listArgs[2]);
  }

  return cb ? [options, cb] : [options];
}

function onConnectSecure() {
  const options = this[kConnectOptions];

  // Check the size of DHE parameter above minimum requirement
  // specified in options.
  const ekeyinfo = this.getEphemeralKeyInfo();
  if (ekeyinfo.type === 'DH' && ekeyinfo.size < options.minDHSize) {
    const err = new ERR_TLS_DH_PARAM_SIZE(ekeyinfo.size);
    debug('client emit:', err);
    this.emit('error', err);
    this.destroy();
    return;
  }

  let verifyError = this._handle.verifyError();

  // Verify that server's identity matches it's certificate's names
  // Unless server has resumed our existing session
  if (!verifyError && !this.isSessionReused()) {
    const hostname = options.servername ||
                   options.host ||
                   (options.socket && options.socket._host) ||
                   'localhost';
    const cert = this.getPeerCertificate(true);
    verifyError = options.checkServerIdentity(hostname, cert);
  }

  if (verifyError) {
    this.authorized = false;
    this.authorizationError = verifyError.code || verifyError.message;

    // rejectUnauthorized property can be explicitly defined as `undefined`
    // causing the assignment to default value (`true`) fail. Before assigning
    // it to the tlssock connection options, explicitly check if it is false
    // and update rejectUnauthorized property. The property gets used by
    // TLSSocket connection handler to allow or reject connection if
    // unauthorized.
    // This check is potentially redundant, however it is better to keep it
    // in case the option object gets modified somewhere.
    if (options.rejectUnauthorized !== false) {
      this.destroy(verifyError);
      return;
    }
    debug('client emit secureConnect. rejectUnauthorized: %s, ' +
          'authorizationError: %s', options.rejectUnauthorized,
          this.authorizationError);
    this.secureConnecting = false;
    this.emit('secureConnect');
  } else {
    this.authorized = true;
    debug('client emit secureConnect. authorized:', this.authorized);
    this.secureConnecting = false;
    this.emit('secureConnect');
  }

  this[kIsVerified] = true;
  const session = this[kPendingSession];
  this[kPendingSession] = null;
  if (session)
    this.emit('session', session);

  this.removeListener('end', onConnectEnd);
}

function onConnectEnd() {
  // NOTE: This logic is shared with _http_client.js
  if (!this._hadError) {
    const options = this[kConnectOptions];
    this._hadError = true;
    const error = connResetException('Client network socket disconnected ' +
                                     'before secure TLS connection was ' +
                                     'established');
    error.path = options.path;
    error.host = options.host;
    error.port = options.port;
    error.localAddress = options.localAddress;
    this.destroy(error);
  }
}

// Arguments: [port,] [host,] [options,] [cb]
exports.connect = function connect(...args) {
  args = normalizeConnectArgs(args);
  let options = args[0];
  const cb = args[1];
  const allowUnauthorized = getAllowUnauthorized();

  options = {
    rejectUnauthorized: !allowUnauthorized,
    ciphers: tls.DEFAULT_CIPHERS,
    checkServerIdentity: tls.checkServerIdentity,
    minDHSize: 1024,
    ...options,
  };

  if (!options.keepAlive)
    options.singleUse = true;

  assert(typeof options.checkServerIdentity === 'function');
  assert(typeof options.minDHSize === 'number',
         'options.minDHSize is not a number: ' + options.minDHSize);
  assert(options.minDHSize > 0,
         'options.minDHSize is not a positive number: ' +
         options.minDHSize);

  const context = options.secureContext || tls.createSecureContext(options);

  const tlssock = new TLSSocket(options.socket, {
    allowHalfOpen: options.allowHalfOpen,
    pipe: !!options.path,
    secureContext: context,
    isServer: false,
    requestCert: true,
    rejectUnauthorized: options.rejectUnauthorized !== false,
    session: options.session,
    ALPNProtocols: options.ALPNProtocols,
    requestOCSP: options.requestOCSP,
    enableTrace: options.enableTrace,
    pskCallback: options.pskCallback,
    highWaterMark: options.highWaterMark,
    onread: options.onread,
    signal: options.signal,
  });

  // rejectUnauthorized property can be explicitly defined as `undefined`
  // causing the assignment to default value (`true`) fail. Before assigning
  // it to the tlssock connection options, explicitly check if it is false
  // and update rejectUnauthorized property. The property gets used by TLSSocket
  // connection handler to allow or reject connection if unauthorized
  options.rejectUnauthorized = options.rejectUnauthorized !== false;

  tlssock[kConnectOptions] = options;

  if (cb)
    tlssock.once('secureConnect', cb);

  if (!options.socket) {
    // If user provided the socket, it's their responsibility to manage its
    // connectivity. If we created one internally, we connect it.
    if (options.timeout) {
      tlssock.setTimeout(options.timeout);
    }

    tlssock.connect(options, tlssock._start);
  }

  tlssock._releaseControl();

  if (options.session)
    tlssock.setSession(options.session);

  if (options.servername) {
    if (!ipServernameWarned && net.isIP(options.servername)) {
      process.emitWarning(
        'Setting the TLS ServerName to an IP address is not permitted by ' +
        'RFC 6066. This will be ignored in a future version.',
        'DeprecationWarning',
        'DEP0123',
      );
      ipServernameWarned = true;
    }
    tlssock.setServername(options.servername);
  }

  if (options.socket)
    tlssock._start();

  tlssock.on('secure', onConnectSecure);
  tlssock.prependListener('end', onConnectEnd);

  return tlssock;
};
          // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const tls = require('tls');

const {
  ArrayPrototypePush,
  JSONParse,
  ObjectCreate,
  RegExpPrototypeSymbolReplace,
} = primordials;

const {
  codes: {
    ERR_TLS_INVALID_PROTOCOL_VERSION,
    ERR_TLS_PROTOCOL_VERSION_CONFLICT,
  },
} = require('internal/errors');

const {
  crypto: {
    SSL_OP_CIPHER_SERVER_PREFERENCE,
    TLS1_VERSION,
    TLS1_1_VERSION,
    TLS1_2_VERSION,
    TLS1_3_VERSION,
  },
} = internalBinding('constants');

const {
  kEmptyObject,
} = require('internal/util');

const {
  validateInteger,
} = require('internal/validators');

const {
  configSecureContext,
} = require('internal/tls/secure-context');

function toV(which, v, def) {
  if (v == null) v = def;
  if (v === 'TLSv1') return TLS1_VERSION;
  if (v === 'TLSv1.1') return TLS1_1_VERSION;
  if (v === 'TLSv1.2') return TLS1_2_VERSION;
  if (v === 'TLSv1.3') return TLS1_3_VERSION;
  throw new ERR_TLS_INVALID_PROTOCOL_VERSION(v, which);
}

const {
  SecureContext: NativeSecureContext,
} = internalBinding('crypto');

function SecureContext(secureProtocol, secureOptions, minVersion, maxVersion) {
  if (!(this instanceof SecureContext)) {
    return new SecureContext(secureProtocol, secureOptions, minVersion,
                             maxVersion);
  }

  if (secureProtocol) {
    if (minVersion != null)
      throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(minVersion, secureProtocol);
    if (maxVersion != null)
      throw new ERR_TLS_PROTOCOL_VERSION_CONFLICT(maxVersion, secureProtocol);
  }

  this.context = new NativeSecureContext();
  this.context.init(secureProtocol,
                    toV('minimum', minVersion, tls.DEFAULT_MIN_VERSION),
                    toV('maximum', maxVersion, tls.DEFAULT_MAX_VERSION));

  if (secureOptions) {
    validateInteger(secureOptions, 'secureOptions');
    this.context.setOptions(secureOptions);
  }
}

function createSecureContext(options) {
  if (!options) options = kEmptyObject;

  const {
    honorCipherOrder,
    minVersion,
    maxVersion,
    secureProtocol,
  } = options;

  let { secureOptions } = options;

  if (honorCipherOrder)
    secureOptions |= SSL_OP_CIPHER_SERVER_PREFERENCE;

  const c = new SecureContext(secureProtocol, secureOptions,
                              minVersion, maxVersion);

  configSecureContext(c.context, options);

  return c;
}

// Translate some fields from the handle's C-friendly format into more idiomatic
// javascript object representations before passing them back to the user.  Can
// be used on any cert object, but changing the name would be semver-major.
function translatePeerCertificate(c) {
  if (!c)
    return null;

  if (c.issuerCertificate != null && c.issuerCertificate !== c) {
    c.issuerCertificate = translatePeerCertificate(c.issuerCertificate);
  }
  if (c.infoAccess != null) {
    const info = c.infoAccess;
    c.infoAccess = ObjectCreate(null);

    // XXX: More key validation?
    RegExpPrototypeSymbolReplace(/([^\n:]*):([^\n]*)(?:\n|$)/g, info,
                                 (all, key, val) => {
                                   if (val.charCodeAt(0) === 0x22) {
                                     // The translatePeerCertificate function is only
                                     // used on internally created legacy certificate
                                     // objects, and any value that contains a quote
                                     // will always be a valid JSON string literal,
                                     // so this should never throw.
                                     val = JSONParse(val);
                                   }
                                   if (key in c.infoAccess)
                                     ArrayPrototypePush(c.infoAccess[key], val);
                                   else
                                     c.infoAccess[key] = [val];
                                 });
  }
  return c;
}

module.exports = {
  SecureContext,
  createSecureContext,
  translatePeerCertificate,
};
       'use strict';

// Keep this file as an alias for the full stream module.

module.exports = require('stream').Writable;
         'use strict';

module.exports = require('internal/js_stream_socket');
process.emitWarning('The _stream_wrap module is deprecated.',
                    'DeprecationWarning', 'DEP0125');
      'use strict';

// Keep this file as an alias for the full stream module.

module.exports = require('stream').Transform;
        'use strict';

// Keep this file as an alias for the full stream module.

module.exports = require('stream').Readable;
         'use strict';

// Keep this file as an alias for the full stream module.

module.exports = require('stream').PassThrough;
      'use strict';

// Keep this file as an alias for the full stream module.

module.exports = require('stream').Duplex;
           // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ArrayIsArray,
  Error,
  MathMin,
  ObjectKeys,
  ObjectSetPrototypeOf,
  RegExpPrototypeExec,
  ReflectApply,
  Symbol,
  SymbolFor,
} = primordials;

const net = require('net');
const EE = require('events');
const assert = require('internal/assert');
const {
  parsers,
  freeParser,
  continueExpression,
  chunkExpression,
  kIncomingMessage,
  HTTPParser,
  isLenient,
  _checkInvalidHeaderChar: checkInvalidHeaderChar,
  prepareError,
} = require('_http_common');
const { ConnectionsList } = internalBinding('http_parser');
const {
  kUniqueHeaders,
  parseUniqueHeadersOption,
  OutgoingMessage,
} = require('_http_outgoing');
const {
  kOutHeaders,
  kNeedDrain,
  isTraceHTTPEnabled,
  traceBegin,
  traceEnd,
  getNextTraceEventId,
} = require('internal/http');
const {
  defaultTriggerAsyncIdScope,
  getOrSetAsyncId,
} = require('internal/async_hooks');
const { IncomingMessage } = require('_http_incoming');
const {
  connResetException,
  codes,
} = require('internal/errors');
const {
  ERR_HTTP_REQUEST_TIMEOUT,
  ERR_HTTP_HEADERS_SENT,
  ERR_HTTP_INVALID_STATUS_CODE,
  ERR_HTTP_SOCKET_ENCODING,
  ERR_INVALID_ARG_TYPE,
  ERR_HTTP_SOCKET_ASSIGNED,
  ERR_INVALID_ARG_VALUE,
  ERR_INVALID_CHAR,
} = codes;
const {
  validateInteger,
  validateBoolean,
  validateLinkHeaderValue,
  validateObject,
} = require('internal/validators');
const Buffer = require('buffer').Buffer;
const {
  DTRACE_HTTP_SERVER_REQUEST,
  DTRACE_HTTP_SERVER_RESPONSE,
} = require('internal/dtrace');
const { setInterval, clearInterval } = require('timers');
let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
  debug = fn;
});

const dc = require('diagnostics_channel');
const onRequestStartChannel = dc.channel('http.server.request.start');
const onResponseFinishChannel = dc.channel('http.server.response.finish');

const kServerResponse = Symbol('ServerResponse');
const kServerResponseStatistics = Symbol('ServerResponseStatistics');

const {
  hasObserver,
  startPerf,
  stopPerf,
} = require('internal/perf/observe');

const STATUS_CODES = {
  100: 'Continue',                   // RFC 7231 6.2.1
  101: 'Switching Protocols',        // RFC 7231 6.2.2
  102: 'Processing',                 // RFC 2518 10.1 (obsoleted by RFC 4918)
  103: 'Early Hints',                // RFC 8297 2
  200: 'OK',                         // RFC 7231 6.3.1
  201: 'Created',                    // RFC 7231 6.3.2
  202: 'Accepted',                   // RFC 7231 6.3.3
  203: 'Non-Authoritative Information', // RFC 7231 6.3.4
  204: 'No Content',                 // RFC 7231 6.3.5
  205: 'Reset Content',              // RFC 7231 6.3.6
  206: 'Partial Content',            // RFC 7233 4.1
  207: 'Multi-Status',               // RFC 4918 11.1
  208: 'Already Reported',           // RFC 5842 7.1
  226: 'IM Used',                    // RFC 3229 10.4.1
  300: 'Multiple Choices',           // RFC 7231 6.4.1
  301: 'Moved Permanently',          // RFC 7231 6.4.2
  302: 'Found',                      // RFC 7231 6.4.3
  303: 'See Other',                  // RFC 7231 6.4.4
  304: 'Not Modified',               // RFC 7232 4.1
  305: 'Use Proxy',                  // RFC 7231 6.4.5
  307: 'Temporary Redirect',         // RFC 7231 6.4.7
  308: 'Permanent Redirect',         // RFC 7238 3
  400: 'Bad Request',                // RFC 7231 6.5.1
  401: 'Unauthorized',               // RFC 7235 3.1
  402: 'Payment Required',           // RFC 7231 6.5.2
  403: 'Forbidden',                  // RFC 7231 6.5.3
  404: 'Not Found',                  // RFC 7231 6.5.4
  405: 'Method Not Allowed',         // RFC 7231 6.5.5
  406: 'Not Acceptable',             // RFC 7231 6.5.6
  407: 'Proxy Authentication Required', // RFC 7235 3.2
  408: 'Request Timeout',            // RFC 7231 6.5.7
  409: 'Conflict',                   // RFC 7231 6.5.8
  410: 'Gone',                       // RFC 7231 6.5.9
  411: 'Length Required',            // RFC 7231 6.5.10
  412: 'Precondition Failed',        // RFC 7232 4.2
  413: 'Payload Too Large',          // RFC 7231 6.5.11
  414: 'URI Too Long',               // RFC 7231 6.5.12
  415: 'Unsupported Media Type',     // RFC 7231 6.5.13
  416: 'Range Not Satisfiable',      // RFC 7233 4.4
  417: 'Expectation Failed',         // RFC 7231 6.5.14
  418: 'I\'m a Teapot',              // RFC 7168 2.3.3
  421: 'Misdirected Request',        // RFC 7540 9.1.2
  422: 'Unprocessable Entity',       // RFC 4918 11.2
  423: 'Locked',                     // RFC 4918 11.3
  424: 'Failed Dependency',          // RFC 4918 11.4
  425: 'Too Early',                  // RFC 8470 5.2
  426: 'Upgrade Required',           // RFC 2817 and RFC 7231 6.5.15
  428: 'Precondition Required',      // RFC 6585 3
  429: 'Too Many Requests',          // RFC 6585 4
  431: 'Request Header Fields Too Large', // RFC 6585 5
  451: 'Unavailable For Legal Reasons', // RFC 7725 3
  500: 'Internal Server Error',      // RFC 7231 6.6.1
  501: 'Not Implemented',            // RFC 7231 6.6.2
  502: 'Bad Gateway',                // RFC 7231 6.6.3
  503: 'Service Unavailable',        // RFC 7231 6.6.4
  504: 'Gateway Timeout',            // RFC 7231 6.6.5
  505: 'HTTP Version Not Supported', // RFC 7231 6.6.6
  506: 'Variant Also Negotiates',    // RFC 2295 8.1
  507: 'Insufficient Storage',       // RFC 4918 11.5
  508: 'Loop Detected',              // RFC 5842 7.2
  509: 'Bandwidth Limit Exceeded',
  510: 'Not Extended',               // RFC 2774 7
  511: 'Network Authentication Required', // RFC 6585 6
};

const kOnExecute = HTTPParser.kOnExecute | 0;
const kOnTimeout = HTTPParser.kOnTimeout | 0;
const kLenientAll = HTTPParser.kLenientAll | 0;
const kLenientNone = HTTPParser.kLenientNone | 0;
const kConnections = Symbol('http.server.connections');
const kConnectionsCheckingInterval = Symbol('http.server.connectionsCheckingInterval');

const HTTP_SERVER_TRACE_EVENT_NAME = 'http.server.request';

class HTTPServerAsyncResource {
  constructor(type, socket) {
    this.type = type;
    this.socket = socket;
  }
}

function ServerResponse(req, options) {
  OutgoingMessage.call(this, options);

  if (req.method === 'HEAD') this._hasBody = false;

  this.req = req;
  this.sendDate = true;
  this._sent100 = false;
  this._expect_continue = false;

  if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
    this.useChunkedEncodingByDefault = RegExpPrototypeExec(chunkExpression,
                                                           req.headers.te) !== null;
    this.shouldKeepAlive = false;
  }

  if (hasObserver('http')) {
    startPerf(this, kServerResponseStatistics, {
      type: 'http',
      name: 'HttpRequest',
      detail: {
        req: {
          method: req.method,
          url: req.url,
          headers: req.headers,
        },
      },
    });
  }
  if (isTraceHTTPEnabled()) {
    this._traceEventId = getNextTraceEventId();
    traceBegin(HTTP_SERVER_TRACE_EVENT_NAME, this._traceEventId);
  }
}
ObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype);
ObjectSetPrototypeOf(ServerResponse, OutgoingMessage);

ServerResponse.prototype._finish = function _finish() {
  DTRACE_HTTP_SERVER_RESPONSE(this.socket);
  if (this[kServerResponseStatistics] && hasObserver('http')) {
    stopPerf(this, kServerResponseStatistics, {
      detail: {
        res: {
          statusCode: this.statusCode,
          statusMessage: this.statusMessage,
          headers: typeof this.getHeaders === 'function' ? this.getHeaders() : {},
        },
      },
    });
  }
  OutgoingMessage.prototype._finish.call(this);
  if (isTraceHTTPEnabled() && typeof this._traceEventId === 'number') {
    const data = {
      url: this.req?.url,
      statusCode: this.statusCode,
    };
    traceEnd(HTTP_SERVER_TRACE_EVENT_NAME, this._traceEventId, data);
  }
};


ServerResponse.prototype.statusCode = 200;
ServerResponse.prototype.statusMessage = undefined;

function onServerResponseClose() {
  // EventEmitter.emit makes a copy of the 'close' listeners array before
  // calling the listeners. detachSocket() unregisters onServerResponseClose
  // but if detachSocket() is called, directly or indirectly, by a 'close'
  // listener, onServerResponseClose is still in that copy of the listeners
  // array. That is, in the example below, b still gets called even though
  // it's been removed by a:
  //
  //   const EventEmitter = require('events');
  //   const obj = new EventEmitter();
  //   obj.on('event', a);
  //   obj.on('event', b);
  //   function a() { obj.removeListener('event', b) }
  //   function b() { throw "BAM!" }
  //   obj.emit('event');  // throws
  //
  // Ergo, we need to deal with stale 'close' events and handle the case
  // where the ServerResponse object has already been deconstructed.
  // Fortunately, that requires only a single if check. :-)
  if (this._httpMessage) {
    emitCloseNT(this._httpMessage);
  }
}

ServerResponse.prototype.assignSocket = function assignSocket(socket) {
  if (socket._httpMessage) {
    throw new ERR_HTTP_SOCKET_ASSIGNED();
  }
  socket._httpMessage = this;
  socket.on('close', onServerResponseClose);
  this.socket = socket;
  this.emit('socket', socket);
  this._flush();
};

ServerResponse.prototype.detachSocket = function detachSocket(socket) {
  assert(socket._httpMessage === this);
  socket.removeListener('close', onServerResponseClose);
  socket._httpMessage = null;
  this.socket = null;
};

ServerResponse.prototype.writeContinue = function writeContinue(cb) {
  this._writeRaw('HTTP/1.1 100 Continue\r\n\r\n', 'ascii', cb);
  this._sent100 = true;
};

ServerResponse.prototype.writeProcessing = function writeProcessing(cb) {
  this._writeRaw('HTTP/1.1 102 Processing\r\n\r\n', 'ascii', cb);
};

ServerResponse.prototype.writeEarlyHints = function writeEarlyHints(hints, cb) {
  let head = 'HTTP/1.1 103 Early Hints\r\n';

  validateObject(hints, 'hints');

  if (hints.link === null || hints.link === undefined) {
    return;
  }

  const link = validateLinkHeaderValue(hints.link);

  if (link.length === 0) {
    return;
  }

  head += 'Link: ' + link + '\r\n';

  for (const key of ObjectKeys(hints)) {
    if (key !== 'link') {
      head += key + ': ' + hints[key] + '\r\n';
    }
  }

  head += '\r\n';

  this._writeRaw(head, 'ascii', cb);
};

ServerResponse.prototype._implicitHeader = function _implicitHeader() {
  this.writeHead(this.statusCode);
};

ServerResponse.prototype.writeHead = writeHead;
function writeHead(statusCode, reason, obj) {
  const originalStatusCode = statusCode;

  statusCode |= 0;
  if (statusCode < 100 || statusCode > 999) {
    throw new ERR_HTTP_INVALID_STATUS_CODE(originalStatusCode);
  }


  if (typeof reason === 'string') {
    // writeHead(statusCode, reasonPhrase[, headers])
    this.statusMessage = reason;
  } else {
    // writeHead(statusCode[, headers])
    if (!this.statusMessage)
      this.statusMessage = STATUS_CODES[statusCode] || 'unknown';
    obj ??= reason;
  }
  this.statusCode = statusCode;

  let headers;
  if (this[kOutHeaders]) {
    // Slow-case: when progressive API and header fields are passed.
    let k;
    if (ArrayIsArray(obj)) {
      if (obj.length % 2 !== 0) {
        throw new ERR_INVALID_ARG_VALUE('headers', obj);
      }

      for (let n = 0; n < obj.length; n += 2) {
        k = obj[n + 0];
        if (k) this.setHeader(k, obj[n + 1]);
      }
    } else if (obj) {
      const keys = ObjectKeys(obj);
      // Retain for(;;) loop for performance reasons
      // Refs: https://github.com/nodejs/node/pull/30958
      for (let i = 0; i < keys.length; i++) {
        k = keys[i];
        if (k) this.setHeader(k, obj[k]);
      }
    }
    if (k === undefined && this._header) {
      throw new ERR_HTTP_HEADERS_SENT('render');
    }
    // Only progressive api is used
    headers = this[kOutHeaders];
  } else {
    // Only writeHead() called
    headers = obj;
  }

  if (checkInvalidHeaderChar(this.statusMessage))
    throw new ERR_INVALID_CHAR('statusMessage');

  const statusLine = `HTTP/1.1 ${statusCode} ${this.statusMessage}\r\n`;

  if (statusCode === 204 || statusCode === 304 ||
      (statusCode >= 100 && statusCode <= 199)) {
    // RFC 2616, 10.2.5:
    // The 204 response MUST NOT include a message-body, and thus is always
    // terminated by the first empty line after the header fields.
    // RFC 2616, 10.3.5:
    // The 304 response MUST NOT contain a message-body, and thus is always
    // terminated by the first empty line after the header fields.
    // RFC 2616, 10.1 Informational 1xx:
    // This class of status code indicates a provisional response,
    // consisting only of the Status-Line and optional headers, and is
    // terminated by an empty line.
    this._hasBody = false;
  }

  // Don't keep alive connections where the client expects 100 Continue
  // but we sent a final status; they may put extra bytes on the wire.
  if (this._expect_continue && !this._sent100) {
    this.shouldKeepAlive = false;
  }

  this._storeHeader(statusLine, headers);

  return this;
}

// Docs-only deprecated: DEP0063
ServerResponse.prototype.writeHeader = ServerResponse.prototype.writeHead;

function storeHTTPOptions(options) {
  this[kIncomingMessage] = options.IncomingMessage || IncomingMessage;
  this[kServerResponse] = options.ServerResponse || ServerResponse;

  const maxHeaderSize = options.maxHeaderSize;
  if (maxHeaderSize !== undefined)
    validateInteger(maxHeaderSize, 'maxHeaderSize', 0);
  this.maxHeaderSize = maxHeaderSize;

  const insecureHTTPParser = options.insecureHTTPParser;
  if (insecureHTTPParser !== undefined)
    validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');
  this.insecureHTTPParser = insecureHTTPParser;

  if (options.noDelay === undefined)
    options.noDelay = true;

  const requestTimeout = options.requestTimeout;
  if (requestTimeout !== undefined) {
    validateInteger(requestTimeout, 'requestTimeout', 0);
    this.requestTimeout = requestTimeout;
  } else {
    this.requestTimeout = 300_000; // 5 minutes
  }

  const headersTimeout = options.headersTimeout;
  if (headersTimeout !== undefined) {
    validateInteger(headersTimeout, 'headersTimeout', 0);
    this.headersTimeout = headersTimeout;
  } else {
    this.headersTimeout = MathMin(60_000, this.requestTimeout); // Minimum between 60 seconds or requestTimeout
  }

  if (this.requestTimeout > 0 && this.headersTimeout > 0 && this.headersTimeout > this.requestTimeout) {
    throw new codes.ERR_OUT_OF_RANGE('headersTimeout', '<= requestTimeout', headersTimeout);
  }

  const keepAliveTimeout = options.keepAliveTimeout;
  if (keepAliveTimeout !== undefined) {
    validateInteger(keepAliveTimeout, 'keepAliveTimeout', 0);
    this.keepAliveTimeout = keepAliveTimeout;
  } else {
    this.keepAliveTimeout = 5_000; // 5 seconds;
  }

  const connectionsCheckingInterval = options.connectionsCheckingInterval;
  if (connectionsCheckingInterval !== undefined) {
    validateInteger(connectionsCheckingInterval, 'connectionsCheckingInterval', 0);
    this.connectionsCheckingInterval = connectionsCheckingInterval;
  } else {
    this.connectionsCheckingInterval = 30_000; // 30 seconds
  }

  const joinDuplicateHeaders = options.joinDuplicateHeaders;
  if (joinDuplicateHeaders !== undefined) {
    validateBoolean(joinDuplicateHeaders, 'options.joinDuplicateHeaders');
  }
  this.joinDuplicateHeaders = joinDuplicateHeaders;

  const rejectNonStandardBodyWrites = options.rejectNonStandardBodyWrites;
  if (rejectNonStandardBodyWrites !== undefined) {
    validateBoolean(rejectNonStandardBodyWrites, 'options.rejectNonStandardBodyWrites');
    this.rejectNonStandardBodyWrites = rejectNonStandardBodyWrites;
  } else {
    this.rejectNonStandardBodyWrites = false;
  }
}

function setupConnectionsTracking() {
  // Start connection handling
  if (!this[kConnections]) {
    this[kConnections] = new ConnectionsList();
  }

  // This checker is started without checking whether any headersTimeout or requestTimeout is non zero
  // otherwise it would not be started if such timeouts are modified after createServer.
  this[kConnectionsCheckingInterval] =
    setInterval(checkConnections.bind(this), this.connectionsCheckingInterval).unref();
}

function httpServerPreClose(server) {
  clearInterval(server[kConnectionsCheckingInterval]);
}

function Server(options, requestListener) {
  if (!(this instanceof Server)) return new Server(options, requestListener);

  if (typeof options === 'function') {
    requestListener = options;
    options = {};
  } else if (options == null || typeof options === 'object') {
    options = { ...options };
  } else {
    throw new ERR_INVALID_ARG_TYPE('options', 'object', options);
  }

  storeHTTPOptions.call(this, options);
  net.Server.call(
    this,
    { allowHalfOpen: true, noDelay: options.noDelay,
      keepAlive: options.keepAlive,
      keepAliveInitialDelay: options.keepAliveInitialDelay,
      highWaterMark: options.highWaterMark });

  if (requestListener) {
    this.on('request', requestListener);
  }

  // Similar option to this. Too lazy to write my own docs.
  // http://www.squid-cache.org/Doc/config/half_closed_clients/
  // https://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
  this.httpAllowHalfOpen = false;

  this.on('connection', connectionListener);
  this.on('listening', setupConnectionsTracking);

  this.timeout = 0;
  this.maxHeadersCount = null;
  this.maxRequestsPerSocket = 0;

  this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);
}
ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
ObjectSetPrototypeOf(Server, net.Server);

Server.prototype.close = function() {
  httpServerPreClose(this);
  ReflectApply(net.Server.prototype.close, this, arguments);
};

Server.prototype.closeAllConnections = function() {
  if (!this[kConnections]) {
    return;
  }

  const connections = this[kConnections].all();

  for (let i = 0, l = connections.length; i < l; i++) {
    connections[i].socket.destroy();
  }
};

Server.prototype.closeIdleConnections = function() {
  if (!this[kConnections]) {
    return;
  }

  const connections = this[kConnections].idle();

  for (let i = 0, l = connections.length; i < l; i++) {
    if (connections[i].socket._httpMessage && !connections[i].socket._httpMessage.finished) {
      continue;
    }

    connections[i].socket.destroy();
  }
};

Server.prototype.setTimeout = function setTimeout(msecs, callback) {
  this.timeout = msecs;
  if (callback)
    this.on('timeout', callback);
  return this;
};

Server.prototype[EE.captureRejectionSymbol] = function(err, event, ...args) {
  switch (event) {
    case 'request': {
      const { 1: res } = args;
      if (!res.headersSent && !res.writableEnded) {
        // Don't leak headers.
        const names = res.getHeaderNames();
        for (let i = 0; i < names.length; i++) {
          res.removeHeader(names[i]);
        }
        res.statusCode = 500;
        res.end(STATUS_CODES[500]);
      } else {
        res.destroy();
      }
      break;
    }
    default:
      net.Server.prototype[SymbolFor('nodejs.rejection')]
        .apply(this, arguments);
  }
};

function checkConnections() {
  if (this.headersTimeout === 0 && this.requestTimeout === 0) {
    return;
  }

  const expired = this[kConnections].expired(this.headersTimeout, this.requestTimeout);

  for (let i = 0; i < expired.length; i++) {
    const socket = expired[i].socket;

    if (socket) {
      onRequestTimeout(socket);
    }
  }
}

function connectionListener(socket) {
  defaultTriggerAsyncIdScope(
    getOrSetAsyncId(socket), connectionListenerInternal, this, socket,
  );
}

function connectionListenerInternal(server, socket) {
  debug('SERVER new http connection');

  // Ensure that the server property of the socket is correctly set.
  // See https://github.com/nodejs/node/issues/13435
  socket.server = server;

  // If the user has added a listener to the server,
  // request, or response, then it's their responsibility.
  // otherwise, destroy on timeout by default
  if (server.timeout && typeof socket.setTimeout === 'function')
    socket.setTimeout(server.timeout);
  socket.on('timeout', socketOnTimeout);

  const parser = parsers.alloc();

  const lenient = server.insecureHTTPParser === undefined ?
    isLenient() : server.insecureHTTPParser;

  // TODO(addaleax): This doesn't play well with the
  // `async_hooks.currentResource()` proposal, see
  // https://github.com/nodejs/node/pull/21313
  parser.initialize(
    HTTPParser.REQUEST,
    new HTTPServerAsyncResource('HTTPINCOMINGMESSAGE', socket),
    server.maxHeaderSize || 0,
    lenient ? kLenientAll : kLenientNone,
    server[kConnections],
  );
  parser.socket = socket;
  socket.parser = parser;

  // Propagate headers limit from server instance to parser
  if (typeof server.maxHeadersCount === 'number') {
    parser.maxHeaderPairs = server.maxHeadersCount << 1;
  }

  const state = {
    onData: null,
    onEnd: null,
    onClose: null,
    onDrain: null,
    outgoing: [],
    incoming: [],
    // `outgoingData` is an approximate amount of bytes queued through all
    // inactive responses. If more data than the high watermark is queued - we
    // need to pause TCP socket/HTTP parser, and wait until the data will be
    // sent to the client.
    outgoingData: 0,
    requestsCount: 0,
    keepAliveTimeoutSet: false,
  };
  state.onData = socketOnData.bind(undefined,
                                   server, socket, parser, state);
  state.onEnd = socketOnEnd.bind(undefined,
                                 server, socket, parser, state);
  state.onClose = socketOnClose.bind(undefined,
                                     socket, state);
  state.onDrain = socketOnDrain.bind(undefined,
                                     socket, state);
  socket.on('data', state.onData);
  socket.on('error', socketOnError);
  socket.on('end', state.onEnd);
  socket.on('close', state.onClose);
  socket.on('drain', state.onDrain);
  parser.onIncoming = parserOnIncoming.bind(undefined,
                                            server, socket, state);

  // We are consuming socket, so it won't get any actual data
  socket.on('resume', onSocketResume);
  socket.on('pause', onSocketPause);

  // Overrides to unconsume on `data`, `readable` listeners
  socket.on = generateSocketListenerWrapper('on');
  socket.addListener = generateSocketListenerWrapper('addListener');
  socket.prependListener = generateSocketListenerWrapper('prependListener');
  socket.setEncoding = socketSetEncoding;

  // We only consume the socket if it has never been consumed before.
  if (socket._handle && socket._handle.isStreamBase &&
      !socket._handle._consumed) {
    parser._consumed = true;
    socket._handle._consumed = true;
    parser.consume(socket._handle);
  }
  parser[kOnExecute] =
    onParserExecute.bind(undefined,
                         server, socket, parser, state);

  parser[kOnTimeout] =
    onParserTimeout.bind(undefined,
                         server, socket);

  socket._paused = false;
}

function socketSetEncoding() {
  throw new ERR_HTTP_SOCKET_ENCODING();
}

function updateOutgoingData(socket, state, delta) {
  state.outgoingData += delta;
  socketOnDrain(socket, state);
}

function socketOnDrain(socket, state) {
  const needPause = state.outgoingData > socket.writableHighWaterMark;

  // If we previously paused, then start reading again.
  if (socket._paused && !needPause) {
    socket._paused = false;
    if (socket.parser)
      socket.parser.resume();
    socket.resume();
  }

  const msg = socket._httpMessage;
  if (msg && !msg.finished && msg[kNeedDrain]) {
    msg[kNeedDrain] = false;
    msg.emit('drain');
  }
}

function socketOnTimeout() {
  const req = this.parser && this.parser.incoming;
  const reqTimeout = req && !req.complete && req.emit('timeout', this);
  const res = this._httpMessage;
  const resTimeout = res && res.emit('timeout', this);
  const serverTimeout = this.server.emit('timeout', this);

  if (!reqTimeout && !resTimeout && !serverTimeout)
    this.destroy();
}

function socketOnClose(socket, state) {
  debug('server socket close');
  freeParser(socket.parser, null, socket);
  abortIncoming(state.incoming);
}

function abortIncoming(incoming) {
  while (incoming.length) {
    const req = incoming.shift();
    req.destroy(connResetException('aborted'));
  }
  // Abort socket._httpMessage ?
}

function socketOnEnd(server, socket, parser, state) {
  const ret = parser.finish();

  if (ret instanceof Error) {
    debug('parse error');
    // socketOnError has additional logic and will call socket.destroy(err).
    socketOnError.call(socket, ret);
  } else if (!server.httpAllowHalfOpen) {
    socket.end();
  } else if (state.outgoing.length) {
    state.outgoing[state.outgoing.length - 1]._last = true;
  } else if (socket._httpMessage) {
    socket._httpMessage._last = true;
  } else {
    socket.end();
  }
}

function socketOnData(server, socket, parser, state, d) {
  assert(!socket._paused);
  debug('SERVER socketOnData %d', d.length);

  const ret = parser.execute(d);
  onParserExecuteCommon(server, socket, parser, state, ret, d);
}

function onRequestTimeout(socket) {
  // socketOnError has additional logic and will call socket.destroy(err).
  socketOnError.call(socket, new ERR_HTTP_REQUEST_TIMEOUT());
}

function onParserExecute(server, socket, parser, state, ret) {
  // When underlying `net.Socket` instance is consumed - no
  // `data` events are emitted, and thus `socket.setTimeout` fires the
  // callback even if the data is constantly flowing into the socket.
  // See, https://github.com/nodejs/node/commit/ec2822adaad76b126b5cccdeaa1addf2376c9aa6
  socket._unrefTimer();
  debug('SERVER socketOnParserExecute %d', ret);
  onParserExecuteCommon(server, socket, parser, state, ret, undefined);
}

function onParserTimeout(server, socket) {
  const serverTimeout = server.emit('timeout', socket);

  if (!serverTimeout)
    socket.destroy();
}

const noop = () => {};
const badRequestResponse = Buffer.from(
  `HTTP/1.1 400 ${STATUS_CODES[400]}\r\n` +
  'Connection: close\r\n\r\n', 'ascii',
);
const requestTimeoutResponse = Buffer.from(
  `HTTP/1.1 408 ${STATUS_CODES[408]}\r\n` +
  'Connection: close\r\n\r\n', 'ascii',
);
const requestHeaderFieldsTooLargeResponse = Buffer.from(
  `HTTP/1.1 431 ${STATUS_CODES[431]}\r\n` +
  'Connection: close\r\n\r\n', 'ascii',
);

const requestChunkExtensionsTooLargeResponse = Buffer.from(
  `HTTP/1.1 413 ${STATUS_CODES[413]}\r\n` +
  'Connection: close\r\n\r\n', 'ascii',
);

function warnUnclosedSocket() {
  if (warnUnclosedSocket.emitted) {
    return;
  }

  warnUnclosedSocket.emitted = true;
  process.emitWarning(
    'An error event has already been emitted on the socket. ' +
    'Please use the destroy method on the socket while handling ' +
    "a 'clientError' event.",
  );
}

function socketOnError(e) {
  // Ignore further errors
  this.removeListener('error', socketOnError);

  if (this.listenerCount('error', noop) === 0) {
    this.on('error', noop);
  } else {
    warnUnclosedSocket();
  }

  if (!this.server.emit('clientError', e, this)) {
    // Caution must be taken to avoid corrupting the remote peer.
    // Reply an error segment if there is no in-flight `ServerResponse`,
    // or no data of the in-flight one has been written yet to this socket.
    if (this.writable &&
        (!this._httpMessage || !this._httpMessage._headerSent)) {
      let response;

      switch (e.code) {
        case 'HPE_HEADER_OVERFLOW':
          response = requestHeaderFieldsTooLargeResponse;
          break;
        case 'HPE_CHUNK_EXTENSIONS_OVERFLOW':
          response = requestChunkExtensionsTooLargeResponse;
          break;
        case 'ERR_HTTP_REQUEST_TIMEOUT':
          response = requestTimeoutResponse;
          break;
        default:
          response = badRequestResponse;
          break;
      }

      this.write(response);
    }
    this.destroy(e);
  }
}

function onParserExecuteCommon(server, socket, parser, state, ret, d) {
  resetSocketTimeout(server, socket, state);

  if (ret instanceof Error) {
    prepareError(ret, parser, d);
    debug('parse error', ret);
    socketOnError.call(socket, ret);
  } else if (parser.incoming && parser.incoming.upgrade) {
    // Upgrade or CONNECT
    const req = parser.incoming;
    debug('SERVER upgrade or connect', req.method);

    if (!d)
      d = parser.getCurrentBuffer();

    socket.removeListener('data', state.onData);
    socket.removeListener('end', state.onEnd);
    socket.removeListener('close', state.onClose);
    socket.removeListener('drain', state.onDrain);
    socket.removeListener('error', socketOnError);
    socket.removeListener('timeout', socketOnTimeout);
    unconsume(parser, socket);
    parser.finish();
    freeParser(parser, req, socket);
    parser = null;

    const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
    if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) {
      debug('SERVER have listener for %s', eventName);
      const bodyHead = d.slice(ret, d.length);

      socket.readableFlowing = null;

      server.emit(eventName, req, socket, bodyHead);
    } else {
      // Got CONNECT method, but have no handler.
      socket.destroy();
    }
  } else if (parser.incoming && parser.incoming.method === 'PRI') {
    debug('SERVER got PRI request');
    socket.destroy();
  }

  if (socket._paused && socket.parser) {
    // onIncoming paused the socket, we should pause the parser as well
    debug('pause parser');
    socket.parser.pause();
  }
}

function clearIncoming(req) {
  req = req || this;
  const parser = req.socket && req.socket.parser;
  // Reset the .incoming property so that the request object can be gc'ed.
  if (parser && parser.incoming === req) {
    if (req.readableEnded) {
      parser.incoming = null;
    } else {
      req.on('end', clearIncoming);
    }
  }
}

function resOnFinish(req, res, socket, state, server) {
  if (onResponseFinishChannel.hasSubscribers) {
    onResponseFinishChannel.publish({
      request: req,
      response: res,
      socket,
      server,
    });
  }

  // Usually the first incoming element should be our request.  it may
  // be that in the case abortIncoming() was called that the incoming
  // array will be empty.
  assert(state.incoming.length === 0 || state.incoming[0] === req);

  state.incoming.shift();

  // If the user never called req.read(), and didn't pipe() or
  // .resume() or .on('data'), then we call req._dump() so that the
  // bytes will be pulled off the wire.
  if (!req._consuming && !req._readableState.resumeScheduled)
    req._dump();

  res.detachSocket(socket);
  clearIncoming(req);
  process.nextTick(emitCloseNT, res);

  if (res._last) {
    if (typeof socket.destroySoon === 'function') {
      socket.destroySoon();
    } else {
      socket.end();
    }
  } else if (state.outgoing.length === 0) {
    if (server.keepAliveTimeout && typeof socket.setTimeout === 'function') {
      socket.setTimeout(server.keepAliveTimeout);
      state.keepAliveTimeoutSet = true;
    }
  } else {
    // Start sending the next message
    const m = state.outgoing.shift();
    if (m) {
      m.assignSocket(socket);
    }
  }
}

function emitCloseNT(self) {
  if (!self._closed) {
    self.destroyed = true;
    self._closed = true;
    self.emit('close');
  }
}

// The following callback is issued after the headers have been read on a
// new message. In this callback we setup the response object and pass it
// to the user.
function parserOnIncoming(server, socket, state, req, keepAlive) {
  resetSocketTimeout(server, socket, state);

  if (req.upgrade) {
    req.upgrade = req.method === 'CONNECT' ||
                  server.listenerCount('upgrade') > 0;
    if (req.upgrade)
      return 2;
  }

  state.incoming.push(req);

  // If the writable end isn't consuming, then stop reading
  // so that we don't become overwhelmed by a flood of
  // pipelined requests that may never be resolved.
  if (!socket._paused) {
    const ws = socket._writableState;
    if (ws.needDrain || state.outgoingData >= socket.writableHighWaterMark) {
      socket._paused = true;
      // We also need to pause the parser, but don't do that until after
      // the call to execute, because we may still be processing the last
      // chunk.
      socket.pause();
    }
  }

  const res = new server[kServerResponse](req,
                                          {
                                            highWaterMark: socket.writableHighWaterMark,
                                            rejectNonStandardBodyWrites: server.rejectNonStandardBodyWrites,
                                          });
  res._keepAliveTimeout = server.keepAliveTimeout;
  res._maxRequestsPerSocket = server.maxRequestsPerSocket;
  res._onPendingData = updateOutgoingData.bind(undefined,
                                               socket, state);

  res.shouldKeepAlive = keepAlive;
  res[kUniqueHeaders] = server[kUniqueHeaders];
  DTRACE_HTTP_SERVER_REQUEST(req, socket);

  if (onRequestStartChannel.hasSubscribers) {
    onRequestStartChannel.publish({
      request: req,
      response: res,
      socket,
      server,
    });
  }

  if (socket._httpMessage) {
    // There are already pending outgoing res, append.
    state.outgoing.push(res);
  } else {
    res.assignSocket(socket);
  }

  // When we're finished writing the response, check if this is the last
  // response, if so destroy the socket.
  res.on('finish',
         resOnFinish.bind(undefined,
                          req, res, socket, state, server));

  let handled = false;

  if (req.httpVersionMajor === 1 && req.httpVersionMinor === 1) {
    const isRequestsLimitSet = (
      typeof server.maxRequestsPerSocket === 'number' &&
      server.maxRequestsPerSocket > 0
    );

    if (isRequestsLimitSet) {
      state.requestsCount++;
      res.maxRequestsOnConnectionReached = (
        server.maxRequestsPerSocket <= state.requestsCount);
    }

    if (isRequestsLimitSet &&
      (server.maxRequestsPerSocket < state.requestsCount)) {
      handled = true;
      server.emit('dropRequest', req, socket);
      res.writeHead(503);
      res.end();
    } else if (req.headers.expect !== undefined) {
      handled = true;

      if (RegExpPrototypeExec(continueExpression, req.headers.expect) !== null) {
        res._expect_continue = true;

        if (server.listenerCount('checkContinue') > 0) {
          server.emit('checkContinue', req, res);
        } else {
          res.writeContinue();
          server.emit('request', req, res);
        }
      } else if (server.listenerCount('checkExpectation') > 0) {
        server.emit('checkExpectation', req, res);
      } else {
        res.writeHead(417);
        res.end();
      }
    }
  }

  if (!handled) {
    server.emit('request', req, res);
  }

  return 0;  // No special treatment.
}

function resetSocketTimeout(server, socket, state) {
  if (!state.keepAliveTimeoutSet)
    return;

  socket.setTimeout(server.timeout || 0);
  state.keepAliveTimeoutSet = false;
}

function onSocketResume() {
  // It may seem that the socket is resumed, but this is an enemy's trick to
  // deceive us! `resume` is emitted asynchronously, and may be called from
  // `incoming.readStart()`. Stop the socket again here, just to preserve the
  // state.
  //
  // We don't care about stream semantics for the consumed socket anyway.
  if (this._paused) {
    this.pause();
    return;
  }

  if (this._handle && !this._handle.reading) {
    this._handle.reading = true;
    this._handle.readStart();
  }
}

function onSocketPause() {
  if (this._handle && this._handle.reading) {
    this._handle.reading = false;
    this._handle.readStop();
  }
}

function unconsume(parser, socket) {
  if (socket._handle) {
    if (parser._consumed)
      parser.unconsume();
    parser._consumed = false;
    socket.removeListener('pause', onSocketPause);
    socket.removeListener('resume', onSocketResume);
  }
}

function generateSocketListenerWrapper(originalFnName) {
  return function socketListenerWrap(ev, fn) {
    const res = net.Socket.prototype[originalFnName].call(this,
                                                          ev, fn);
    if (!this.parser) {
      this.on = net.Socket.prototype.on;
      this.addListener = net.Socket.prototype.addListener;
      this.prependListener = net.Socket.prototype.prependListener;
      return res;
    }

    if (ev === 'data' || ev === 'readable')
      unconsume(this.parser, this);

    return res;
  };
}

module.exports = {
  STATUS_CODES,
  Server,
  ServerResponse,
  setupConnectionsTracking,
  storeHTTPOptions,
  _connectionListener: connectionListener,
  kServerResponse,
  httpServerPreClose,
  kConnectionsCheckingInterval,
};
      // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  Array,
  ArrayIsArray,
  ArrayPrototypeJoin,
  MathFloor,
  NumberPrototypeToString,
  ObjectCreate,
  ObjectDefineProperty,
  ObjectKeys,
  ObjectValues,
  ObjectPrototypeHasOwnProperty,
  ObjectSetPrototypeOf,
  RegExpPrototypeExec,
  SafeSet,
  StringPrototypeToLowerCase,
  Symbol,
} = primordials;

const { getDefaultHighWaterMark } = require('internal/streams/state');
const assert = require('internal/assert');
const EE = require('events');
const Stream = require('stream');
const internalUtil = require('internal/util');
const { kOutHeaders, utcDate, kNeedDrain } = require('internal/http');
const { Buffer } = require('buffer');
const {
  _checkIsHttpToken: checkIsHttpToken,
  _checkInvalidHeaderChar: checkInvalidHeaderChar,
  chunkExpression: RE_TE_CHUNKED,
} = require('_http_common');
const {
  defaultTriggerAsyncIdScope,
  symbols: { async_id_symbol },
} = require('internal/async_hooks');
const {
  codes: {
    ERR_HTTP_CONTENT_LENGTH_MISMATCH,
    ERR_HTTP_HEADERS_SENT,
    ERR_HTTP_INVALID_HEADER_VALUE,
    ERR_HTTP_TRAILER_INVALID,
    ERR_HTTP_BODY_NOT_ALLOWED,
    ERR_INVALID_HTTP_TOKEN,
    ERR_INVALID_ARG_TYPE,
    ERR_INVALID_ARG_VALUE,
    ERR_INVALID_CHAR,
    ERR_METHOD_NOT_IMPLEMENTED,
    ERR_STREAM_CANNOT_PIPE,
    ERR_STREAM_ALREADY_FINISHED,
    ERR_STREAM_WRITE_AFTER_END,
    ERR_STREAM_NULL_VALUES,
    ERR_STREAM_DESTROYED,
  },
  hideStackFrames,
} = require('internal/errors');
const { validateString } = require('internal/validators');
const { isUint8Array } = require('internal/util/types');

let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
  debug = fn;
});

const kCorked = Symbol('corked');
const kUniqueHeaders = Symbol('kUniqueHeaders');
const kBytesWritten = Symbol('kBytesWritten');
const kErrored = Symbol('errored');
const kHighWaterMark = Symbol('kHighWaterMark');
const kRejectNonStandardBodyWrites = Symbol('kRejectNonStandardBodyWrites');

const nop = () => {};

const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i;

// isCookieField performs a case-insensitive comparison of a provided string
// against the word "cookie." As of V8 6.6 this is faster than handrolling or
// using a case-insensitive RegExp.
function isCookieField(s) {
  return s.length === 6 && StringPrototypeToLowerCase(s) === 'cookie';
}

function isContentDispositionField(s) {
  return s.length === 19 && StringPrototypeToLowerCase(s) === 'content-disposition';
}

function OutgoingMessage(options) {
  Stream.call(this);

  // Queue that holds all currently pending data, until the response will be
  // assigned to the socket (until it will its turn in the HTTP pipeline).
  this.outputData = [];

  // `outputSize` is an approximate measure of how much data is queued on this
  // response. `_onPendingData` will be invoked to update similar global
  // per-connection counter. That counter will be used to pause/unpause the
  // TCP socket and HTTP Parser and thus handle the backpressure.
  this.outputSize = 0;

  this.writable = true;
  this.destroyed = false;

  this._last = false;
  this.chunkedEncoding = false;
  this.shouldKeepAlive = true;
  this.maxRequestsOnConnectionReached = false;
  this._defaultKeepAlive = true;
  this.useChunkedEncodingByDefault = true;
  this.sendDate = false;
  this._removedConnection = false;
  this._removedContLen = false;
  this._removedTE = false;

  this.strictContentLength = false;
  this[kBytesWritten] = 0;
  this._contentLength = null;
  this._hasBody = true;
  this._trailer = '';
  this[kNeedDrain] = false;

  this.finished = false;
  this._headerSent = false;
  this[kCorked] = 0;
  this._closed = false;

  this.socket = null;
  this._header = null;
  this[kOutHeaders] = null;

  this._keepAliveTimeout = 0;

  this._onPendingData = nop;

  this[kErrored] = null;
  this[kHighWaterMark] = options?.highWaterMark ?? getDefaultHighWaterMark();
  this[kRejectNonStandardBodyWrites] = options?.rejectNonStandardBodyWrites ?? false;
}
ObjectSetPrototypeOf(OutgoingMessage.prototype, Stream.prototype);
ObjectSetPrototypeOf(OutgoingMessage, Stream);

ObjectDefineProperty(OutgoingMessage.prototype, 'errored', {
  __proto__: null,
  get() {
    return this[kErrored];
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'closed', {
  __proto__: null,
  get() {
    return this._closed;
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableFinished', {
  __proto__: null,
  get() {
    return (
      this.finished &&
      this.outputSize === 0 &&
      (!this.socket || this.socket.writableLength === 0)
    );
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableObjectMode', {
  __proto__: null,
  get() {
    return false;
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableLength', {
  __proto__: null,
  get() {
    return this.outputSize + (this.socket ? this.socket.writableLength : 0);
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableHighWaterMark', {
  __proto__: null,
  get() {
    return this.socket ? this.socket.writableHighWaterMark : this[kHighWaterMark];
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableCorked', {
  __proto__: null,
  get() {
    const corked = this.socket ? this.socket.writableCorked : 0;
    return corked + this[kCorked];
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, '_headers', {
  __proto__: null,
  get: internalUtil.deprecate(function() {
    return this.getHeaders();
  }, 'OutgoingMessage.prototype._headers is deprecated', 'DEP0066'),
  set: internalUtil.deprecate(function(val) {
    if (val == null) {
      this[kOutHeaders] = null;
    } else if (typeof val === 'object') {
      const headers = this[kOutHeaders] = ObjectCreate(null);
      const keys = ObjectKeys(val);
      // Retain for(;;) loop for performance reasons
      // Refs: https://github.com/nodejs/node/pull/30958
      for (let i = 0; i < keys.length; ++i) {
        const name = keys[i];
        headers[StringPrototypeToLowerCase(name)] = [name, val[name]];
      }
    }
  }, 'OutgoingMessage.prototype._headers is deprecated', 'DEP0066'),
});

ObjectDefineProperty(OutgoingMessage.prototype, 'connection', {
  __proto__: null,
  get: function() {
    return this.socket;
  },
  set: function(val) {
    this.socket = val;
  },
});

ObjectDefineProperty(OutgoingMessage.prototype, '_headerNames', {
  __proto__: null,
  get: internalUtil.deprecate(function() {
    const headers = this[kOutHeaders];
    if (headers !== null) {
      const out = ObjectCreate(null);
      const keys = ObjectKeys(headers);
      // Retain for(;;) loop for performance reasons
      // Refs: https://github.com/nodejs/node/pull/30958
      for (let i = 0; i < keys.length; ++i) {
        const key = keys[i];
        const val = headers[key][0];
        out[key] = val;
      }
      return out;
    }
    return null;
  }, 'OutgoingMessage.prototype._headerNames is deprecated', 'DEP0066'),
  set: internalUtil.deprecate(function(val) {
    if (typeof val === 'object' && val !== null) {
      const headers = this[kOutHeaders];
      if (!headers)
        return;
      const keys = ObjectKeys(val);
      // Retain for(;;) loop for performance reasons
      // Refs: https://github.com/nodejs/node/pull/30958
      for (let i = 0; i < keys.length; ++i) {
        const header = headers[keys[i]];
        if (header)
          header[0] = val[keys[i]];
      }
    }
  }, 'OutgoingMessage.prototype._headerNames is deprecated', 'DEP0066'),
});


OutgoingMessage.prototype._renderHeaders = function _renderHeaders() {
  if (this._header) {
    throw new ERR_HTTP_HEADERS_SENT('render');
  }

  const headersMap = this[kOutHeaders];
  const headers = {};

  if (headersMap !== null) {
    const keys = ObjectKeys(headersMap);
    // Retain for(;;) loop for performance reasons
    // Refs: https://github.com/nodejs/node/pull/30958
    for (let i = 0, l = keys.length; i < l; i++) {
      const key = keys[i];
      headers[headersMap[key][0]] = headersMap[key][1];
    }
  }
  return headers;
};

OutgoingMessage.prototype.cork = function() {
  if (this.socket) {
    this.socket.cork();
  } else {
    this[kCorked]++;
  }
};

OutgoingMessage.prototype.uncork = function() {
  if (this.socket) {
    this.socket.uncork();
  } else if (this[kCorked]) {
    this[kCorked]--;
  }
};

OutgoingMessage.prototype.setTimeout = function setTimeout(msecs, callback) {

  if (callback) {
    this.on('timeout', callback);
  }

  if (!this.socket) {
    this.once('socket', function socketSetTimeoutOnConnect(socket) {
      socket.setTimeout(msecs);
    });
  } else {
    this.socket.setTimeout(msecs);
  }
  return this;
};


// It's possible that the socket will be destroyed, and removed from
// any messages, before ever calling this.  In that case, just skip
// it, since something else is destroying this connection anyway.
OutgoingMessage.prototype.destroy = function destroy(error) {
  if (this.destroyed) {
    return this;
  }
  this.destroyed = true;

  this[kErrored] = error;

  if (this.socket) {
    this.socket.destroy(error);
  } else {
    this.once('socket', function socketDestroyOnConnect(socket) {
      socket.destroy(error);
    });
  }

  return this;
};


// This abstract either writing directly to the socket or buffering it.
OutgoingMessage.prototype._send = function _send(data, encoding, callback, byteLength) {
  // This is a shameful hack to get the headers and first body chunk onto
  // the same packet. Future versions of Node are going to take care of
  // this at a lower level and in a more general way.
  if (!this._headerSent && this._header !== null) {
    // `this._header` can be null if OutgoingMessage is used without a proper Socket
    // See: /test/parallel/test-http-outgoing-message-inheritance.js
    if (typeof data === 'string' &&
        (encoding === 'utf8' || encoding === 'latin1' || !encoding)) {
      data = this._header + data;
    } else {
      const header = this._header;
      this.outputData.unshift({
        data: header,
        encoding: 'latin1',
        callback: null,
      });
      this.outputSize += header.length;
      this._onPendingData(header.length);
    }
    this._headerSent = true;
  }
  return this._writeRaw(data, encoding, callback, byteLength);
};

OutgoingMessage.prototype._writeRaw = _writeRaw;
function _writeRaw(data, encoding, callback, size) {
  const conn = this.socket;
  if (conn && conn.destroyed) {
    // The socket was destroyed. If we're still trying to write to it,
    // then we haven't gotten the 'close' event yet.
    return false;
  }

  if (typeof encoding === 'function') {
    callback = encoding;
    encoding = null;
  }

  if (conn && conn._httpMessage === this && conn.writable) {
    // There might be pending data in the this.output buffer.
    if (this.outputData.length) {
      this._flushOutput(conn);
    }
    // Directly write to socket.
    return conn.write(data, encoding, callback);
  }
  // Buffer, as long as we're not destroyed.
  this.outputData.push({ data, encoding, callback });
  this.outputSize += data.length;
  this._onPendingData(data.length);
  return this.outputSize < this[kHighWaterMark];
}


OutgoingMessage.prototype._storeHeader = _storeHeader;
function _storeHeader(firstLine, headers) {
  // firstLine in the case of request is: 'GET /index.html HTTP/1.1\r\n'
  // in the case of response it is: 'HTTP/1.1 200 OK\r\n'
  const state = {
    connection: false,
    contLen: false,
    te: false,
    date: false,
    expect: false,
    trailer: false,
    header: firstLine,
  };

  if (headers) {
    if (headers === this[kOutHeaders]) {
      for (const key in headers) {
        const entry = headers[key];
        processHeader(this, state, entry[0], entry[1], false);
      }
    } else if (ArrayIsArray(headers)) {
      if (headers.length && ArrayIsArray(headers[0])) {
        for (let i = 0; i < headers.length; i++) {
          const entry = headers[i];
          processHeader(this, state, entry[0], entry[1], true);
        }
      } else {
        if (headers.length % 2 !== 0) {
          throw new ERR_INVALID_ARG_VALUE('headers', headers);
        }

        for (let n = 0; n < headers.length; n += 2) {
          processHeader(this, state, headers[n + 0], headers[n + 1], true);
        }
      }
    } else {
      for (const key in headers) {
        if (ObjectPrototypeHasOwnProperty(headers, key)) {
          processHeader(this, state, key, headers[key], true);
        }
      }
    }
  }

  let { header } = state;

  // Date header
  if (this.sendDate && !state.date) {
    header += 'Date: ' + utcDate() + '\r\n';
  }

  // Force the connection to close when the response is a 204 No Content or
  // a 304 Not Modified and the user has set a "Transfer-Encoding: chunked"
  // header.
  //
  // RFC 2616 mandates that 204 and 304 responses MUST NOT have a body but
  // node.js used to send out a zero chunk anyway to accommodate clients
  // that don't have special handling for those responses.
  //
  // It was pointed out that this might confuse reverse proxies to the point
  // of creating security liabilities, so suppress the zero chunk and force
  // the connection to close.
  if (this.chunkedEncoding && (this.statusCode === 204 ||
                               this.statusCode === 304)) {
    debug(this.statusCode + ' response should not use chunked encoding,' +
          ' closing connection.');
    this.chunkedEncoding = false;
    this.shouldKeepAlive = false;
  }

  // keep-alive logic
  if (this._removedConnection) {
    this._last = true;
    this.shouldKeepAlive = false;
  } else if (!state.connection) {
    const shouldSendKeepAlive = this.shouldKeepAlive &&
        (state.contLen || this.useChunkedEncodingByDefault || this.agent);
    if (shouldSendKeepAlive && this.maxRequestsOnConnectionReached) {
      header += 'Connection: close\r\n';
    } else if (shouldSendKeepAlive) {
      header += 'Connection: keep-alive\r\n';
      if (this._keepAliveTimeout && this._defaultKeepAlive) {
        const timeoutSeconds = MathFloor(this._keepAliveTimeout / 1000);
        let max = '';
        if (~~this._maxRequestsPerSocket > 0) {
          max = `, max=${this._maxRequestsPerSocket}`;
        }
        header += `Keep-Alive: timeout=${timeoutSeconds}${max}\r\n`;
      }
    } else {
      this._last = true;
      header += 'Connection: close\r\n';
    }
  }

  if (!state.contLen && !state.te) {
    if (!this._hasBody) {
      // Make sure we don't end the 0\r\n\r\n at the end of the message.
      this.chunkedEncoding = false;
    } else if (!this.useChunkedEncodingByDefault) {
      this._last = true;
    } else if (!state.trailer &&
               !this._removedContLen &&
               typeof this._contentLength === 'number') {
      header += 'Content-Length: ' + this._contentLength + '\r\n';
    } else if (!this._removedTE) {
      header += 'Transfer-Encoding: chunked\r\n';
      this.chunkedEncoding = true;
    } else {
      // We should only be able to get here if both Content-Length and
      // Transfer-Encoding are removed by the user.
      // See: test/parallel/test-http-remove-header-stays-removed.js
      debug('Both Content-Length and Transfer-Encoding are removed');
    }
  }

  // Test non-chunked message does not have trailer header set,
  // message will be terminated by the first empty line after the
  // header fields, regardless of the header fields present in the
  // message, and thus cannot contain a message body or 'trailers'.
  if (this.chunkedEncoding !== true && state.trailer) {
    throw new ERR_HTTP_TRAILER_INVALID();
  }

  this._header = header + '\r\n';
  this._headerSent = false;

  // Wait until the first body chunk, or close(), is sent to flush,
  // UNLESS we're sending Expect: 100-continue.
  if (state.expect) this._send('');
}

function processHeader(self, state, key, value, validate) {
  if (validate)
    validateHeaderName(key);

  // If key is content-disposition and there is content-length
  // encode the value in latin1
  // https://www.rfc-editor.org/rfc/rfc6266#section-4.3
  // Refs: https://github.com/nodejs/node/pull/46528
  if (isContentDispositionField(key) && self._contentLength) {
    // The value could be an array here
    if (ArrayIsArray(value)) {
      for (let i = 0; i < value.length; i++) {
        value[i] = Buffer.from(value[i], 'latin1');
      }
    } else {
      value = Buffer.from(value, 'latin1');
    }
  }

  if (ArrayIsArray(value)) {
    if (
      (value.length < 2 || !isCookieField(key)) &&
      (!self[kUniqueHeaders] || !self[kUniqueHeaders].has(StringPrototypeToLowerCase(key)))
    ) {
      // Retain for(;;) loop for performance reasons
      // Refs: https://github.com/nodejs/node/pull/30958
      for (let i = 0; i < value.length; i++)
        storeHeader(self, state, key, value[i], validate);
      return;
    }
    value = ArrayPrototypeJoin(value, '; ');
  }
  storeHeader(self, state, key, value, validate);
}

function storeHeader(self, state, key, value, validate) {
  if (validate)
    validateHeaderValue(key, value);
  state.header += key + ': ' + value + '\r\n';
  matchHeader(self, state, key, value);
}

function matchHeader(self, state, field, value) {
  if (field.length < 4 || field.length > 17)
    return;
  field = StringPrototypeToLowerCase(field);
  switch (field) {
    case 'connection':
      state.connection = true;
      self._removedConnection = false;
      if (RegExpPrototypeExec(RE_CONN_CLOSE, value) !== null)
        self._last = true;
      else
        self.shouldKeepAlive = true;
      break;
    case 'transfer-encoding':
      state.te = true;
      self._removedTE = false;
      if (RegExpPrototypeExec(RE_TE_CHUNKED, value) !== null)
        self.chunkedEncoding = true;
      break;
    case 'content-length':
      state.contLen = true;
      self._contentLength = value;
      self._removedContLen = false;
      break;
    case 'date':
    case 'expect':
    case 'trailer':
      state[field] = true;
      break;
    case 'keep-alive':
      self._defaultKeepAlive = false;
      break;
  }
}

const validateHeaderName = hideStackFrames((name, label) => {
  if (typeof name !== 'string' || !name || !checkIsHttpToken(name)) {
    throw new ERR_INVALID_HTTP_TOKEN(label || 'Header name', name);
  }
});

const validateHeaderValue = hideStackFrames((name, value) => {
  if (value === undefined) {
    throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
  }
  if (checkInvalidHeaderChar(value)) {
    debug('Header "%s" contains invalid characters', name);
    throw new ERR_INVALID_CHAR('header content', name);
  }
});

function parseUniqueHeadersOption(headers) {
  if (!ArrayIsArray(headers)) {
    return null;
  }

  const unique = new SafeSet();
  const l = headers.length;
  for (let i = 0; i < l; i++) {
    unique.add(StringPrototypeToLowerCase(headers[i]));
  }

  return unique;
}

OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
  if (this._header) {
    throw new ERR_HTTP_HEADERS_SENT('set');
  }
  validateHeaderName(name);
  validateHeaderValue(name, value);

  let headers = this[kOutHeaders];
  if (headers === null)
    this[kOutHeaders] = headers = ObjectCreate(null);

  headers[StringPrototypeToLowerCase(name)] = [name, value];
  return this;
};

OutgoingMessage.prototype.setHeaders = function setHeaders(headers) {
  if (this._header) {
    throw new ERR_HTTP_HEADERS_SENT('set');
  }


  if (
    !headers ||
    ArrayIsArray(headers) ||
    typeof headers.keys !== 'function' ||
    typeof headers.get !== 'function'
  ) {
    throw new ERR_INVALID_ARG_TYPE('headers', ['Headers', 'Map'], headers);
  }

  for (const key of headers.keys()) {
    this.setHeader(key, headers.get(key));
  }

  return this;
};

OutgoingMessage.prototype.appendHeader = function appendHeader(name, value) {
  if (this._header) {
    throw new ERR_HTTP_HEADERS_SENT('append');
  }
  validateHeaderName(name);
  validateHeaderValue(name, value);

  const field = StringPrototypeToLowerCase(name);
  const headers = this[kOutHeaders];
  if (headers === null || !headers[field]) {
    return this.setHeader(name, value);
  }

  // Prepare the field for appending, if required
  if (!ArrayIsArray(headers[field][1])) {
    headers[field][1] = [headers[field][1]];
  }

  const existingValues = headers[field][1];
  if (ArrayIsArray(value)) {
    for (let i = 0, length = value.length; i < length; i++) {
      existingValues.push(value[i]);
    }
  } else {
    existingValues.push(value);
  }

  return this;
};


OutgoingMessage.prototype.getHeader = function getHeader(name) {
  validateString(name, 'name');

  const headers = this[kOutHeaders];
  if (headers === null)
    return;

  const entry = headers[StringPrototypeToLowerCase(name)];
  return entry && entry[1];
};


// Returns an array of the names of the current outgoing headers.
OutgoingMessage.prototype.getHeaderNames = function getHeaderNames() {
  return this[kOutHeaders] !== null ? ObjectKeys(this[kOutHeaders]) : [];
};


// Returns an array of the names of the current outgoing raw headers.
OutgoingMessage.prototype.getRawHeaderNames = function getRawHeaderNames() {
  const headersMap = this[kOutHeaders];
  if (headersMap === null) return [];

  const values = ObjectValues(headersMap);
  const headers = Array(values.length);
  // Retain for(;;) loop for performance reasons
  // Refs: https://github.com/nodejs/node/pull/30958
  for (let i = 0, l = values.length; i < l; i++) {
    headers[i] = values[i][0];
  }

  return headers;
};


// Returns a shallow copy of the current outgoing headers.
OutgoingMessage.prototype.getHeaders = function getHeaders() {
  const headers = this[kOutHeaders];
  const ret = ObjectCreate(null);
  if (headers) {
    const keys = ObjectKeys(headers);
    // Retain for(;;) loop for performance reasons
    // Refs: https://github.com/nodejs/node/pull/30958
    for (let i = 0; i < keys.length; ++i) {
      const key = keys[i];
      const val = headers[key][1];
      ret[key] = val;
    }
  }
  return ret;
};


OutgoingMessage.prototype.hasHeader = function hasHeader(name) {
  validateString(name, 'name');
  return this[kOutHeaders] !== null &&
    !!this[kOutHeaders][StringPrototypeToLowerCase(name)];
};


OutgoingMessage.prototype.removeHeader = function removeHeader(name) {
  validateString(name, 'name');

  if (this._header) {
    throw new ERR_HTTP_HEADERS_SENT('remove');
  }

  const key = StringPrototypeToLowerCase(name);

  switch (key) {
    case 'connection':
      this._removedConnection = true;
      break;
    case 'content-length':
      this._removedContLen = true;
      break;
    case 'transfer-encoding':
      this._removedTE = true;
      break;
    case 'date':
      this.sendDate = false;
      break;
  }

  if (this[kOutHeaders] !== null) {
    delete this[kOutHeaders][key];
  }
};


OutgoingMessage.prototype._implicitHeader = function _implicitHeader() {
  throw new ERR_METHOD_NOT_IMPLEMENTED('_implicitHeader()');
};

ObjectDefineProperty(OutgoingMessage.prototype, 'headersSent', {
  __proto__: null,
  configurable: true,
  enumerable: true,
  get: function() { return !!this._header; },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableEnded', {
  __proto__: null,
  get: function() { return this.finished; },
});

ObjectDefineProperty(OutgoingMessage.prototype, 'writableNeedDrain', {
  __proto__: null,
  get: function() {
    return !this.destroyed && !this.finished && this[kNeedDrain];
  },
});

const crlf_buf = Buffer.from('\r\n');
OutgoingMessage.prototype.write = function write(chunk, encoding, callback) {
  if (typeof encoding === 'function') {
    callback = encoding;
    encoding = null;
  }

  const ret = write_(this, chunk, encoding, callback, false);
  if (!ret)
    this[kNeedDrain] = true;
  return ret;
};

function onError(msg, err, callback) {
  const triggerAsyncId = msg.socket ? msg.socket[async_id_symbol] : undefined;
  defaultTriggerAsyncIdScope(triggerAsyncId,
                             process.nextTick,
                             emitErrorNt,
                             msg,
                             err,
                             callback);
}

function emitErrorNt(msg, err, callback) {
  callback(err);
  if (typeof msg.emit === 'function' && !msg._closed) {
    msg.emit('error', err);
  }
}

function strictContentLength(msg) {
  return (
    msg.strictContentLength &&
    msg._contentLength != null &&
    msg._hasBody &&
    !msg._removedContLen &&
    !msg.chunkedEncoding &&
    !msg.hasHeader('transfer-encoding')
  );
}

function write_(msg, chunk, encoding, callback, fromEnd) {
  if (typeof callback !== 'function')
    callback = nop;

  if (chunk === null) {
    throw new ERR_STREAM_NULL_VALUES();
  } else if (typeof chunk !== 'string' && !isUint8Array(chunk)) {
    throw new ERR_INVALID_ARG_TYPE(
      'chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
  }

  let err;
  if (msg.finished) {
    err = new ERR_STREAM_WRITE_AFTER_END();
  } else if (msg.destroyed) {
    err = new ERR_STREAM_DESTROYED('write');
  }

  if (err) {
    if (!msg.destroyed) {
      onError(msg, err, callback);
    } else {
      process.nextTick(callback, err);
    }
    return false;
  }

  let len;

  if (msg.strictContentLength) {
    len ??= typeof chunk === 'string' ? Buffer.byteLength(chunk, encoding) : chunk.byteLength;

    if (
      strictContentLength(msg) &&
      (fromEnd ? msg[kBytesWritten] + len !== msg._contentLength : msg[kBytesWritten] + len > msg._contentLength)
    ) {
      throw new ERR_HTTP_CONTENT_LENGTH_MISMATCH(len + msg[kBytesWritten], msg._contentLength);
    }

    msg[kBytesWritten] += len;
  }

  if (!msg._header) {
    if (fromEnd) {
      len ??= typeof chunk === 'string' ? Buffer.byteLength(chunk, encoding) : chunk.byteLength;
      msg._contentLength = len;
    }
    msg._implicitHeader();
  }

  if (!msg._hasBody) {
    if (msg[kRejectNonStandardBodyWrites]) {
      throw new ERR_HTTP_BODY_NOT_ALLOWED();
    } else {
      debug('This type of response MUST NOT have a body. ' +
        'Ignoring write() calls.');
      process.nextTick(callback);
      return true;
    }
  }

  if (!fromEnd && msg.socket && !msg.socket.writableCorked) {
    msg.socket.cork();
    process.nextTick(connectionCorkNT, msg.socket);
  }

  let ret;
  if (msg.chunkedEncoding && chunk.length !== 0) {
    len ??= typeof chunk === 'string' ? Buffer.byteLength(chunk, encoding) : chunk.byteLength;
    msg._send(NumberPrototypeToString(len, 16), 'latin1', null);
    msg._send(crlf_buf, null, null);
    msg._send(chunk, encoding, null, len);
    ret = msg._send(crlf_buf, null, callback);
  } else {
    ret = msg._send(chunk, encoding, callback, len);
  }

  debug('write ret = ' + ret);
  return ret;
}


function connectionCorkNT(conn) {
  conn.uncork();
}

OutgoingMessage.prototype.addTrailers = function addTrailers(headers) {
  this._trailer = '';
  const keys = ObjectKeys(headers);
  const isArray = ArrayIsArray(headers);
  // Retain for(;;) loop for performance reasons
  // Refs: https://github.com/nodejs/node/pull/30958
  for (let i = 0, l = keys.length; i < l; i++) {
    let field, value;
    const key = keys[i];
    if (isArray) {
      field = headers[key][0];
      value = headers[key][1];
    } else {
      field = key;
      value = headers[key];
    }
    validateHeaderName(field, 'Trailer name');

    // Check if the field must be sent several times
    const isArrayValue = ArrayIsArray(value);
    if (
      isArrayValue && value.length > 1 &&
      (!this[kUniqueHeaders] || !this[kUniqueHeaders].has(StringPrototypeToLowerCase(field)))
    ) {
      for (let j = 0, l = value.length; j < l; j++) {
        if (checkInvalidHeaderChar(value[j])) {
          debug('Trailer "%s"[%d] contains invalid characters', field, j);
          throw new ERR_INVALID_CHAR('trailer content', field);
        }
        this._trailer += field + ': ' + value[j] + '\r\n';
      }
    } else {
      if (isArrayValue) {
        value = ArrayPrototypeJoin(value, '; ');
      }

      if (checkInvalidHeaderChar(value)) {
        debug('Trailer "%s" contains invalid characters', field);
        throw new ERR_INVALID_CHAR('trailer content', field);
      }
      this._trailer += field + ': ' + value + '\r\n';
    }
  }
};

function onFinish(outmsg) {
  if (outmsg && outmsg.socket && outmsg.socket._hadError) return;
  outmsg.emit('finish');
}

OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
  if (typeof chunk === 'function') {
    callback = chunk;
    chunk = null;
    encoding = null;
  } else if (typeof encoding === 'function') {
    callback = encoding;
    encoding = null;
  }

  if (chunk) {
    if (this.finished) {
      onError(this,
              new ERR_STREAM_WRITE_AFTER_END(),
              typeof callback !== 'function' ? nop : callback);
      return this;
    }

    if (this.socket) {
      this.socket.cork();
    }

    write_(this, chunk, encoding, null, true);
  } else if (this.finished) {
    if (typeof callback === 'function') {
      if (!this.writableFinished) {
        this.on('finish', callback);
      } else {
        callback(new ERR_STREAM_ALREADY_FINISHED('end'));
      }
    }
    return this;
  } else if (!this._header) {
    if (this.socket) {
      this.socket.cork();
    }

    this._contentLength = 0;
    this._implicitHeader();
  }

  if (typeof callback === 'function')
    this.once('finish', callback);

  if (strictContentLength(this) && this[kBytesWritten] !== this._contentLength) {
    throw new ERR_HTTP_CONTENT_LENGTH_MISMATCH(this[kBytesWritten], this._contentLength);
  }

  const finish = onFinish.bind(undefined, this);

  if (this._hasBody && this.chunkedEncoding) {
    this._send('0\r\n' + this._trailer + '\r\n', 'latin1', finish);
  } else if (!this._headerSent || this.writableLength || chunk) {
    this._send('', 'latin1', finish);
  } else {
    process.nextTick(finish);
  }

  if (this.socket) {
    // Fully uncork connection on end().
    this.socket._writableState.corked = 1;
    this.socket.uncork();
  }
  this[kCorked] = 0;

  this.finished = true;

  // There is the first message on the outgoing queue, and we've sent
  // everything to the socket.
  debug('outgoing message end.');
  if (this.outputData.length === 0 &&
      this.socket &&
      this.socket._httpMessage === this) {
    this._finish();
  }

  return this;
};


// This function is called once all user data are flushed to the socket.
// Note that it has a chance that the socket is not drained.
OutgoingMessage.prototype._finish = function _finish() {
  assert(this.socket);
  this.emit('prefinish');
};


// This logic is probably a bit confusing. Let me explain a bit:
//
// In both HTTP servers and clients it is possible to queue up several
// outgoing messages. This is easiest to imagine in the case of a client.
// Take the following situation:
//
//    req1 = client.request('GET', '/');
//    req2 = client.request('POST', '/');
//
// When the user does
//
//   req2.write('hello world\n');
//
// it's possible that the first request has not been completely flushed to
// the socket yet. Thus the outgoing messages need to be prepared to queue
// up data internally before sending it on further to the socket's queue.
//
// This function, _flush(), is called by both the Server and Client
// to attempt to flush any pending messages out to the socket.
OutgoingMessage.prototype._flush = function _flush() {
  const socket = this.socket;

  if (socket && socket.writable) {
    // There might be remaining data in this.output; write it out
    const ret = this._flushOutput(socket);

    if (this.finished) {
      // This is a queue to the server or client to bring in the next this.
      this._finish();
    } else if (ret && this[kNeedDrain]) {
      this[kNeedDrain] = false;
      this.emit('drain');
    }
  }
};

OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) {
  while (this[kCorked]) {
    this[kCorked]--;
    socket.cork();
  }

  const outputLength = this.outputData.length;
  if (outputLength <= 0)
    return undefined;

  const outputData = this.outputData;
  socket.cork();
  let ret;
  // Retain for(;;) loop for performance reasons
  // Refs: https://github.com/nodejs/node/pull/30958
  for (let i = 0; i < outputLength; i++) {
    const { data, encoding, callback } = outputData[i];
    ret = socket.write(data, encoding, callback);
  }
  socket.uncork();

  this.outputData = [];
  this._onPendingData(-this.outputSize);
  this.outputSize = 0;

  return ret;
};


OutgoingMessage.prototype.flushHeaders = function flushHeaders() {
  if (!this._header) {
    this._implicitHeader();
  }

  // Force-flush the headers.
  this._send('');
};

OutgoingMessage.prototype.pipe = function pipe() {
  // OutgoingMessage should be write-only. Piping from it is disabled.
  this.emit('error', new ERR_STREAM_CANNOT_PIPE());
};

OutgoingMessage.prototype[EE.captureRejectionSymbol] =
function(err, event) {
  this.destroy(err);
};

module.exports = {
  kHighWaterMark,
  kUniqueHeaders,
  parseUniqueHeadersOption,
  validateHeaderName,
  validateHeaderValue,
  OutgoingMessage,
};
            // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ObjectDefineProperty,
  ObjectSetPrototypeOf,
  StringPrototypeCharCodeAt,
  StringPrototypeSlice,
  StringPrototypeToLowerCase,
  Symbol,
} = primordials;

const { Readable, finished } = require('stream');

const kHeaders = Symbol('kHeaders');
const kHeadersDistinct = Symbol('kHeadersDistinct');
const kHeadersCount = Symbol('kHeadersCount');
const kTrailers = Symbol('kTrailers');
const kTrailersDistinct = Symbol('kTrailersDistinct');
const kTrailersCount = Symbol('kTrailersCount');

function readStart(socket) {
  if (socket && !socket._paused && socket.readable)
    socket.resume();
}

function readStop(socket) {
  if (socket)
    socket.pause();
}

/* Abstract base class for ServerRequest and ClientResponse. */
function IncomingMessage(socket) {
  let streamOptions;

  if (socket) {
    streamOptions = {
      highWaterMark: socket.readableHighWaterMark,
    };
  }

  Readable.call(this, streamOptions);

  this._readableState.readingMore = true;

  this.socket = socket;

  this.httpVersionMajor = null;
  this.httpVersionMinor = null;
  this.httpVersion = null;
  this.complete = false;
  this[kHeaders] = null;
  this[kHeadersCount] = 0;
  this.rawHeaders = [];
  this[kTrailers] = null;
  this[kTrailersCount] = 0;
  this.rawTrailers = [];
  this.joinDuplicateHeaders = false;
  this.aborted = false;

  this.upgrade = null;

  // request (server) only
  this.url = '';
  this.method = null;

  // response (client) only
  this.statusCode = null;
  this.statusMessage = null;
  this.client = socket;

  this._consuming = false;
  // Flag for when we decide that this message cannot possibly be
  // read by the user, so there's no point continuing to handle it.
  this._dumped = false;
}
ObjectSetPrototypeOf(IncomingMessage.prototype, Readable.prototype);
ObjectSetPrototypeOf(IncomingMessage, Readable);

ObjectDefineProperty(IncomingMessage.prototype, 'connection', {
  __proto__: null,
  get: function() {
    return this.socket;
  },
  set: function(val) {
    this.socket = val;
  },
});

ObjectDefineProperty(IncomingMessage.prototype, 'headers', {
  __proto__: null,
  get: function() {
    if (!this[kHeaders]) {
      this[kHeaders] = {};

      const src = this.rawHeaders;
      const dst = this[kHeaders];

      for (let n = 0; n < this[kHeadersCount]; n += 2) {
        this._addHeaderLine(src[n + 0], src[n + 1], dst);
      }
    }
    return this[kHeaders];
  },
  set: function(val) {
    this[kHeaders] = val;
  },
});

ObjectDefineProperty(IncomingMessage.prototype, 'headersDistinct', {
  __proto__: null,
  get: function() {
    if (!this[kHeadersDistinct]) {
      this[kHeadersDistinct] = {};

      const src = this.rawHeaders;
      const dst = this[kHeadersDistinct];

      for (let n = 0; n < this[kHeadersCount]; n += 2) {
        this._addHeaderLineDistinct(src[n + 0], src[n + 1], dst);
      }
    }
    return this[kHeadersDistinct];
  },
  set: function(val) {
    this[kHeadersDistinct] = val;
  },
});

ObjectDefineProperty(IncomingMessage.prototype, 'trailers', {
  __proto__: null,
  get: function() {
    if (!this[kTrailers]) {
      this[kTrailers] = {};

      const src = this.rawTrailers;
      const dst = this[kTrailers];

      for (let n = 0; n < this[kTrailersCount]; n += 2) {
        this._addHeaderLine(src[n + 0], src[n + 1], dst);
      }
    }
    return this[kTrailers];
  },
  set: function(val) {
    this[kTrailers] = val;
  },
});

ObjectDefineProperty(IncomingMessage.prototype, 'trailersDistinct', {
  __proto__: null,
  get: function() {
    if (!this[kTrailersDistinct]) {
      this[kTrailersDistinct] = {};

      const src = this.rawTrailers;
      const dst = this[kTrailersDistinct];

      for (let n = 0; n < this[kTrailersCount]; n += 2) {
        this._addHeaderLineDistinct(src[n + 0], src[n + 1], dst);
      }
    }
    return this[kTrailersDistinct];
  },
  set: function(val) {
    this[kTrailersDistinct] = val;
  },
});

IncomingMessage.prototype.setTimeout = function setTimeout(msecs, callback) {
  if (callback)
    this.on('timeout', callback);
  this.socket.setTimeout(msecs);
  return this;
};

// Argument n cannot be factored out due to the overhead of
// argument adaptor frame creation inside V8 in case that number of actual
// arguments is different from expected arguments.
// Ref: https://bugs.chromium.org/p/v8/issues/detail?id=10201
// NOTE: Argument adapt frame issue might be solved in V8 engine v8.9.
// Refactoring `n` out might be possible when V8 is upgraded to that
// version.
// Ref: https://v8.dev/blog/v8-release-89
IncomingMessage.prototype._read = function _read(n) {
  if (!this._consuming) {
    this._readableState.readingMore = false;
    this._consuming = true;
  }

  // We actually do almost nothing here, because the parserOnBody
  // function fills up our internal buffer directly.  However, we
  // do need to unpause the underlying socket so that it flows.
  if (this.socket.readable)
    readStart(this.socket);
};

// It's possible that the socket will be destroyed, and removed from
// any messages, before ever calling this.  In that case, just skip
// it, since something else is destroying this connection anyway.
IncomingMessage.prototype._destroy = function _destroy(err, cb) {
  if (!this.readableEnded || !this.complete) {
    this.aborted = true;
    this.emit('aborted');
  }

  // If aborted and the underlying socket is not already destroyed,
  // destroy it.
  // We have to check if the socket is already destroyed because finished
  // does not call the callback when this method is invoked from `_http_client`
  // in `test/parallel/test-http-client-spurious-aborted.js`
  if (this.socket && !this.socket.destroyed && this.aborted) {
    this.socket.destroy(err);
    const cleanup = finished(this.socket, (e) => {
      if (e?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
        e = null;
      }
      cleanup();
      process.nextTick(onError, this, e || err, cb);
    });
  } else {
    process.nextTick(onError, this, err, cb);
  }
};

IncomingMessage.prototype._addHeaderLines = _addHeaderLines;
function _addHeaderLines(headers, n) {
  if (headers && headers.length) {
    let dest;
    if (this.complete) {
      this.rawTrailers = headers;
      this[kTrailersCount] = n;
      dest = this[kTrailers];
    } else {
      this.rawHeaders = headers;
      this[kHeadersCount] = n;
      dest = this[kHeaders];
    }

    if (dest) {
      for (let i = 0; i < n; i += 2) {
        this._addHeaderLine(headers[i], headers[i + 1], dest);
      }
    }
  }
}


// This function is used to help avoid the lowercasing of a field name if it
// matches a 'traditional cased' version of a field name. It then returns the
// lowercased name to both avoid calling toLowerCase() a second time and to
// indicate whether the field was a 'no duplicates' field. If a field is not a
// 'no duplicates' field, a `0` byte is prepended as a flag. The one exception
// to this is the Set-Cookie header which is indicated by a `1` byte flag, since
// it is an 'array' field and thus is treated differently in _addHeaderLines().
// TODO: perhaps http_parser could be returning both raw and lowercased versions
// of known header names to avoid us having to call toLowerCase() for those
// headers.
function matchKnownFields(field, lowercased) {
  switch (field.length) {
    case 3:
      if (field === 'Age' || field === 'age') return 'age';
      break;
    case 4:
      if (field === 'Host' || field === 'host') return 'host';
      if (field === 'From' || field === 'from') return 'from';
      if (field === 'ETag' || field === 'etag') return 'etag';
      if (field === 'Date' || field === 'date') return '\u0000date';
      if (field === 'Vary' || field === 'vary') return '\u0000vary';
      break;
    case 6:
      if (field === 'Server' || field === 'server') return 'server';
      if (field === 'Cookie' || field === 'cookie') return '\u0002cookie';
      if (field === 'Origin' || field === 'origin') return '\u0000origin';
      if (field === 'Expect' || field === 'expect') return '\u0000expect';
      if (field === 'Accept' || field === 'accept') return '\u0000accept';
      break;
    case 7:
      if (field === 'Referer' || field === 'referer') return 'referer';
      if (field === 'Expires' || field === 'expires') return 'expires';
      if (field === 'Upgrade' || field === 'upgrade') return '\u0000upgrade';
      break;
    case 8:
      if (field === 'Location' || field === 'location')
        return 'location';
      if (field === 'If-Match' || field === 'if-match')
        return '\u0000if-match';
      break;
    case 10:
      if (field === 'User-Agent' || field === 'user-agent')
        return 'user-agent';
      if (field === 'Set-Cookie' || field === 'set-cookie')
        return '\u0001';
      if (field === 'Connection' || field === 'connection')
        return '\u0000connection';
      break;
    case 11:
      if (field === 'Retry-After' || field === 'retry-after')
        return 'retry-after';
      break;
    case 12:
      if (field === 'Content-Type' || field === 'content-type')
        return 'content-type';
      if (field === 'Max-Forwards' || field === 'max-forwards')
        return 'max-forwards';
      break;
    case 13:
      if (field === 'Authorization' || field === 'authorization')
        return 'authorization';
      if (field === 'Last-Modified' || field === 'last-modified')
        return 'last-modified';
      if (field === 'Cache-Control' || field === 'cache-control')
        return '\u0000cache-control';
      if (field === 'If-None-Match' || field === 'if-none-match')
        return '\u0000if-none-match';
      break;
    case 14:
      if (field === 'Content-Length' || field === 'content-length')
        return 'content-length';
      break;
    case 15:
      if (field === 'Accept-Encoding' || field === 'accept-encoding')
        return '\u0000accept-encoding';
      if (field === 'Accept-Language' || field === 'accept-language')
        return '\u0000accept-language';
      if (field === 'X-Forwarded-For' || field === 'x-forwarded-for')
        return '\u0000x-forwarded-for';
      break;
    case 16:
      if (field === 'Content-Encoding' || field === 'content-encoding')
        return '\u0000content-encoding';
      if (field === 'X-Forwarded-Host' || field === 'x-forwarded-host')
        return '\u0000x-forwarded-host';
      break;
    case 17:
      if (field === 'If-Modified-Since' || field === 'if-modified-since')
        return 'if-modified-since';
      if (field === 'Transfer-Encoding' || field === 'transfer-encoding')
        return '\u0000transfer-encoding';
      if (field === 'X-Forwarded-Proto' || field === 'x-forwarded-proto')
        return '\u0000x-forwarded-proto';
      break;
    case 19:
      if (field === 'Proxy-Authorization' || field === 'proxy-authorization')
        return 'proxy-authorization';
      if (field === 'If-Unmodified-Since' || field === 'if-unmodified-since')
        return 'if-unmodified-since';
      break;
  }
  if (lowercased) {
    return '\u0000' + field;
  }
  return matchKnownFields(StringPrototypeToLowerCase(field), true);
}
// Add the given (field, value) pair to the message
//
// Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
// same header with a ', ' if the header in question supports specification of
// multiple values this way. The one exception to this is the Cookie header,
// which has multiple values joined with a '; ' instead. If a header's values
// cannot be joined in either of these ways, we declare the first instance the
// winner and drop the second. Extended header fields (those beginning with
// 'x-') are always joined.
IncomingMessage.prototype._addHeaderLine = _addHeaderLine;
function _addHeaderLine(field, value, dest) {
  field = matchKnownFields(field);
  const flag = StringPrototypeCharCodeAt(field, 0);
  if (flag === 0 || flag === 2) {
    field = StringPrototypeSlice(field, 1);
    // Make a delimited list
    if (typeof dest[field] === 'string') {
      dest[field] += (flag === 0 ? ', ' : '; ') + value;
    } else {
      dest[field] = value;
    }
  } else if (flag === 1) {
    // Array header -- only Set-Cookie at the moment
    if (dest['set-cookie'] !== undefined) {
      dest['set-cookie'].push(value);
    } else {
      dest['set-cookie'] = [value];
    }
  } else if (this.joinDuplicateHeaders) {
    // RFC 9110 https://www.rfc-editor.org/rfc/rfc9110#section-5.2
    // https://github.com/nodejs/node/issues/45699
    // allow authorization multiple fields
    // Make a delimited list
    if (dest[field] === undefined) {
      dest[field] = value;
    } else {
      dest[field] += ', ' + value;
    }
  } else if (dest[field] === undefined) {
    // Drop duplicates
    dest[field] = value;
  }
}

IncomingMessage.prototype._addHeaderLineDistinct = _addHeaderLineDistinct;
function _addHeaderLineDistinct(field, value, dest) {
  field = StringPrototypeToLowerCase(field);
  if (!dest[field]) {
    dest[field] = [value];
  } else {
    dest[field].push(value);
  }
}


// Call this instead of resume() if we want to just
// dump all the data to /dev/null
IncomingMessage.prototype._dump = function _dump() {
  if (!this._dumped) {
    this._dumped = true;
    // If there is buffered data, it may trigger 'data' events.
    // Remove 'data' event listeners explicitly.
    this.removeAllListeners('data');
    this.resume();
  }
};

function onError(self, error, cb) {
  // This is to keep backward compatible behavior.
  // An error is emitted only if there are listeners attached to the event.
  if (self.listenerCount('error') === 0) {
    cb();
  } else {
    cb(error);
  }
}

module.exports = {
  IncomingMessage,
  readStart,
  readStop,
};
         // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  MathMin,
  Symbol,
  RegExpPrototypeExec,
} = primordials;
const { setImmediate } = require('timers');

const { methods, HTTPParser } = internalBinding('http_parser');
const { getOptionValue } = require('internal/options');
const insecureHTTPParser = getOptionValue('--insecure-http-parser');

const FreeList = require('internal/freelist');
const incoming = require('_http_incoming');
const {
  IncomingMessage,
  readStart,
  readStop,
} = incoming;

const kIncomingMessage = Symbol('IncomingMessage');
const kOnMessageBegin = HTTPParser.kOnMessageBegin | 0;
const kOnHeaders = HTTPParser.kOnHeaders | 0;
const kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
const kOnBody = HTTPParser.kOnBody | 0;
const kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
const kOnExecute = HTTPParser.kOnExecute | 0;
const kOnTimeout = HTTPParser.kOnTimeout | 0;

const MAX_HEADER_PAIRS = 2000;

// Only called in the slow case where slow means
// that the request headers were either fragmented
// across multiple TCP packets or too large to be
// processed in a single run. This method is also
// called to process trailing HTTP headers.
function parserOnHeaders(headers, url) {
  // Once we exceeded headers limit - stop collecting them
  if (this.maxHeaderPairs <= 0 ||
      this._headers.length < this.maxHeaderPairs) {
    this._headers.push(...headers);
  }
  this._url += url;
}

// `headers` and `url` are set only if .onHeaders() has not been called for
// this request.
// `url` is not set for response parsers but that's not applicable here since
// all our parsers are request parsers.
function parserOnHeadersComplete(versionMajor, versionMinor, headers, method,
                                 url, statusCode, statusMessage, upgrade,
                                 shouldKeepAlive) {
  const parser = this;
  const { socket } = parser;

  if (headers === undefined) {
    headers = parser._headers;
    parser._headers = [];
  }

  if (url === undefined) {
    url = parser._url;
    parser._url = '';
  }

  // Parser is also used by http client
  const ParserIncomingMessage = (socket && socket.server &&
                                 socket.server[kIncomingMessage]) ||
                                 IncomingMessage;

  const incoming = parser.incoming = new ParserIncomingMessage(socket);
  incoming.httpVersionMajor = versionMajor;
  incoming.httpVersionMinor = versionMinor;
  incoming.httpVersion = `${versionMajor}.${versionMinor}`;
  incoming.joinDuplicateHeaders = socket?.server?.joinDuplicateHeaders ||
                                  parser.joinDuplicateHeaders;
  incoming.url = url;
  incoming.upgrade = upgrade;

  let n = headers.length;

  // If parser.maxHeaderPairs <= 0 assume that there's no limit.
  if (parser.maxHeaderPairs > 0)
    n = MathMin(n, parser.maxHeaderPairs);

  incoming._addHeaderLines(headers, n);

  if (typeof method === 'number') {
    // server only
    incoming.method = methods[method];
  } else {
    // client only
    incoming.statusCode = statusCode;
    incoming.statusMessage = statusMessage;
  }

  return parser.onIncoming(incoming, shouldKeepAlive);
}

function parserOnBody(b) {
  const stream = this.incoming;

  // If the stream has already been removed, then drop it.
  if (stream === null)
    return;

  // Pretend this was the result of a stream._read call.
  if (!stream._dumped) {
    const ret = stream.push(b);
    if (!ret)
      readStop(this.socket);
  }
}

function parserOnMessageComplete() {
  const parser = this;
  const stream = parser.incoming;

  if (stream !== null) {
    stream.complete = true;
    // Emit any trailing headers.
    const headers = parser._headers;
    if (headers.length) {
      stream._addHeaderLines(headers, headers.length);
      parser._headers = [];
      parser._url = '';
    }

    // For emit end event
    stream.push(null);
  }

  // Force to read the next incoming message
  readStart(parser.socket);
}


const parsers = new FreeList('parsers', 1000, function parsersCb() {
  const parser = new HTTPParser();

  cleanParser(parser);

  parser[kOnHeaders] = parserOnHeaders;
  parser[kOnHeadersComplete] = parserOnHeadersComplete;
  parser[kOnBody] = parserOnBody;
  parser[kOnMessageComplete] = parserOnMessageComplete;

  return parser;
});

function closeParserInstance(parser) { parser.close(); }

// Free the parser and also break any links that it
// might have to any other things.
// TODO: All parser data should be attached to a
// single object, so that it can be easily cleaned
// up by doing `parser.data = {}`, which should
// be done in FreeList.free.  `parsers.free(parser)`
// should be all that is needed.
function freeParser(parser, req, socket) {
  if (parser) {
    if (parser._consumed)
      parser.unconsume();
    cleanParser(parser);
    parser.remove();
    if (parsers.free(parser) === false) {
      // Make sure the parser's stack has unwound before deleting the
      // corresponding C++ object through .close().
      setImmediate(closeParserInstance, parser);
    } else {
      // Since the Parser destructor isn't going to run the destroy() callbacks
      // it needs to be triggered manually.
      parser.free();
    }
  }
  if (req) {
    req.parser = null;
  }
  if (socket) {
    socket.parser = null;
  }
}

const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
/**
 * Verifies that the given val is a valid HTTP token
 * per the rules defined in RFC 7230
 * See https://tools.ietf.org/html/rfc7230#section-3.2.6
 */
function checkIsHttpToken(val) {
  return RegExpPrototypeExec(tokenRegExp, val) !== null;
}

const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
/**
 * True if val contains an invalid field-vchar
 *  field-value    = *( field-content / obs-fold )
 *  field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
 *  field-vchar    = VCHAR / obs-text
 */
function checkInvalidHeaderChar(val) {
  return RegExpPrototypeExec(headerCharRegex, val) !== null;
}

function cleanParser(parser) {
  parser._headers = [];
  parser._url = '';
  parser.socket = null;
  parser.incoming = null;
  parser.outgoing = null;
  parser.maxHeaderPairs = MAX_HEADER_PAIRS;
  parser[kOnMessageBegin] = null;
  parser[kOnExecute] = null;
  parser[kOnTimeout] = null;
  parser._consumed = false;
  parser.onIncoming = null;
  parser.joinDuplicateHeaders = null;
}

function prepareError(err, parser, rawPacket) {
  err.rawPacket = rawPacket || parser.getCurrentBuffer();
  if (typeof err.reason === 'string')
    err.message = `Parse Error: ${err.reason}`;
}

let warnedLenient = false;

function isLenient() {
  if (insecureHTTPParser && !warnedLenient) {
    warnedLenient = true;
    process.emitWarning('Using insecure HTTP parsing');
  }
  return insecureHTTPParser;
}

module.exports = {
  _checkInvalidHeaderChar: checkInvalidHeaderChar,
  _checkIsHttpToken: checkIsHttpToken,
  chunkExpression: /(?:^|\W)chunked(?:$|\W)/i,
  continueExpression: /(?:^|\W)100-continue(?:$|\W)/i,
  CRLF: '\r\n', // TODO: Deprecate this.
  freeParser,
  methods,
  parsers,
  kIncomingMessage,
  HTTPParser,
  isLenient,
  prepareError,
};
                           // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ArrayIsArray,
  Boolean,
  Error,
  FunctionPrototypeCall,
  NumberIsFinite,
  ObjectAssign,
  ObjectKeys,
  ObjectSetPrototypeOf,
  ReflectApply,
  RegExpPrototypeExec,
  String,
  StringPrototypeCharCodeAt,
  StringPrototypeIncludes,
  StringPrototypeIndexOf,
  StringPrototypeToUpperCase,
  Symbol,
  TypedArrayPrototypeSlice,
} = primordials;

const net = require('net');
const assert = require('internal/assert');
const {
  kEmptyObject,
  once,
} = require('internal/util');
const {
  _checkIsHttpToken: checkIsHttpToken,
  freeParser,
  parsers,
  HTTPParser,
  isLenient,
  prepareError,
} = require('_http_common');
const {
  kUniqueHeaders,
  parseUniqueHeadersOption,
  OutgoingMessage,
} = require('_http_outgoing');
const Agent = require('_http_agent');
const { Buffer } = require('buffer');
const { defaultTriggerAsyncIdScope } = require('internal/async_hooks');
const { URL, urlToHttpOptions, isURL } = require('internal/url');
const {
  kOutHeaders,
  kNeedDrain,
  isTraceHTTPEnabled,
  traceBegin,
  traceEnd,
  getNextTraceEventId,
} = require('internal/http');
const { connResetException, codes } = require('internal/errors');
const {
  ERR_HTTP_HEADERS_SENT,
  ERR_INVALID_ARG_TYPE,
  ERR_INVALID_HTTP_TOKEN,
  ERR_INVALID_PROTOCOL,
  ERR_UNESCAPED_CHARACTERS,
} = codes;
const {
  validateInteger,
  validateBoolean,
} = require('internal/validators');
const { getTimerDuration } = require('internal/timers');
const {
  DTRACE_HTTP_CLIENT_REQUEST,
  DTRACE_HTTP_CLIENT_RESPONSE,
} = require('internal/dtrace');

const {
  hasObserver,
  startPerf,
  stopPerf,
} = require('internal/perf/observe');

const kClientRequestStatistics = Symbol('ClientRequestStatistics');

const dc = require('diagnostics_channel');
const onClientRequestStartChannel = dc.channel('http.client.request.start');
const onClientResponseFinishChannel = dc.channel('http.client.response.finish');

const { addAbortSignal, finished } = require('stream');

let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
  debug = fn;
});

const INVALID_PATH_REGEX = /[^\u0021-\u00ff]/;
const kError = Symbol('kError');

const kLenientAll = HTTPParser.kLenientAll | 0;
const kLenientNone = HTTPParser.kLenientNone | 0;

const HTTP_CLIENT_TRACE_EVENT_NAME = 'http.client.request';

function validateHost(host, name) {
  if (host !== null && host !== undefined && typeof host !== 'string') {
    throw new ERR_INVALID_ARG_TYPE(`options.${name}`,
                                   ['string', 'undefined', 'null'],
                                   host);
  }
  return host;
}

class HTTPClientAsyncResource {
  constructor(type, req) {
    this.type = type;
    this.req = req;
  }
}

function ClientRequest(input, options, cb) {
  FunctionPrototypeCall(OutgoingMessage, this);

  if (typeof input === 'string') {
    const urlStr = input;
    input = urlToHttpOptions(new URL(urlStr));
  } else if (isURL(input)) {
    // url.URL instance
    input = urlToHttpOptions(input);
  } else {
    cb = options;
    options = input;
    input = null;
  }

  if (typeof options === 'function') {
    cb = options;
    options = input || kEmptyObject;
  } else {
    options = ObjectAssign(input || {}, options);
  }

  let agent = options.agent;
  const defaultAgent = options._defaultAgent || Agent.globalAgent;
  if (agent === false) {
    agent = new defaultAgent.constructor();
  } else if (agent === null || agent === undefined) {
    if (typeof options.createConnection !== 'function') {
      agent = defaultAgent;
    }
    // Explicitly pass through this statement as agent will not be used
    // when createConnection is provided.
  } else if (typeof agent.addRequest !== 'function') {
    throw new ERR_INVALID_ARG_TYPE('options.agent',
                                   ['Agent-like Object', 'undefined', 'false'],
                                   agent);
  }
  this.agent = agent;

  const protocol = options.protocol || defaultAgent.protocol;
  let expectedProtocol = defaultAgent.protocol;
  if (this.agent && this.agent.protocol)
    expectedProtocol = this.agent.protocol;

  if (options.path) {
    const path = String(options.path);
    if (RegExpPrototypeExec(INVALID_PATH_REGEX, path) !== null) {
      debug('Path contains unescaped characters: "%s"', path);
      throw new ERR_UNESCAPED_CHARACTERS('Request path');
    }
  }

  if (protocol !== expectedProtocol) {
    throw new ERR_INVALID_PROTOCOL(protocol, expectedProtocol);
  }

  const defaultPort = options.defaultPort ||
                    (this.agent && this.agent.defaultPort);

  const port = options.port = options.port || defaultPort || 80;
  const host = options.host = validateHost(options.hostname, 'hostname') ||
                            validateHost(options.host, 'host') || 'localhost';

  const setHost = (options.setHost === undefined || Boolean(options.setHost));

  this.socketPath = options.socketPath;

  if (options.timeout !== undefined)
    this.timeout = getTimerDuration(options.timeout, 'timeout');

  const signal = options.signal;
  if (signal) {
    addAbortSignal(signal, this);
  }
  let method = options.method;
  const methodIsString = (typeof method === 'string');
  if (method !== null && method !== undefined && !methodIsString) {
    throw new ERR_INVALID_ARG_TYPE('options.method', 'string', method);
  }

  if (methodIsString && method) {
    if (!checkIsHttpToken(method)) {
      throw new ERR_INVALID_HTTP_TOKEN('Method', method);
    }
    method = this.method = StringPrototypeToUpperCase(method);
  } else {
    method = this.method = 'GET';
  }

  const maxHeaderSize = options.maxHeaderSize;
  if (maxHeaderSize !== undefined)
    validateInteger(maxHeaderSize, 'maxHeaderSize', 0);
  this.maxHeaderSize = maxHeaderSize;

  const insecureHTTPParser = options.insecureHTTPParser;
  if (insecureHTTPParser !== undefined) {
    validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');
  }

  this.insecureHTTPParser = insecureHTTPParser;

  if (options.joinDuplicateHeaders !== undefined) {
    validateBoolean(options.joinDuplicateHeaders, 'options.joinDuplicateHeaders');
  }

  this.joinDuplicateHeaders = options.joinDuplicateHeaders;

  this.path = options.path || '/';
  if (cb) {
    this.once('response', cb);
  }

  if (method === 'GET' ||
      method === 'HEAD' ||
      method === 'DELETE' ||
      method === 'OPTIONS' ||
      method === 'TRACE' ||
      method === 'CONNECT') {
    this.useChunkedEncodingByDefault = false;
  } else {
    this.useChunkedEncodingByDefault = true;
  }

  this._ended = false;
  this.res = null;
  this.aborted = false;
  this.timeoutCb = null;
  this.upgradeOrConnect = false;
  this.parser = null;
  this.maxHeadersCount = null;
  this.reusedSocket = false;
  this.host = host;
  this.protocol = protocol;

  if (this.agent) {
    // If there is an agent we should default to Connection:keep-alive,
    // but only if the Agent will actually reuse the connection!
    // If it's not a keepAlive agent, and the maxSockets==Infinity, then
    // there's never a case where this socket will actually be reused
    if (!this.agent.keepAlive && !NumberIsFinite(this.agent.maxSockets)) {
      this._last = true;
      this.shouldKeepAlive = false;
    } else {
      this._last = false;
      this.shouldKeepAlive = true;
    }
  }

  const headersArray = ArrayIsArray(options.headers);
  if (!headersArray) {
    if (options.headers) {
      const keys = ObjectKeys(options.headers);
      // Retain for(;;) loop for performance reasons
      // Refs: https://github.com/nodejs/node/pull/30958
      for (let i = 0; i < keys.length; i++) {
        const key = keys[i];
        this.setHeader(key, options.headers[key]);
      }
    }

    if (host && !this.getHeader('host') && setHost) {
      let hostHeader = host;

      // For the Host header, ensure that IPv6 addresses are enclosed
      // in square brackets, as defined by URI formatting
      // https://tools.ietf.org/html/rfc3986#section-3.2.2
      const posColon = StringPrototypeIndexOf(hostHeader, ':');
      if (posColon !== -1 &&
          StringPrototypeIncludes(hostHeader, ':', posColon + 1) &&
          StringPrototypeCharCodeAt(hostHeader, 0) !== 91/* '[' */) {
        hostHeader = `[${hostHeader}]`;
      }

      if (port && +port !== defaultPort) {
        hostHeader += ':' + port;
      }
      this.setHeader('Host', hostHeader);
    }

    if (options.auth && !this.getHeader('Authorization')) {
      this.setHeader('Authorization', 'Basic ' +
                     Buffer.from(options.auth).toString('base64'));
    }

    if (this.getHeader('expect')) {
      if (this._header) {
        throw new ERR_HTTP_HEADERS_SENT('render');
      }

      this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n',
                        this[kOutHeaders]);
    }
  } else {
    this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n',
                      options.headers);
  }

  this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);

  let optsWithoutSignal = options;
  if (optsWithoutSignal.signal) {
    optsWithoutSignal = ObjectAssign({}, options);
    delete optsWithoutSignal.signal;
  }

  // initiate connection
  if (this.agent) {
    this.agent.addRequest(this, optsWithoutSignal);
  } else {
    // No agent, default to Connection:close.
    this._last = true;
    this.shouldKeepAlive = false;
    if (typeof optsWithoutSignal.createConnection === 'function') {
      const oncreate = once((err, socket) => {
        if (err) {
          process.nextTick(() => this.emit('error', err));
        } else {
          this.onSocket(socket);
        }
      });

      try {
        const newSocket = optsWithoutSignal.createConnection(optsWithoutSignal,
                                                             oncreate);
        if (newSocket) {
          oncreate(null, newSocket);
        }
      } catch (err) {
        oncreate(err);
      }
    } else {
      debug('CLIENT use net.createConnection', optsWithoutSignal);
      this.onSocket(net.createConnection(optsWithoutSignal));
    }
  }
}
ObjectSetPrototypeOf(ClientRequest.prototype, OutgoingMessage.prototype);
ObjectSetPrototypeOf(ClientRequest, OutgoingMessage);

ClientRequest.prototype._finish = function _finish() {
  DTRACE_HTTP_CLIENT_REQUEST(this, this.socket);
  FunctionPrototypeCall(OutgoingMessage.prototype._finish, this);
  if (hasObserver('http')) {
    startPerf(this, kClientRequestStatistics, {
      type: 'http',
      name: 'HttpClient',
      detail: {
        req: {
          method: this.method,
          url: `${this.protocol}//${this.host}${this.path}`,
          headers: typeof this.getHeaders === 'function' ? this.getHeaders() : {},
        },
      },
    });
  }
  if (onClientRequestStartChannel.hasSubscribers) {
    onClientRequestStartChannel.publish({
      request: this,
    });
  }
  if (isTraceHTTPEnabled()) {
    this._traceEventId = getNextTraceEventId();
    traceBegin(HTTP_CLIENT_TRACE_EVENT_NAME, this._traceEventId);
  }
};

ClientRequest.prototype._implicitHeader = function _implicitHeader() {
  if (this._header) {
    throw new ERR_HTTP_HEADERS_SENT('render');
  }
  this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n',
                    this[kOutHeaders]);
};

ClientRequest.prototype.abort = function abort() {
  if (this.aborted) {
    return;
  }
  this.aborted = true;
  process.nextTick(emitAbortNT, this);
  this.destroy();
};

ClientRequest.prototype.destroy = function destroy(err) {
  if (this.destroyed) {
    return this;
  }
  this.destroyed = true;

  // If we're aborting, we don't care about any more response data.
  if (this.res) {
    this.res._dump();
  }

  this[kError] = err;
  this.socket?.destroy(err);

  return this;
};

function emitAbortNT(req) {
  req.emit('abort');
}

function ondrain() {
  const msg = this._httpMessage;
  if (msg && !msg.finished && msg[kNeedDrain]) {
    msg[kNeedDrain] = false;
    msg.emit('drain');
  }
}

function socketCloseListener() {
  const socket = this;
  const req = socket._httpMessage;
  debug('HTTP socket close');

  // NOTE: It's important to get parser here, because it could be freed by
  // the `socketOnData`.
  const parser = socket.parser;
  const res = req.res;

  req.destroyed = true;
  if (res) {
    // Socket closed before we emitted 'end' below.
    if (!res.complete) {
      res.destroy(connResetException('aborted'));
    }
    req._closed = true;
    req.emit('close');
    if (!res.aborted && res.readable) {
      res.push(null);
    }
  } else {
    if (!req.socket._hadError) {
      // This socket error fired before we started to
      // receive a response. The error needs to
      // fire on the request.
      req.socket._hadError = true;
      req.emit('error', connResetException('socket hang up'));
    }
    req._closed = true;
    req.emit('close');
  }

  // Too bad.  That output wasn't getting written.
  // This is pretty terrible that it doesn't raise an error.
  // Fixed better in v0.10
  if (req.outputData)
    req.outputData.length = 0;

  if (parser) {
    parser.finish();
    freeParser(parser, req, socket);
  }
}

function socketErrorListener(err) {
  const socket = this;
  const req = socket._httpMessage;
  debug('SOCKET ERROR:', err.message, err.stack);

  if (req) {
    // For Safety. Some additional errors might fire later on
    // and we need to make sure we don't double-fire the error event.
    req.socket._hadError = true;
    req.emit('error', err);
  }

  const parser = socket.parser;
  if (parser) {
    parser.finish();
    freeParser(parser, req, socket);
  }

  // Ensure that no further data will come out of the socket
  socket.removeListener('data', socketOnData);
  socket.removeListener('end', socketOnEnd);
  socket.destroy();
}

function socketOnEnd() {
  const socket = this;
  const req = this._httpMessage;
  const parser = this.parser;

  if (!req.res && !req.socket._hadError) {
    // If we don't have a response then we know that the socket
    // ended prematurely and we need to emit an error on the request.
    req.socket._hadError = true;
    req.emit('error', connResetException('socket hang up'));
  }
  if (parser) {
    parser.finish();
    freeParser(parser, req, socket);
  }
  socket.destroy();
}

function socketOnData(d) {
  const socket = this;
  const req = this._httpMessage;
  const parser = this.parser;

  assert(parser && parser.socket === socket);

  const ret = parser.execute(d);
  if (ret instanceof Error) {
    prepareError(ret, parser, d);
    debug('parse error', ret);
    freeParser(parser, req, socket);
    socket.removeListener('data', socketOnData);
    socket.removeListener('end', socketOnEnd);
    socket.destroy();
    req.socket._hadError = true;
    req.emit('error', ret);
  } else if (parser.incoming && parser.incoming.upgrade) {
    // Upgrade (if status code 101) or CONNECT
    const bytesParsed = ret;
    const res = parser.incoming;
    req.res = res;

    socket.removeListener('data', socketOnData);
    socket.removeListener('end', socketOnEnd);
    socket.removeListener('drain', ondrain);

    if (req.timeoutCb) socket.removeListener('timeout', req.timeoutCb);
    socket.removeListener('timeout', responseOnTimeout);

    parser.finish();
    freeParser(parser, req, socket);

    const bodyHead = TypedArrayPrototypeSlice(d, bytesParsed, d.length);

    const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
    if (req.listenerCount(eventName) > 0) {
      req.upgradeOrConnect = true;

      // detach the socket
      socket.emit('agentRemove');
      socket.removeListener('close', socketCloseListener);
      socket.removeListener('error', socketErrorListener);

      socket._httpMessage = null;
      socket.readableFlowing = null;

      req.emit(eventName, res, socket, bodyHead);
      req.destroyed = true;
      req._closed = true;
      req.emit('close');
    } else {
      // Requested Upgrade or used CONNECT method, but have no handler.
      socket.destroy();
    }
  } else if (parser.incoming && parser.incoming.complete &&
             // When the status code is informational (100, 102-199),
             // the server will send a final response after this client
             // sends a request body, so we must not free the parser.
             // 101 (Switching Protocols) and all other status codes
             // should be processed normally.
             !statusIsInformational(parser.incoming.statusCode)) {
    socket.removeListener('data', socketOnData);
    socket.removeListener('end', socketOnEnd);
    socket.removeListener('drain', ondrain);
    freeParser(parser, req, socket);
  }
}

function statusIsInformational(status) {
  // 100 (Continue)    RFC7231 Section 6.2.1
  // 102 (Processing)  RFC2518
  // 103 (Early Hints) RFC8297
  // 104-199 (Unassigned)
  return (status < 200 && status >= 100 && status !== 101);
}

// client
function parserOnIncomingClient(res, shouldKeepAlive) {
  const socket = this.socket;
  const req = socket._httpMessage;

  debug('AGENT incoming response!');

  if (req.res) {
    // We already have a response object, this means the server
    // sent a double response.
    socket.destroy();
    return 0;  // No special treatment.
  }
  req.res = res;

  // Skip body and treat as Upgrade.
  if (res.upgrade)
    return 2;

  // Responses to CONNECT request is handled as Upgrade.
  const method = req.method;
  if (method === 'CONNECT') {
    res.upgrade = true;
    return 2;  // Skip body and treat as Upgrade.
  }

  if (statusIsInformational(res.statusCode)) {
    // Restart the parser, as this is a 1xx informational message.
    req.res = null; // Clear res so that we don't hit double-responses.
    // Maintain compatibility by sending 100-specific events
    if (res.statusCode === 100) {
      req.emit('continue');
    }
    // Send information events to all 1xx responses except 101 Upgrade.
    req.emit('information', {
      statusCode: res.statusCode,
      statusMessage: res.statusMessage,
      httpVersion: res.httpVersion,
      httpVersionMajor: res.httpVersionMajor,
      httpVersionMinor: res.httpVersionMinor,
      headers: res.headers,
      rawHeaders: res.rawHeaders,
    });

    return 1;  // Skip body but don't treat as Upgrade.
  }

  if (req.shouldKeepAlive && !shouldKeepAlive && !req.upgradeOrConnect) {
    // Server MUST respond with Connection:keep-alive for us to enable it.
    // If we've been upgraded (via WebSockets) we also shouldn't try to
    // keep the connection open.
    req.shouldKeepAlive = false;
  }

  DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
  if (req[kClientRequestStatistics] && hasObserver('http')) {
    stopPerf(req, kClientRequestStatistics, {
      detail: {
        res: {
          statusCode: res.statusCode,
          statusMessage: res.statusMessage,
          headers: res.headers,
        },
      },
    });
  }
  if (onClientResponseFinishChannel.hasSubscribers) {
    onClientResponseFinishChannel.publish({
      request: req,
      response: res,
    });
  }
  if (isTraceHTTPEnabled() && typeof req._traceEventId === 'number') {
    traceEnd(HTTP_CLIENT_TRACE_EVENT_NAME, req._traceEventId, {
      path: req.path,
      statusCode: res.statusCode,
    });
  }
  req.res = res;
  res.req = req;

  // Add our listener first, so that we guarantee socket cleanup
  res.on('end', responseOnEnd);
  req.on('finish', requestOnFinish);
  socket.on('timeout', responseOnTimeout);

  // If the user did not listen for the 'response' event, then they
  // can't possibly read the data, so we ._dump() it into the void
  // so that the socket doesn't hang there in a paused state.
  if (req.aborted || !req.emit('response', res))
    res._dump();

  if (method === 'HEAD')
    return 1;  // Skip body but don't treat as Upgrade.

  if (res.statusCode === 304) {
    res.complete = true;
    return 1; // Skip body as there won't be any
  }

  return 0;  // No special treatment.
}

// client
function responseKeepAlive(req) {
  const socket = req.socket;

  debug('AGENT socket keep-alive');
  if (req.timeoutCb) {
    socket.setTimeout(0, req.timeoutCb);
    req.timeoutCb = null;
  }
  socket.removeListener('close', socketCloseListener);
  socket.removeListener('error', socketErrorListener);
  socket.removeListener('data', socketOnData);
  socket.removeListener('end', socketOnEnd);

  // TODO(ronag): Between here and emitFreeNT the socket
  // has no 'error' handler.

  // There are cases where _handle === null. Avoid those. Passing undefined to
  // nextTick() will call getDefaultTriggerAsyncId() to retrieve the id.
  const asyncId = socket._handle ? socket._handle.getAsyncId() : undefined;
  // Mark this socket as available, AFTER user-added end
  // handlers have a chance to run.
  defaultTriggerAsyncIdScope(asyncId, process.nextTick, emitFreeNT, req);

  req.destroyed = true;
  if (req.res) {
    // Detach socket from IncomingMessage to avoid destroying the freed
    // socket in IncomingMessage.destroy().
    req.res.socket = null;
  }
}

function responseOnEnd() {
  const req = this.req;
  const socket = req.socket;

  if (socket) {
    if (req.timeoutCb) socket.removeListener('timeout', emitRequestTimeout);
    socket.removeListener('timeout', responseOnTimeout);
  }

  req._ended = true;

  if (!req.shouldKeepAlive) {
    if (socket.writable) {
      debug('AGENT socket.destroySoon()');
      if (typeof socket.destroySoon === 'function')
        socket.destroySoon();
      else
        socket.end();
    }
    assert(!socket.writable);
  } else if (req.writableFinished && !this.aborted) {
    assert(req.finished);
    // We can assume `req.finished` means all data has been written since:
    // - `'responseOnEnd'` means we have been assigned a socket.
    // - when we have a socket we write directly to it without buffering.
    // - `req.finished` means `end()` has been called and no further data.
    //   can be written
    // In addition, `req.writableFinished` means all data written has been
    // accepted by the kernel. (i.e. the `req.socket` is drained).Without
    // this constraint, we may assign a non drained socket to a request.
    responseKeepAlive(req);
  }
}

function responseOnTimeout() {
  const req = this._httpMessage;
  if (!req) return;
  const res = req.res;
  if (!res) return;
  res.emit('timeout');
}

// This function is necessary in the case where we receive the entire response
// from the server before we finish sending out the request.
function requestOnFinish() {
  const req = this;

  if (req.shouldKeepAlive && req._ended)
    responseKeepAlive(req);
}

function emitFreeNT(req) {
  req._closed = true;
  req.emit('close');
  if (req.socket) {
    req.socket.emit('free');
  }
}

function tickOnSocket(req, socket) {
  const parser = parsers.alloc();
  req.socket = socket;
  const lenient = req.insecureHTTPParser === undefined ?
    isLenient() : req.insecureHTTPParser;
  parser.initialize(HTTPParser.RESPONSE,
                    new HTTPClientAsyncResource('HTTPINCOMINGMESSAGE', req),
                    req.maxHeaderSize || 0,
                    lenient ? kLenientAll : kLenientNone);
  parser.socket = socket;
  parser.outgoing = req;
  req.parser = parser;

  socket.parser = parser;
  socket._httpMessage = req;

  // Propagate headers limit from request object to parser
  if (typeof req.maxHeadersCount === 'number') {
    parser.maxHeaderPairs = req.maxHeadersCount << 1;
  }

  parser.joinDuplicateHeaders = req.joinDuplicateHeaders;

  parser.onIncoming = parserOnIncomingClient;
  socket.on('error', socketErrorListener);
  socket.on('data', socketOnData);
  socket.on('end', socketOnEnd);
  socket.on('close', socketCloseListener);
  socket.on('drain', ondrain);

  if (
    req.timeout !== undefined ||
    (req.agent && req.agent.options && req.agent.options.timeout)
  ) {
    listenSocketTimeout(req);
  }
  req.emit('socket', socket);
}

function emitRequestTimeout() {
  const req = this._httpMessage;
  if (req) {
    req.emit('timeout');
  }
}

function listenSocketTimeout(req) {
  if (req.timeoutCb) {
    return;
  }
  // Set timeoutCb so it will get cleaned up on request end.
  req.timeoutCb = emitRequestTimeout;
  // Delegate socket timeout event.
  if (req.socket) {
    req.socket.once('timeout', emitRequestTimeout);
  } else {
    req.on('socket', (socket) => {
      socket.once('timeout', emitRequestTimeout);
    });
  }
}

ClientRequest.prototype.onSocket = function onSocket(socket, err) {
  // TODO(ronag): Between here and onSocketNT the socket
  // has no 'error' handler.
  process.nextTick(onSocketNT, this, socket, err);
};

function onSocketNT(req, socket, err) {
  if (req.destroyed || err) {
    req.destroyed = true;

    function _destroy(req, err) {
      if (!req.aborted && !err) {
        err = connResetException('socket hang up');
      }
      if (err) {
        req.emit('error', err);
      }
      req._closed = true;
      req.emit('close');
    }

    if (socket) {
      if (!err && req.agent && !socket.destroyed) {
        socket.emit('free');
      } else {
        finished(socket.destroy(err || req[kError]), (er) => {
          if (er?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
            er = null;
          }
          _destroy(req, er || err);
        });
        return;
      }
    }

    _destroy(req, err || req[kError]);
  } else {
    tickOnSocket(req, socket);
    req._flush();
  }
}

ClientRequest.prototype._deferToConnect = _deferToConnect;
function _deferToConnect(method, arguments_) {
  // This function is for calls that need to happen once the socket is
  // assigned to this request and writable. It's an important promisy
  // thing for all the socket calls that happen either now
  // (when a socket is assigned) or in the future (when a socket gets
  // assigned out of the pool and is eventually writable).

  const callSocketMethod = () => {
    if (method)
      ReflectApply(this.socket[method], this.socket, arguments_);
  };

  const onSocket = () => {
    if (this.socket.writable) {
      callSocketMethod();
    } else {
      this.socket.once('connect', callSocketMethod);
    }
  };

  if (!this.socket) {
    this.once('socket', onSocket);
  } else {
    onSocket();
  }
}

ClientRequest.prototype.setTimeout = function setTimeout(msecs, callback) {
  if (this._ended) {
    return this;
  }

  listenSocketTimeout(this);
  msecs = getTimerDuration(msecs, 'msecs');
  if (callback) this.once('timeout', callback);

  if (this.socket) {
    setSocketTimeout(this.socket, msecs);
  } else {
    this.once('socket', (sock) => setSocketTimeout(sock, msecs));
  }

  return this;
};

function setSocketTimeout(sock, msecs) {
  if (sock.connecting) {
    sock.once('connect', function() {
      sock.setTimeout(msecs);
    });
  } else {
    sock.setTimeout(msecs);
  }
}

ClientRequest.prototype.setNoDelay = function setNoDelay(noDelay) {
  this._deferToConnect('setNoDelay', [noDelay]);
};

ClientRequest.prototype.setSocketKeepAlive =
    function setSocketKeepAlive(enable, initialDelay) {
      this._deferToConnect('setKeepAlive', [enable, initialDelay]);
    };

ClientRequest.prototype.clearTimeout = function clearTimeout(cb) {
  this.setTimeout(0, cb);
};

module.exports = {
  ClientRequest,
};
              // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const {
  ArrayPrototypeIncludes,
  ArrayPrototypeIndexOf,
  ArrayPrototypePop,
  ArrayPrototypePush,
  ArrayPrototypeShift,
  ArrayPrototypeSome,
  ArrayPrototypeSplice,
  FunctionPrototypeCall,
  ObjectCreate,
  ObjectKeys,
  ObjectSetPrototypeOf,
  ObjectValues,
  StringPrototypeIndexOf,
  StringPrototypeSplit,
  StringPrototypeStartsWith,
  StringPrototypeSubstr,
  Symbol,
} = primordials;

const net = require('net');
const EventEmitter = require('events');
let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
  debug = fn;
});
const { AsyncResource } = require('async_hooks');
const { async_id_symbol } = require('internal/async_hooks').symbols;
const {
  kEmptyObject,
  once,
} = require('internal/util');
const {
  validateNumber,
  validateOneOf,
  validateString,
} = require('internal/validators');

const kOnKeylog = Symbol('onkeylog');
const kRequestOptions = Symbol('requestOptions');
const kRequestAsyncResource = Symbol('requestAsyncResource');
// New Agent code.

// The largest departure from the previous implementation is that
// an Agent instance holds connections for a variable number of host:ports.
// Surprisingly, this is still API compatible as far as third parties are
// concerned. The only code that really notices the difference is the
// request object.

// Another departure is that all code related to HTTP parsing is in
// ClientRequest.onSocket(). The Agent is now *strictly*
// concerned with managing a connection pool.

class ReusedHandle {
  constructor(type, handle) {
    this.type = type;
    this.handle = handle;
  }
}

function freeSocketErrorListener(err) {
  const socket = this;
  debug('SOCKET ERROR on FREE socket:', err.message, err.stack);
  socket.destroy();
  socket.emit('agentRemove');
}

function Agent(options) {
  if (!(this instanceof Agent))
    return new Agent(options);

  FunctionPrototypeCall(EventEmitter, this);

  this.defaultPort = 80;
  this.protocol = 'http:';

  this.options = { __proto__: null, ...options };

  if (this.options.noDelay === undefined)
    this.options.noDelay = true;

  // Don't confuse net and make it think that we're connecting to a pipe
  this.options.path = null;
  this.requests = ObjectCreate(null);
  this.sockets = ObjectCreate(null);
  this.freeSockets = ObjectCreate(null);
  this.keepAliveMsecs = this.options.keepAliveMsecs || 1000;
  this.keepAlive = this.options.keepAlive || false;
  this.maxSockets = this.options.maxSockets || Agent.defaultMaxSockets;
  this.maxFreeSockets = this.options.maxFreeSockets || 256;
  this.scheduling = this.options.scheduling || 'lifo';
  this.maxTotalSockets = this.options.maxTotalSockets;
  this.totalSocketCount = 0;

  validateOneOf(this.scheduling, 'scheduling', ['fifo', 'lifo']);

  if (this.maxTotalSockets !== undefined) {
    validateNumber(this.maxTotalSockets, 'maxTotalSockets', 1);
  } else {
    this.maxTotalSockets = Infinity;
  }

  this.on('free', (socket, options) => {
    const name = this.getName(options);
    debug('agent.on(free)', name);

    // TODO(ronag): socket.destroy(err) might have been called
    // before coming here and have an 'error' scheduled. In the
    // case of socket.destroy() below this 'error' has no handler
    // and could cause unhandled exception.

    if (!socket.writable) {
      socket.destroy();
      return;
    }

    const requests = this.requests[name];
    if (requests && requests.length) {
      const req = ArrayPrototypeShift(requests);
      const reqAsyncRes = req[kRequestAsyncResource];
      if (reqAsyncRes) {
        // Run request within the original async context.
        reqAsyncRes.runInAsyncScope(() => {
          asyncResetHandle(socket);
          setRequestSocket(this, req, socket);
        });
        req[kRequestAsyncResource] = null;
      } else {
        setRequestSocket(this, req, socket);
      }
      if (requests.length === 0) {
        delete this.requests[name];
      }
      return;
    }

    // If there are no pending requests, then put it in
    // the freeSockets pool, but only if we're allowed to do so.
    const req = socket._httpMessage;
    if (!req || !req.shouldKeepAlive || !this.keepAlive) {
      socket.destroy();
      return;
    }

    const freeSockets = this.freeSockets[name] || [];
    const freeLen = freeSockets.length;
    let count = freeLen;
    if (this.sockets[name])
      count += this.sockets[name].length;

    if (this.totalSocketCount > this.maxTotalSockets ||
        count > this.maxSockets ||
        freeLen >= this.maxFreeSockets ||
        !this.keepSocketAlive(socket)) {
      socket.destroy();
      return;
    }

    this.freeSockets[name] = freeSockets;
    socket[async_id_symbol] = -1;
    socket._httpMessage = null;
    this.removeSocket(socket, options);

    socket.once('error', freeSocketErrorListener);
    ArrayPrototypePush(freeSockets, socket);
  });

  // Don't emit keylog events unless there is a listener for them.
  this.on('newListener', maybeEnableKeylog);
}
ObjectSetPrototypeOf(Agent.prototype, EventEmitter.prototype);
ObjectSetPrototypeOf(Agent, EventEmitter);

function maybeEnableKeylog(eventName) {
  if (eventName === 'keylog') {
    this.removeListener('newListener', maybeEnableKeylog);
    // Future sockets will listen on keylog at creation.
    const agent = this;
    this[kOnKeylog] = function onkeylog(keylog) {
      agent.emit('keylog', keylog, this);
    };
    // Existing sockets will start listening on keylog now.
    const sockets = ObjectValues(this.sockets);
    for (let i = 0; i < sockets.length; i++) {
      sockets[i].on('keylog', this[kOnKeylog]);
    }
  }
}

Agent.defaultMaxSockets = Infinity;

Agent.prototype.createConnection = net.createConnection;

// Get the key for a given set of request options
Agent.prototype.getName = function getName(options = kEmptyObject) {
  let name = options.host || 'localhost';

  name += ':';
  if (options.port)
    name += options.port;

  name += ':';
  if (options.localAddress)
    name += options.localAddress;

  // Pacify parallel/test-http-agent-getname by only appending
  // the ':' when options.family is set.
  if (options.family === 4 || options.family === 6)
    name += `:${options.family}`;

  if (options.socketPath)
    name += `:${options.socketPath}`;

  return name;
};

Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */,
                                                 localAddress/* legacy */) {
  // Legacy API: addRequest(req, host, port, localAddress)
  if (typeof options === 'string') {
    options = {
      __proto__: null,
      host: options,
      port,
      localAddress,
    };
  }

  options = { __proto__: null, ...options, ...this.options };
  if (options.socketPath)
    options.path = options.socketPath;

  if (!options.servername && options.servername !== '')
    options.servername = calculateServerName(options, req);

  const name = this.getName(options);
  if (!this.sockets[name]) {
    this.sockets[name] = [];
  }

  const freeSockets = this.freeSockets[name];
  let socket;
  if (freeSockets) {
    while (freeSockets.length && freeSockets[0].destroyed) {
      ArrayPrototypeShift(freeSockets);
    }
    socket = this.scheduling === 'fifo' ?
      ArrayPrototypeShift(freeSockets) :
      ArrayPrototypePop(freeSockets);
    if (!freeSockets.length)
      delete this.freeSockets[name];
  }

  const freeLen = freeSockets ? freeSockets.length : 0;
  const sockLen = freeLen + this.sockets[name].length;

  if (socket) {
    asyncResetHandle(socket);
    this.reuseSocket(socket, req);
    setRequestSocket(this, req, socket);
    ArrayPrototypePush(this.sockets[name], socket);
  } else if (sockLen < this.maxSockets &&
             this.totalSocketCount < this.maxTotalSockets) {
    debug('call onSocket', sockLen, freeLen);
    // If we are under maxSockets create a new one.
    this.createSocket(req, options, (err, socket) => {
      if (err)
        req.onSocket(socket, err);
      else
        setRequestSocket(this, req, socket);
    });
  } else {
    debug('wait for socket');
    // We are over limit so we'll add it to the queue.
    if (!this.requests[name]) {
      this.requests[name] = [];
    }

    // Used to create sockets for pending requests from different origin
    req[kRequestOptions] = options;
    // Used to capture the original async context.
    req[kRequestAsyncResource] = new AsyncResource('QueuedRequest');

    ArrayPrototypePush(this.requests[name], req);
  }
};

Agent.prototype.createSocket = function createSocket(req, options, cb) {
  options = { __proto__: null, ...options, ...this.options };
  if (options.socketPath)
    options.path = options.socketPath;

  if (!options.servername && options.servername !== '')
    options.servername = calculateServerName(options, req);

  const name = this.getName(options);
  options._agentKey = name;

  debug('createConnection', name, options);
  options.encoding = null;

  const oncreate = once((err, s) => {
    if (err)
      return cb(err);
    if (!this.sockets[name]) {
      this.sockets[name] = [];
    }
    ArrayPrototypePush(this.sockets[name], s);
    this.totalSocketCount++;
    debug('sockets', name, this.sockets[name].length, this.totalSocketCount);
    installListeners(this, s, options);
    cb(null, s);
  });
  // When keepAlive is true, pass the related options to createConnection
  if (this.keepAlive) {
    options.keepAlive = this.keepAlive;
    options.keepAliveInitialDelay = this.keepAliveMsecs;
  }
  const newSocket = this.createConnection(options, oncreate);
  if (newSocket)
    oncreate(null, newSocket);
};

function calculateServerName(options, req) {
  let servername = options.host;
  const hostHeader = req.getHeader('host');
  if (hostHeader) {
    validateString(hostHeader, 'options.headers.host');

    // abc => abc
    // abc:123 => abc
    // [::1] => ::1
    // [::1]:123 => ::1
    if (StringPrototypeStartsWith(hostHeader, '[')) {
      const index = StringPrototypeIndexOf(hostHeader, ']');
      if (index === -1) {
        // Leading '[', but no ']'. Need to do something...
        servername = hostHeader;
      } else {
        servername = StringPrototypeSubstr(hostHeader, 1, index - 1);
      }
    } else {
      servername = StringPrototypeSplit(hostHeader, ':', 1)[0];
    }
  }
  // Don't implicitly set invalid (IP) servernames.
  if (net.isIP(servername))
    servername = '';
  return servername;
}

function installListeners(agent, s, options) {
  function onFree() {
    debug('CLIENT socket onFree');
    agent.emit('free', s, options);
  }
  s.on('free', onFree);

  function onClose(err) {
    debug('CLIENT socket onClose');
    // This is the only place where sockets get removed from the Agent.
    // If you want to remove a socket from the pool, just close it.
    // All socket errors end in a close event anyway.
    agent.totalSocketCount--;
    agent.removeSocket(s, options);
  }
  s.on('close', onClose);

  function onTimeout() {
    debug('CLIENT socket onTimeout');

    // Destroy if in free list.
    // TODO(ronag): Always destroy, even if not in free list.
    const sockets = agent.freeSockets;
    if (ArrayPrototypeSome(ObjectKeys(sockets), (name) =>
      ArrayPrototypeIncludes(sockets[name], s),
    )) {
      return s.destroy();
    }
  }
  s.on('timeout', onTimeout);

  function onRemove() {
    // We need this function for cases like HTTP 'upgrade'
    // (defined by WebSockets) where we need to remove a socket from the
    // pool because it'll be locked up indefinitely
    debug('CLIENT socket onRemove');
    agent.totalSocketCount--;
    agent.removeSocket(s, options);
    s.removeListener('close', onClose);
    s.removeListener('free', onFree);
    s.removeListener('timeout', onTimeout);
    s.removeListener('agentRemove', onRemove);
  }
  s.on('agentRemove', onRemove);

  if (agent[kOnKeylog]) {
    s.on('keylog', agent[kOnKeylog]);
  }
}

Agent.prototype.removeSocket = function removeSocket(s, options) {
  const name = this.getName(options);
  debug('removeSocket', name, 'writable:', s.writable);
  const sets = [this.sockets];

  // If the socket was destroyed, remove it from the free buffers too.
  if (!s.writable)
    ArrayPrototypePush(sets, this.freeSockets);

  for (let sk = 0; sk < sets.length; sk++) {
    const sockets = sets[sk];

    if (sockets[name]) {
      const index = ArrayPrototypeIndexOf(sockets[name], s);
      if (index !== -1) {
        ArrayPrototypeSplice(sockets[name], index, 1);
        // Don't leak
        if (sockets[name].length === 0)
          delete sockets[name];
      }
    }
  }

  let req;
  if (this.requests[name] && this.requests[name].length) {
    debug('removeSocket, have a request, make a socket');
    req = this.requests[name][0];
  } else {
    // TODO(rickyes): this logic will not be FIFO across origins.
    // There might be older requests in a different origin, but
    // if the origin which releases the socket has pending requests
    // that will be prioritized.
    const keys = ObjectKeys(this.requests);
    for (let i = 0; i < keys.length; i++) {
      const prop = keys[i];
      // Check whether this specific origin is already at maxSockets
      if (this.sockets[prop] && this.sockets[prop].length) break;
      debug('removeSocket, have a request with different origin,' +
        ' make a socket');
      req = this.requests[prop][0];
      options = req[kRequestOptions];
      break;
    }
  }

  if (req && options) {
    req[kRequestOptions] = undefined;
    // If we have pending requests and a socket gets closed make a new one
    this.createSocket(req, options, (err, socket) => {
      if (err)
        req.onSocket(socket, err);
      else
        socket.emit('free');
    });
  }

};

Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
  socket.setKeepAlive(true, this.keepAliveMsecs);
  socket.unref();

  const agentTimeout = this.options.timeout || 0;
  if (socket.timeout !== agentTimeout) {
    socket.setTimeout(agentTimeout);
  }

  return true;
};

Agent.prototype.reuseSocket = function reuseSocket(socket, req) {
  debug('have free socket');
  socket.removeListener('error', freeSocketErrorListener);
  req.reusedSocket = true;
  socket.ref();
};

Agent.prototype.destroy = function destroy() {
  const sets = [this.freeSockets, this.sockets];
  for (let s = 0; s < sets.length; s++) {
    const set = sets[s];
    const keys = ObjectKeys(set);
    for (let v = 0; v < keys.length; v++) {
      const setName = set[keys[v]];
      for (let n = 0; n < setName.length; n++) {
        setName[n].destroy();
      }
    }
  }
};

function setRequestSocket(agent, req, socket) {
  req.onSocket(socket);
  const agentTimeout = agent.options.timeout || 0;
  if (req.timeout === undefined || req.timeout === agentTimeout) {
    return;
  }
  socket.setTimeout(req.timeout);
}

function asyncResetHandle(socket) {
  // Guard against an uninitialized or user supplied Socket.
  const handle = socket._handle;
  if (handle && typeof handle.asyncReset === 'function') {
    // Assign the handle a new asyncId and run any destroy()/init() hooks.
    handle.asyncReset(new ReusedHandle(handle.getProviderType(), handle));
    socket[async_id_symbol] = handle.getAsyncId();
  }
}

module.exports = {
  Agent,
  globalAgent: new Agent(),
};
\u Internal error  at position  JSON: stack limit exceeded JSON: no input JSON: invalid token JSON: invalid number JSON: invalid string JSON: unexpected array end JSON: string literal expected JSON: colon expected JSON: unexpected map end JSON: value expected CBOR: invalid int32 CBOR: invalid double CBOR: invalid envelope CBOR: invalid string8 CBOR: invalid string16 CBOR: invalid binary CBOR: unsupported value CBOR: no input CBOR: invalid start byte CBOR: unexpected eof in array CBOR: unexpected eof in map CBOR: invalid map key CBOR: stack limit exceeded CBOR: trailing junk CBOR: map start expected CBOR: map stop expected INVALID ERROR CODE Message must be a valid JSON Message must be an object ' wasn't found object expected it != m_data.end()   `
     	     	     	     	     	     	     	     	     	     
     
     	     	     
     
     
     
     
     
     
     
     
     
     
     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     (
     	     @
     	     	     	     	     	     	     	     	     p	     	     	     	     	     	     	     	     	     	     	     	     	     	      	     	     	     	     	     	     	     
     	     P
     z
     	     	     	     	     	     	     	     	     	     	     	     	     z
     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     	     z
     	     	     	     	     	     z
     	     	     	     z
     	     	     	     	     	     	     	     z
     	     	     	     z
     	     z
          z
     	          P                                                                                                                                                                                                                                                                                                       0                                             `                                                                                                                   @     h                                                                 h                                                                                                                                                                                                                                 h                              h                    h                                        h                    h          h          h          
                                                            @               @     @     @     @     @     @     @     @     @     @                                                                                                                                                                                                                                                                                                         (                                             0                                                                                                                                                                                                                                                                                                                                                                                                                                                   0     `                                                                                                                                                                                                                                                                                                                                                                                                                   P                                                                                                                           P                x                                                                             x                                                                                                                                                                                                                                                                             x                                   x                       x                                               x                       x           x     (!     x                  N      N     `N     N     HN     HN     HN     HN     T     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     T     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     hU     T     hU     hU     hU     hU     hU     pT     hU     hU     hU     T     hU     hU     hU     hU     hU     hU     hU     T     hU     hU     hU     T     hU     XU     T     T          ؊     (     X               P          ی     ȉ                    0          8          P     x     H               p     `     P     @     0                                Ч                              p     `     P     @     (                         ئ     Ȧ                                                                                                                                                                                                                                                                                                                                                                                                                   н                                                  =          =     x                         h                              h                                   H     p                                                                 p                                                                                                                                                                                                                                 p                                                                                                              8                P                                                                           b                                                                             b                                                                                                                                                                                                                                                                             b                                                                                                                                                          `          	          X
     
     p                              @                             virtual void node::inspector::protocol::DictionaryValue::writeJSON(node::inspector::protocol::StringBuilder*) const                     0          P                               0                           Y      Z          0     X                                          p                P          0     0           P                                                @     @c     Z     `b     @Z     `]     n     k     `j     d      d     a                               `               0     P     `                0                                                  ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ Z     Invalid parameters              }    u}    @}            0123456789ABCDEF        JSON: unprocessed input remains JSON: comma or array end expected       JSON: comma or map end expected CBOR: unexpected eof expected value     CBOR: envelope size limit exceeded      Message must have integer 'id' property Message must have string 'method' property      /home/iojs/build/ws/out/Release/obj/gen/src/node/inspector/protocol/Protocol.cpp:671    ../src/inspector/node_string.h:103      ../src/inspector/node_string.h:99       ../src/inspector/node_string.h:98                               size_t node::inspector::protocol::Binary::size() const          node::inspector::protocol::String node::inspector::protocol::Binary::toBase64() const           static node::inspector::protocol::Binary node::inspector::protocol::Binary::fromSpan(const uint8_t*, size_t)                                                                             X                                              P     p                      @Q                                                                      t           p     `Y      %                                                                      `                                          0                                        @          #                               p     @                                    s          0                                                                                                                                                P     P                     `                                           @     }    51     @}            8}    51     }            `}    51     }                                                0            AwaitForDebuggerOnStart boolean value expected string value expected workerId workerInfo waitingForDebugger                      v      w     0x     y                     }     @}     |     {                      ~     }     pw     w                     ~     @~     w      z                     x     pz     v      q     1.0     NodeWorker.     NodeWorker              waitForDebuggerOwaitingForDebuggNodeWorker.attacNodeWorker.detacNodeWorker.receivedMessageFromWoNodeWorker.sendMNodeWorker.enablNodeWorker.disabrecordMode includedCategories array expected traceConfig recordAsMuchAsPossible recordContinuously recordUntilFull                           @          `                                     P                               p     p     1.0     NodeTracing.    NodeTracing     includedCategoriNodeTracing.dataNodeTracing.tracNodeTracing.getCNodeTracing.starNodeTracing.stop                `               P     1.0     NodeRuntime.    NodeRuntime             NodeRuntime.waitingForDisconnectNodeRuntime.notifyWhenWaitingFor                     P                                     p     0                                              0   0   0   0   0   /   (   '                            EnableAccessChecks      p                                   P     `     !constructor_or_back_pointer().IsMap() Check failed: %s.        !obj->GetInstanceCallHandler().IsUndefined(isolate)     parent_prototype->IsHeapObject() DisableAccessChecks ApiNatives::InstantiateObject unreachable code     value != SideEffectType::kHasNoSideEffect       
#
# Fatal error in %s
# %s
#

 HostDefinedOptions is not a PrimitiveArray, please use ScriptOrigin::GetHostDefinedOptions()    ScriptOrigin::HostDefinedOptions Internal field out of bounds Not a native context Negative index Index too large 
#
# Fatal %s OOM in %s
#

   Fatal process out of memory: %s API fatal error handler returned after process out of memory 
<--- Last few GCs --->
%s
 
<--- JS stacktrace --->
%s
   Disposing the isolate that is entered by a thread. v8::Isolate::Dispose()       isolate == context->GetIsolate()        source != nullptr || source_length_ == 0        initial_heap_size_in_bytes <= maximum_heap_size_in_bytes Maybe value is Nothing. v8::FromJust Empty MaybeLocal. v8::ToLocalChecked Internal field out of bounds.        WeakCallbackInfo::GetInternalField      Entering the V8 API without proper locking in place HandleScope::HandleScope Escape value set twice EscapableHandleScope::Escape        Cannot exit non-entered context v8::Context::Exit()     Context::GetNumberOfEmbedderDataFields  v8::Context::GetEmbedderData()  v8::Context::SetEmbedderData()  v8::Context::GetAlignedPointerFromEmbedderData() Pointer is not aligned v8::Context::SetAlignedPointerInEmbedderData()  Invalid value, must be a primitive or a Template v8::Template::Set Protoype must be undefined   v8::FunctionTemplate::SetPrototypeProviderTemplate      Prototype provider must be empty        FunctionTemplate already instantiated   Protoype provider must be empty v8::FunctionTemplate::Inherit   v8::FunctionTemplate::SetCallHandler    Fast API calls are not supported for constructor functions. FunctionTemplate::New       FunctionTemplate::NewWithCFunctionOverloads     v8::FunctionTemplate::SetLength v8::FunctionTemplate::SetClassName      v8::FunctionTemplate::SetAcceptAnyReceiver      v8::FunctionTemplate::ReadOnlyPrototype v8::FunctionTemplate::RemovePrototype   ObjectTemplateSetNamedPropertyHandler   v8::ObjectTemplate::MarkAsUndetectable  v8::ObjectTemplate::SetAccessCheckCallback      v8::ObjectTemplate::SetAccessCheckCallbackWithHandler   v8::ObjectTemplate::SetHandler  v8::ObjectTemplate::SetCallAsFunctionHandler sfi.script().IsScript()    length must be equal or greater than zero v8::PrimitiveArray::New       index must be greater than or equal to 0 and less than the array length v8::PrimitiveArray::Set v8::PrimitiveArray::Get Value is not a PrimitiveArray. This is a temporary issue, v8::Data and v8::PrimitiveArray will not be compatible in the future. v8::PrimitiveArray::Cast i < self->length()     Module status must be kErrored v8::Module::GetException v8::Module::SourceOffsetToLocation must be used on an SourceTextModule  v8::Module::SourceOffsetToLocation      v8::Module::GetModuleNamespace must be used on an instantiated module   v8::Module::GetModuleNamespace  v8::Module::GetUnboundModuleScript must be used on an SourceTextModule  v8::Module::GetUnboundModuleScript      v8::Module::ScriptId must be used on an SourceTextModule v8::Module::ScriptId   v8::Module::IsGraphAsync must be used on an instantiated module v8::Module::IsGraphAsync        Expected SharedFunctionInfo with wrapped source code.   v8::ScriptCompiler::CreateCodeCacheForFunction  Host-defined options has to be a PrimitiveArray PrimitiveArray can only contain primtive values ScriptOrigin()  i::Script::GetPositionInfo(script, i::StackFrameInfo::GetSourcePosition(self), &info, i::Script::WITH_OFFSET)   Isolate is not initialized or V8 has died       v8::internal::Internals::CheckInitialized Data is not a Value v8::Value::Cast Value is not an External v8::External::Cast Value is not an Object v8::Object::Cast Value is not a Function v8::Function::Cast Value is not a Boolean v8::Boolean::Cast Value is not a Name v8::Name::Cast Value is not a String v8::String::Cast Value is not a Symbol v8::Symbol::Cast Value is not a Private v8::Private::Cast Value is not a FixedArray v8::FixedArray::Cast Value is not a ModuleRequest v8::ModuleRequest::Cast Value is not a Module v8::Module::Cast Value is not a Number v8::Number::Cast() Value is not an Integer v8::Integer::Cast   Value is not a 32-bit signed integer v8::Int32::Cast    Value is not a 32-bit unsigned integer v8::Uint32::Cast Value is not a BigInt v8::BigInt::Cast Value is not a Context v8::Context::Cast Value is not an Array v8::Array::Cast Value is not a Map v8::Map::Cast Value is not a Set v8_Set_Cast Value is not a Promise v8::Promise::Cast  Value is not a Promise::Resolver v8::Promise::Resolver::Cast Value is not a Proxy v8::Proxy::Cast       Value is not a WasmMemoryObject v8::WasmMemoryObject::Cast      Value is not a WasmModuleObject v8::WasmModuleObject::Cast byte_lenght is too large v8::BackingStore::Reallocate Value is not an ArrayBuffer v8::ArrayBuffer::Cast()    Value is not an ArrayBufferView v8::ArrayBufferView::Cast() Value is not a TypedArray v8::TypedArray::Cast() Value is not a Uint8Array v8::Uint8Array::Cast() Value is not a Int8Array v8::Int8Array::Cast() Value is not a Uint16Array v8::Uint16Array::Cast() Value is not a Int16Array v8::Int16Array::Cast() Value is not a Uint32Array v8::Uint32Array::Cast() Value is not a Int32Array v8::Int32Array::Cast() Value is not a Float32Array v8::Float32Array::Cast() Value is not a Float64Array v8::Float64Array::Cast()  Value is not a Uint8ClampedArray v8::Uint8ClampedArray::Cast() Value is not a BigUint64Array v8::BigUint64Array::Cast() Value is not a BigInt64Array v8::BigInt64Array::Cast() Value is not a DataView v8::DataView::Cast()     Value is not a SharedArrayBuffer v8::SharedArrayBuffer::Cast() Value is not a Date v8::Date::Cast() Value is not a StringObject v8::StringObject::Cast() Value is not a SymbolObject v8::SymbolObject::Cast() Value is not a NumberObject v8::NumberObject::Cast() Value is not a BigIntObject v8::BigIntObject::Cast() Value is not a BooleanObject v8::BooleanObject::Cast() Value is not a RegExp v8::RegExp::Cast() No creation context available   v8::Object::GetCreationContextChecked        )                                        )                              `     0                               x     `     8                     @                     v          v     v     o                     v          expected == value expectedEncoding == encoding  v8::Object::GetInternalField()  v8::Object::SetInternalField()  v8::Object::GetAlignedPointerFromInternalField() Unaligned pointer      v8::Object::SetAlignedPointerInInternalField()  v8::Object::SetAlignedPointerInInternalFields() Embedder-vs-V8 build configuration mismatch. On embedder side pointer compression is %s while on V8 side it's %s.       Embedder-vs-V8 build configuration mismatch. On embedder side Smi value size is %d while on V8 side it's %d.    Embedder-vs-V8 build configuration mismatch. On embedder side sandboxed external pointers is %s while on V8 side it's %s.       Embedder-vs-V8 build configuration mismatch. On embedder side sandbox is %s while on V8 side it's %s.   isolate->builtins()->code(i::Builtin::kIllegal).IsCodeT()       Must be calld on a native context       v8::Context::GetMicrotaskQueue  Value is not an ObjectTemplate v8::ObjectTemplate::Cast Value is not a FunctionTemplate v8::FunctionTemplate::Cast Value is not a Signature v8::Signature::Cast Value is not an AccessorSignature v8::AccessorSignature::Cast (location_) != nullptr i::kMaxInt >= len i::kMaxInt >= length resource && resource->data() (resource) != nullptr (resource->data()) != nullptr    prototype must be null or object v8::Object::New Promise is still pending v8_Promise_Result (native_module_) != nullptr v8.wasm wasm.SerializeModule WasmModuleObject::Compile()        maybe_compiled.is_null() == i_isolate->has_pending_exception()  Only detachable ArrayBuffers can be detached v8::ArrayBuffer::Detach v8::ArrayBuffer::New       byte_length <= i::JSArrayBuffer::kMaxByteLength v8::ArrayBuffer::NewBackingStore        length exceeds max allowed value        v8::Uint8Array::New(Local<ArrayBuffer>, size_t, size_t) i::FLAG_harmony_sharedarraybuffer       v8::Uint8Array::New(Local<SharedArrayBuffer>, size_t, size_t)   v8::Int8Array::New(Local<ArrayBuffer>, size_t, size_t)  v8::Int8Array::New(Local<SharedArrayBuffer>, size_t, size_t)    v8::Uint16Array::New(Local<ArrayBuffer>, size_t, size_t)        v8::Uint16Array::New(Local<SharedArrayBuffer>, size_t, size_t)  v8::Int16Array::New(Local<ArrayBuffer>, size_t, size_t) v8::Int16Array::New(Local<SharedArrayBuffer>, size_t, size_t)   v8::Uint32Array::New(Local<ArrayBuffer>, size_t, size_t)        v8::Uint32Array::New(Local<SharedArrayBuffer>, size_t, size_t)  v8::Int32Array::New(Local<ArrayBuffer>, size_t, size_t) v8::Int32Array::New(Local<SharedArrayBuffer>, size_t, size_t)   v8::Float32Array::New(Local<ArrayBuffer>, size_t, size_t)       v8::Float32Array::New(Local<SharedArrayBuffer>, size_t, size_t) v8::Float64Array::New(Local<ArrayBuffer>, size_t, size_t)       v8::Float64Array::New(Local<SharedArrayBuffer>, size_t, size_t) v8::Uint8ClampedArray::New(Local<ArrayBuffer>, size_t, size_t)  v8::Uint8ClampedArray::New(Local<SharedArrayBuffer>, size_t, size_t)    v8::BigUint64Array::New(Local<ArrayBuffer>, size_t, size_t)     v8::BigUint64Array::New(Local<SharedArrayBuffer>, size_t, size_t)       v8::BigInt64Array::New(Local<ArrayBuffer>, size_t, size_t)      v8::BigInt64Array::New(Local<SharedArrayBuffer>, size_t, size_t)        v8::SharedArrayBuffer::NewBackingStore  (isolate->heap()->cpp_heap()) == nullptr        (GetEmbedderHeapTracer()) == nullptr Must use --expose-gc       v8::Isolate::RequestGarbageCollectionForTesting kMinReasonableBytes <= change_in_bytes && change_in_bytes < kMaxReasonableBytes V8.GCLowMemoryNotification stack_limit  deque::_M_range_check: __n (which is %zu)>= this->size() (which is %zu) Unknown serialization format v8::HeapSnapshot::Serialize Invalid stream chunk size      Out of memory: HashMap::Initialize      internal::kGlobalHandleZapValue != *reinterpret_cast<uint64_t*>(val_) (address_) != nullptr (type_info_) != nullptr     disabled-by-default-v8.runtime V8.ExternalCallback Expected instantiated module Module::Evaluate        self->IsJSFunction() && i::JSFunction::cast(*self).shared().IsApiFunction()     v8::Module::SyntheticModuleSetExport must only be called on a SyntheticModule   v8::Module::SyntheticModuleSetExport    disabled-by-default-v8.compile V8.CompileStreamedScript V8.CompileStreamedModule        backtrack_limit is too large or too small.      v8::RegExp::NewWithBacktrackLimit Must set backtrack_limit APISetAccessor V8.CompileScript      v8::ScriptCompiler::CompileModule must be used to compile modules       v8::ScriptCompiler::CompileUnboundScript Invalid CompileOptions v8::ScriptCompiler::CompileModule       Invalid ScriptOrigin: is_module must be true v8::ScriptCompiler::Compile        Global template needs to have access checks enabled.    Global template needs to have access check handlers. v8::Context::NewRemoteContext      InstanceTemplate needs to have access checks enabled.   v8::FunctionTemplate::NewRemoteInstance InstanceTemplate needs to have access check handlers.   backing_store->ByteLength() != 0 implies backing_store->Data() != nullptr       Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer v8_ArrayBuffer_New        Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer v8_SharedArrayBuffer_New    params.array_buffer_allocator == nullptr || params.array_buffer_allocator == allocator.get()    (params.array_buffer_allocator) != nullptr      V8 snapshot blob was not set during initialization. This can mean that the snapshot blob file is corrupted or missing.  Failed to deserialize the V8 snapshot blob. This can mean that the snapshot blob file is corrupted or missing.  The current platform's foreground task runner does not have non-nestable tasks enabled. The embedder must provide one.  CreateBlob() cannot be called more than once on the same SnapshotCreator.       v8::SnapshotCreator::CreateBlob CreateBlob() cannot be called before the default context is set.        handle_checker.CheckGlobalAndEternalHandles() v8::SharedArrayBuffer::New                                          InterpretedFunction BytecodeHandler LazyCompile Relocation          |~    2!        c׊    }    ~    }    }    }    q    {~    }                    @     0     p                                               @                                               0                           0                                               P     `                                                           p          0                p                                     P     P     P      	                                     P                                     P          P     P           P          p                     P                    `     8                                                     A        A      0         GG   ?C?     @@      C                    0                    0     p     p          @                                      О                         0               p                         М     ș          P     0                                        p                                    p     p               0          `     `     p                               `               @                p          (     `                                                                   0     @     P     x     h     X     H     0                                              h     P     8                               h     X     @     (                                         p     X     8     (new_string) != nullptr (anonymous function) .static_home_object anonymous bigint <computed> .brand .default .for .generator_object .home_object .result .repl_result .switch_tag get  let .new.target #constructor return set  .this_function  AstStringConstants                      @     `                     P     p     	     p	      	     	     `	     O	     O	     	     
     p
      
     
     `
     O
     O
     
     =(      )     M(     h(     (     (     (     (     )      .     ,     -     -     -     -     ,     ,     @7     @6     6     07     6     7      6     06     8@     @     ?      @      @     ?     ?     n@     (context function) super (var) ImportCall( (... yield*  (intermediate value)    @w     @w     y     6     ~     ~     ~          ߀     (y     @w     y     }     @w     @w     (y     u}     >~     y     @w     W~     ~     ~     w~     g~     Y}     (y                                   }     Y}     i}          Y     <     @w     Q     
~     @w     (y     .~               @w     G~     '     (y     }     }     (y     x     Y     x     x     9y     {     z     |     |     s|     {     x     x     Ey     {{     x     x     x     y     z     9y     x     {     	|     c|     |     |     hy     x     |     S|     y     z     cz     Sz     Cz     hy     xy     @{     Y     z     x     }     {     x     x     z     w     y     x     z     )|     x     z     P{     x     `x     Y               	     3                         B     ؄               #               ؄     R          	          d     L     4               .     ؄               w     ߆               r     .     F                         ͇     |          ؄     Z     D               *          ؄     S     k     ؄               ԋ     ԋ           Î          ݍ          z          ȋ     ԋ               ԋ     ԋ     ȋ          ֌           ԋ     ݏ     Ə     !     
     9     H     ȋ     Ԑ                    P     O     8     H     v                     ԋ          &     ԋ     ȋ     f     Ԏ     M     ԋ     ܌          ȋ          }     ȋ                |     |     $     F                     ]     /     p     |     0     ٔ     |     |     p               $     |     	               j     S     _     p     g     P               B     +          _                          |               |     p          W          |          ~     p     ב          p     /                          p          ϙ                                                                                3     ՚               З                                             З          z          -               I                    !     ~               v          Ҙ     E                    ̝     ̝               ܠ                              ̝               ̝     ̝          D     4          ̝                    9          !          h     g     P     ~     =     &          !     8          Ģ          ̝     =     ß     ̝                    W     ̝                                   o     Ģ     *     *     T          c     F     0          5          *     `     K     *     *               ̧     T     *     !          y     c     M     ¦     @     I     3                              ¦     ئ          %     ˪     *          _     *     @          w     ۨ     *     7          @     է                    %               :     #     4     p               D               F     p                    i     A     :          ƭ     ܭ          5     K     $          v                    ί          `     $     ]     Z     %               a                    ߬     ̫               J                    ʮ          ̥     %     Ա     Ա     8                    0     `     p     ȱ     Ա     D     @     Ա     Ա     ȱ     l          8     Ա     @                    (           ȱ          з     p                                `          ϸ          Ա               Ա     ȱ                    Ա               ȱ               ȱ     H     ϸ               P     p     `           H                6          Y                     6     ɹ          P                    к          x          6     X     P     @     0     X     H     8                    ͼ     `                         6                         h          6               6          ͼ     ?. (...)                                                l               
                         B                         S     ?               "               n     Z     F                    "     6     X                                                  *               c                                   \     \          g     +          o     A          P     \               \     \     P                    \                                   P                         |     h     T                    ?           \          *     \     P     O     p          \     +          P          c     P          ?                    8          0                                                        D     P                                                             x     `     `     H     0           8                         `                          H                    p                                                  @                              x               P               x          `               @          p                    x     8                     x     `                                        X               x     H     P                         x          (     x     8          L     L     h     p     0     H                8     @     L     t          L     L     @          P     h     L                                   @     X     @     (                                         ]     p     L     `     P     L     @     x               L                @     8          @           ]     is_sloppy(language_mode())      E     c     _                              H     x               =          P     P               0     =               x     x     0                    x          l     x                                             7                    o          x     V     x          x     x                         x          x               x                    0                    P               8                               0     0                P     8     0               0     h          p     H     p                          P     p     p          H     0          0          0     0     H     p          0     0          0     H     H     0     H     H          enclosingSourceRanges->HasRange(SourceRangeKind::kContinuation) could not open file. If on Android, try passing --redirect-code-traces-to=/sdcard/Download/<file-name>  [Baseline batch compilation] Enqueued function   with estimated size %d (current budget: %d/%d)
        [Baseline batch compilation] Compiling current batch of %d functions
   [Concurrent Sparkplug] compiling %zu functions
 [Concurrent Sparkplug Off Thread] Function   installed
                                  P                                                               ~    x~    ~    	~    P                                              @                     0     p           @          0    H     8     (                                         x     X     @                           h     h                                          h     ]     ]     ]     ]     h     h     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]     ]           p     @          p     0          |     ~               (     @     X     p                                         0     `     p                    :     :     :     :     :     :     :     :     :     :     :     z     \     L     +     
                         *     *                                   q     a     Q     A     1     !                                   Q     A     1     !                                                       a     Q     A     1     !                                                       q     a     Q     A     1     !                                                            q     a     Q     A     1     !                                                       q     q     a     Q     A     1     !                                                       q                                   x     h     X     H     8     (          q     a               w     
     
                                   |     l     \     L     \     L          |                              l     +                                                            x     F     ;                              &     6     W                         V     P     /                              i     K     :             BaselineCompiler                              `           4Y    @1Y    0Y    P2Y    	
           
               0
     
             Fatal JavaScript invalid array length %u        array->length().ToArrayLength(&actual_new_len) it.HasAccess()   LookupIterator::ACCESSOR == it.state()                  P     `               DoubleToUint32IfEqualToSelf(start_index, &start)        DoubleToUint32IfEqualToSelf(end_index, &end) Array.prototype.groupBy Array.prototype.groupByToMap unimplemented code    x     x     x     x     0     0     x     x     x     x     x     x     К               h     h     @     @     @     @     @     @     @     @     @     @     @                                                            z     x     x     x     x                 x     x     x     x     x     x                                                                                                                                                                                                                                           p     p     p     p     p     p     p     p     p     p     p                                                                 Array.prototype.concat    A                          $     ;     N     c     v               SharedArrayBuffer.prototype.slice ArrayBuffer.prototype.slice   get SharedArrayBuffer.prototype.byteLength round_return_value   0 == array_buffer->byte_length() ArrayBuffer.prototype.resize   SharedArrayBuffer.prototype.grow              CBigInt.prototype.toLocaleString BigInt.prototype.toString BigInt.prototype.valueOf getColumnNumber getEnclosingColumnNumber getEnclosingLineNumber getEvalOrigin getFileName getFunction getFunctionName getLineNumber getMethodName getPosition getPromiseIndex getScriptNameOrSourceUrl getThis getTypeName isAsync isConstructor isEval isNative isPromiseAll isToplevel Map.prototype.clear Set.prototype.clear     5     4     4      5     8     `4     8     8     @3     4     2      5     8     `4     !isolate->has_pending_exception()       !isolate->has_scheduled_exception() dirXml countReset profileEnd timeLog timeEnd timeStamp DataView constructor Date.prototype.setDate Date.prototype.setFullYear Date.prototype.setHours       Date.prototype.setMilliseconds Date.prototype.setMinutes Date.prototype.setMonth Date.prototype.setSeconds Date.prototype.setTime Date.prototype.setUTCDate Date.prototype.setUTCFullYear Date.prototype.setUTCHours    Date.prototype.setUTCMilliseconds Date.prototype.setUTCMinutes Date.prototype.setUTCMonth Date.prototype.setUTCSeconds Date.prototype.toDateString Date.prototype.toISOString   %04d-%02d-%02dT%02d:%02d:%02d.%03dZ     -%06d-%02d-%02dT%02d:%02d:%02d.%03dZ    +%06d-%02d-%02dT%02d:%02d:%02d.%03dZ Date.prototype.toString Date.prototype.toTimeString        Date.prototype.toLocaleDateString Date.prototype.toLocaleString Date.prototype.toLocaleTimeString Date.prototype.toUTCString Date.prototype.getYear Date.prototype.setYear                                                                                                                               @ Z]	> Z]	>C anonymous( ) {
 
}) async function async function* Function.prototype.toString                                 String.prototype.toUpperCase String.prototype.normalize Intl.v8BreakIterator.supportedLocalesOf Intl.NumberFormat.supportedLocalesOf    Intl.NumberFormat.prototype.formatToParts       Intl.DateTimeFormat.prototype.resolvedOptions   Intl.DateTimeFormat.supportedLocalesOf  Intl.DateTimeFormat.prototype.formatToParts Intl.DisplayNames   Intl.DisplayNames.prototype.resolvedOptions     Intl.DisplayNames.supportedLocalesOf    Intl.DisplayNames.prototype.of Intl.NumberFormat success.FromJust()     Intl.NumberFormat.prototype.resolvedOptions     get Intl.NumberFormat.prototype.format  (icu_localized_number_formatter) != nullptr Intl.DateTimeFormat get Intl.DateTimeFormat.prototype.format Intl.ListFormat        Intl.ListFormat.prototype.resolvedOptions       Intl.ListFormat.supportedLocalesOf Intl.Locale  Intl.Locale.prototype.maximize  Intl.Locale.prototype.minimize  Intl.Locale.prototype.calendars Intl.Locale.prototype.collations        Intl.Locale.prototype.hourCycles        Intl.Locale.prototype.numberingSystems  Intl.Locale.prototype.textInfo  Intl.Locale.prototype.timeZones Intl.Locale.prototype.weekInfo  Intl.RelativeTimeFormat.supportedLocalesOf      Intl.RelativeTimeFormat.prototype.format        Intl.RelativeTimeFormat.prototype.formatToParts Intl.Locale.prototype.language Intl.Locale.prototype.script Intl.Locale.prototype.region        Intl.Locale.prototype.baseName  Intl.Locale.prototype.calendar  Intl.Locale.prototype.caseFirst Intl.Locale.prototype.collation Intl.Locale.prototype.hourCycle Intl.Locale.prototype.numeric   Intl.Locale.prototype.numberingSystem   Intl.Locale.prototype.toString Intl.RelativeTimeFormat  Intl.RelativeTimeFormat.prototype.resolvedOptions       String.prototype.toLocaleLowerCase      String.prototype.toLocaleUpperCase Intl.PluralRules     Intl.PluralRules.prototype.resolvedOptions      Intl.PluralRules.prototype.select       Intl.PluralRules.prototype.selectRange  Intl.PluralRules.supportedLocalesOf Intl.Collator       Intl.Collator.prototype.resolvedOptions Intl.Collator.supportedLocalesOf        get Intl.Collator.prototype.compare (icu_collator) != nullptr   %SegmentIterator.prototype%.next Intl.Segmenter Intl.Segmenter.supportedLocalesOf       Intl.Segmenter.prototype.resolvedOptions        Intl.Segmenter.prototype.segment        %Segments.prototype%.containing %SegmentIsPrototype%[@@iterator] Intl.v8BreakIterator   Intl.v8BreakIterator.prototype.resolvedOptions  get Intl.v8BreakIterator.prototype.adoptText    get Intl.v8BreakIterator.prototype.first        get Intl.v8BreakIterator.prototype.next get Intl.v8BreakIterator.prototype.current      get Intl.v8BreakIterator.prototype.breakType    Intl.DateTimeFormat.prototype.formatRange       Intl.DateTimeFormat.prototype.formatRangeToParts        Intl.NumberFormat.prototype.formatRange Intl.NumberFormat.prototype.formatRangeToParts  Number.prototype.toExponential toExponential() Number.prototype.toFixed toFixed() digits        Number.prototype.toLocaleString Number.prototype.toPrecision         С          P               С          set Object.prototype.__proto__ Reflect.defineProperty   Reflect.getOwnPropertyDescriptor Reflect.ownKeys Reflect.set RegExp.prototype.toString has_pending_exception() Atomics.notify Atomics.wait      String.prototype.localeCompare      0Astatic_cast<unsigned>(value) <= 255             SharedStructType             8@get Temporal.PlainDate.prototype.calendar       get Temporal.PlainDate.prototype.year   get Temporal.PlainDate.prototype.month  get Temporal.PlainDate.prototype.monthCode      get Temporal.PlainDate.prototype.day    get Temporal.PlainDate.prototype.dayOfWeek      get Temporal.PlainDate.prototype.dayOfYear      get Temporal.PlainDate.prototype.weekOfYear     get Temporal.PlainDate.prototype.daysInWeek     get Temporal.PlainDate.prototype.daysInMonth    get Temporal.PlainDate.prototype.daysInYear     get Temporal.PlainDate.prototype.monthsInYear   get Temporal.PlainDate.prototype.inLeapYear     Temporal.PlainDate.prototype.withCalendar       Temporal.PlainDate.prototype.getISOFields       use Temporal.PlainDate.prototype.compare for comparison.        Temporal.PlainDate.prototype.valueOf    get Temporal.PlainTime.prototype.calendar       get Temporal.PlainTime.prototype.iso_hour       get Temporal.PlainTime.prototype.iso_minute     get Temporal.PlainTime.prototype.iso_second     get Temporal.PlainTime.prototype.iso_millisecond        get Temporal.PlainTime.prototype.iso_microsecond        get Temporal.PlainTime.prototype.iso_nanosecond Temporal.PlainTime.prototype.getISOFields       use Temporal.PlainTime.prototype.compare for comparison.        Temporal.PlainTime.prototype.valueOf    get Temporal.PlainDateTime.prototype.calendar   get Temporal.PlainDateTime.prototype.year       get Temporal.PlainDateTime.prototype.month      get Temporal.PlainDateTime.prototype.monthCode  get Temporal.PlainDateTime.prototype.day        get Temporal.PlainDateTime.prototype.dayOfWeek  get Temporal.PlainDateTime.prototype.dayOfYear  get Temporal.PlainDateTime.prototype.weekOfYear get Temporal.PlainDateTime.prototype.daysInWeek get Temporal.PlainDateTime.prototype.daysInMonth        get Temporal.PlainDateTime.prototype.daysInYear get Temporal.PlainDateTime.prototype.monthsInYear       get Temporal.PlainDateTime.prototype.inLeapYear Temporal.PlainDateTime.prototype.withCalendar   get Temporal.PlainDateTime.prototype.iso_hour   get Temporal.PlainDateTime.prototype.iso_minute get Temporal.PlainDateTime.prototype.iso_second get Temporal.PlainDateTime.prototype.iso_millisecond    get Temporal.PlainDateTime.prototype.iso_microsecond    get Temporal.PlainDateTime.prototype.iso_nanosecond     Temporal.PlainDateTime.prototype.getISOFields   use Temporal.PlainDateTime.prototype.compare for comparison.    Temporal.PlainDateTime.prototype.valueOf        get Temporal.PlainYearMonth.prototype.calendar  get Temporal.PlainYearMonth.prototype.year      get Temporal.PlainYearMonth.prototype.month     get Temporal.PlainYearMonth.prototype.monthCode get Temporal.PlainYearMonth.prototype.daysInYear        get Temporal.PlainYearMonth.prototype.daysInMonth       get Temporal.PlainYearMonth.prototype.monthsInYear      get Temporal.PlainYearMonth.prototype.inLeapYear        Temporal.PlainYearMonth.prototype.getISOFields  use Temporal.PlainYearMonth.prototype.compare for comparison.   Temporal.PlainYearMonth.prototype.valueOf       get Temporal.PlainMonthDay.prototype.calendar   get Temporal.PlainMonthDay.prototype.monthCode  get Temporal.PlainMonthDay.prototype.day        Temporal.PlainMonthDay.prototype.getISOFields   use Temporal.PlainMonthDay.prototype.compare for comparison.    Temporal.PlainMonthDay.prototype.valueOf        get Temporal.ZonedDateTime.prototype.calendar   get Temporal.ZonedDateTime.prototype.time_zone  get Temporal.ZonedDateTime.prototype.nanoseconds        get Temporal.ZonedDateTime.prototype.epochSeconds       get Temporal.ZonedDateTime.prototype.epochMilliseconds  get Temporal.ZonedDateTime.prototype.epochMicroseconds  get Temporal.ZonedDateTime.prototype.Hour       get Temporal.ZonedDateTime.prototype.Minute     get Temporal.ZonedDateTime.prototype.Second     get Temporal.ZonedDateTime.prototype.Millisecond        get Temporal.ZonedDateTime.prototype.Microsecond        get Temporal.ZonedDateTime.prototype.Nanosecond Temporal.ZonedDateTime.prototype.withCalendar   Temporal.ZonedDateTime.prototype.withTimeZone   Temporal.ZonedDateTime.prototype.toPlainYearMonth       Temporal.ZonedDateTime.prototype.toPlainMonthDay        Temporal.ZonedDateTime.prototype.getISOFields   use Temporal.ZonedDateTime.prototype.compare for comparison.    Temporal.ZonedDateTime.prototype.valueOf        get Temporal.Duration.prototype.years   get Temporal.Duration.prototype.months  get Temporal.Duration.prototype.weeks   get Temporal.Duration.prototype.days    get Temporal.Duration.prototype.hours   get Temporal.Duration.prototype.minutes get Temporal.Duration.prototype.seconds get Temporal.Duration.prototype.milliseconds    get Temporal.Duration.prototype.microseconds    get Temporal.Duration.prototype.nanoseconds     Temporal.Duration.prototype.sign        Temporal.Duration.prototype.blank       Temporal.Duration.prototype.negated     Temporal.Duration.prototype.abs use Temporal.Duration.prototype.compare for comparison. Temporal.Duration.prototype.valueOf     use Temporal.Instant.prototype.compare for comparison.  Temporal.Instant.prototype.valueOf      get Temporal.Instant.prototype.nanoseconds      get Temporal.Instant.prototype.epochSeconds     get Temporal.Instant.prototype.epochMilliseconds        get Temporal.Instant.prototype.epochMicroseconds        Temporal.Calendar.prototype.dateFromFields      Temporal.Calendar.prototype.daysInMonth Temporal.Calendar.prototype.daysInWeek  Temporal.Calendar.prototype.daysInYear  Temporal.Calendar.prototype.dayOfWeek   Temporal.Calendar.prototype.dayOfYear   Temporal.Calendar.prototype.inLeapYear  Temporal.Calendar.prototype.mergeFields Temporal.Calendar.prototype.monthsInYear        Temporal.Calendar.prototype.year        Temporal.Calendar.prototype.toString Temporal.Calendar.from     Temporal.TimeZone.prototype.toString Temporal.TimeZone.from     get Temporal.PlainDate.prototype.era    get Temporal.PlainDate.prototype.eraYear        get Temporal.PlainDateTime.prototype.era        get Temporal.PlainDateTime.prototype.eraYear    get Temporal.PlainYearMonth.prototype.era       get Temporal.PlainYearMonth.prototype.eraYear                                   get %TypedArray%.prototype.buffer       %TypedArray%.prototype.copyWithin %TypedArray%.prototype.fill   %TypedArray%.prototype.includes %TypedArray%.prototype.indexOf  %TypedArray%.prototype.lastIndexOf      %TypedArray%.prototype.reverse  FinalizationRegistry.prototype.unregister       x     x     x     @     @     @     @     @     @          
     
     
     
     
     
     
     
                                                  
          D     >     8     2     :                                                                                                      x     x     (     "           x     x     `                           r     r     r     r     r     ^     X                                         x     x     \     V     x     J     x     x     x                       x     x     x     x     x                                                                                               ^     X     R     L     F     @     0                    0     0     0          
               0     0     
     
     
     
     
     
     
     
                                             t     n     h     b     D     >     8     2                                        ,     &                                                                                                                                                                                                                                                                                           l     f                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ~                              x     r                                                                                     Z                                                       j     l          f     l          f     l          f     l          f     l     f                                                       2          2     ,          ,          4     .     (     "                                                                                
                         &     &     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     `     `     `     `     `     `     P     P     P     P     P     P     x     x     x     x     ~     ~     ~     ~                                                                                                                                            >     >     ,     &                    8     8                                                                                                                   n     h     x     x                                                       V          P                                                                                                                                                                                                                            x     x          x     x     x     x                                                                                                         z                                                                                                    x     x     x     x     x     x     x     x     x     x     x               x     x                         x     x                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                x                    r                         l                         f          `          Z                    T                    N     H     B     <     6     0                                                  *                              $                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ~     t                $     *                                                                                                                                                                                                                                                          T     Z     N     0     6     <     B     *                                                                                               F     j     v                                                                                                                   j          v                         R     ^     L     p     |                         p                                        |                                        X               d               @                                                                                                                                                                                                                                                                                                                                                                                            0     <     N          B     T          6     H                                        `                                   z                                                                 
     J     P     V     \     
                    .     4          "     (                         d                         n     t     :     @     d     v     |     p                    R                         z                              $                     F          L                                                       H           ~                                                                                                    J     \     b                                         D     P     b     h     f     :     .     4     l                                                                                                                                                                                                                                                                                                                                                                                                           r     %s Builtin, %s, %d
     (     (     (     r(     h(     W(     E(     3(     '(     (      (     '     '     '     '     '     r'               5  8  ;  @  >  1  [  R  CPP TFJ TFC TFS TFH BCH ASM DeoptimizationEntry_Eager DeoptimizationEntry_Lazy DeoptimizationEntry_Unused EphemeronKeyBarrierSaveFP EphemeronKeyBarrierIgnoreFP AdaptorWithBuiltinExitFrame CallFunction_ReceiverIsAny CallBoundFunction CallWrappedFunction Call_ReceiverIsAny Call_ReceiverIsAny_Baseline CallProxy CallVarargs CallWithSpread_Baseline CallWithSpread_WithFeedback CallFunctionForwardVarargs ConstructFunction ConstructBoundFunction ConstructedNonConstructable ConstructVarargs ConstructWithSpread_Baseline Construct_Baseline Construct_WithFeedback JSConstructStubGeneric JSBuiltinsConstructStub FastNewObject FastNewClosure ConstructProxy JSEntry JSConstructEntry JSRunMicrotasksEntry JSEntryTrampoline JSConstructEntryTrampoline ResumeGeneratorTrampoline StringFromCodePointAt StringGreaterThanOrEqual StringLessThanOrEqual OrderedHashTableHealIndex InterpreterEntryTrampoline InterpreterPushArgsThenCall InterpreterEnterAtBytecode InterpreterOnStackReplacement BaselineOutOfLinePrologue BaselineOnStackReplacement BaselineLeaveFrame CompileLazyDeoptimizedCode ContinueToCodeStubBuiltin ContinueToJavaScriptBuiltin CallApiCallback CallApiGetter HandleApiCallAsFunction HandleApiCallAsConstructor AllocateInYoungGeneration AllocateInOldGeneration CopyFastSmiOrObjectElements GrowFastDoubleElements GrowFastSmiOrObjectElements DebugBreakTrampoline ToNumber_Baseline ToNumeric_Baseline PlainPrimitiveToNumber BigIntToI64 BigIntToI32Pair I64ToBigInt I32PairToBigInt KeyedLoadIC_PolymorphicName KeyedStoreIC_Megamorphic DefineKeyedOwnIC_Megamorphic LoadGlobalIC_NoFeedback LoadIC_FunctionPrototype LoadIC_StringLength LoadIC_StringWrapperLength LoadIC_NoFeedback StoreIC_NoFeedback DefineNamedOwnIC_NoFeedback KeyedLoadIC_SloppyArguments LoadIndexedInterceptorIC StoreFastElementIC_Standard KeyedHasIC_PolymorphicName KeyedHasIC_SloppyArguments HasIndexedInterceptorIC RunMicrotasksTrampoline RunMicrotasks StrictPoisonPillThrower ReturnReceiver ArrayConstructorImpl ArrayNArgumentsConstructor ArrayIncludesSmiOrObject ArrayIncludesPackedDoubles ArrayIncludesHoleyDoubles ArrayIncludes ArrayIndexOfSmiOrObject ArrayIndexOfPackedDoubles ArrayIndexOfHoleyDoubles ArrayPrototypePop ArrayPrototypeGroupByToMap ArrayPrototypePush CloneFastJSArray CloneFastJSArrayFillingHoles ExtractFastJSArray ArrayIteratorPrototypeNext FlattenIntoArray FlatMapIntoArray ArrayPrototypeFlat ArrayPrototypeFlatMap ArrayBufferConstructor ArrayBufferPrototypeSlice ArrayBufferPrototypeResize BigIntPrototypeToLocaleString BigIntPrototypeToString BigIntPrototypeValueOf CallSitePrototypeGetFileName CallSitePrototypeGetFunction CallSitePrototypeGetPosition CallSitePrototypeGetThis CallSitePrototypeGetTypeName CallSitePrototypeIsAsync CallSitePrototypeIsEval CallSitePrototypeIsNative CallSitePrototypeIsPromiseAll CallSitePrototypeIsToplevel CallSitePrototypeToString DatePrototypeGetDate DatePrototypeGetDay DatePrototypeGetFullYear DatePrototypeGetHours DatePrototypeGetMilliseconds DatePrototypeGetMinutes DatePrototypeGetMonth DatePrototypeGetSeconds DatePrototypeGetTime DatePrototypeGetUTCDate DatePrototypeGetUTCDay DatePrototypeGetUTCFullYear DatePrototypeGetUTCHours DatePrototypeGetUTCMinutes DatePrototypeGetUTCMonth DatePrototypeGetUTCSeconds DatePrototypeValueOf DatePrototypeToPrimitive DatePrototypeSetFullYear DatePrototypeSetMilliseconds DatePrototypeSetMinutes DatePrototypeSetSeconds DatePrototypeSetUTCDate DatePrototypeSetUTCFullYear DatePrototypeSetUTCHours DatePrototypeSetUTCMinutes DatePrototypeSetUTCMonth DatePrototypeSetUTCSeconds DatePrototypeToDateString DatePrototypeToISOString DatePrototypeToUTCString DatePrototypeToTimeString ErrorCaptureStackTrace ErrorPrototypeToString FunctionPrototypeApply FunctionPrototypeCall FunctionPrototypeToString GeneratorFunctionConstructor AsyncFunctionConstructor SuspendGeneratorBaseline ResumeGeneratorBaseline GlobalDecodeURIComponent GlobalEncodeURIComponent GlobalIsFinite GlobalIsNaN LoadIC_Noninlined LoadICTrampoline_Megamorphic LoadSuperIC LoadSuperICBaseline KeyedLoadIC KeyedLoadIC_Megamorphic KeyedLoadICTrampoline KeyedLoadICBaseline StoreGlobalIC StoreGlobalICTrampoline StoreGlobalICBaseline DefineNamedOwnIC DefineNamedOwnICTrampoline DefineNamedOwnICBaseline KeyedStoreIC KeyedStoreICTrampoline KeyedStoreICBaseline DefineKeyedOwnIC DefineKeyedOwnICTrampoline DefineKeyedOwnICBaseline StoreInArrayLiteralIC StoreInArrayLiteralICBaseline LookupContextBaseline LoadGlobalIC LoadGlobalICInsideTypeof LoadGlobalICTrampoline LoadGlobalICBaseline LookupGlobalICBaseline CloneObjectIC CloneObjectICBaseline CloneObjectIC_Slow KeyedHasIC KeyedHasICBaseline KeyedHasIC_Megamorphic IterableToList IterableToFixedArray IterableToFixedArrayForWasm StringListFromIterable FindOrderedHashMapEntry MapPrototypeGet MapPrototypeEntries MapPrototypeGetSize MapPrototypeForEach MapPrototypeKeys MapPrototypeValues MapIteratorPrototypeNext MapIteratorToList NumberPrototypeToExponential NumberPrototypeToFixed NumberPrototypeToLocaleString NumberPrototypeToPrecision SameValueNumbersOnly Add_Baseline AddSmi_Baseline Subtract_Baseline SubtractSmi_Baseline Multiply_Baseline MultiplySmi_Baseline Divide_Baseline DivideSmi_Baseline Modulus_Baseline ModulusSmi_Baseline Exponentiate_Baseline ExponentiateSmi_Baseline BitwiseAnd_Baseline BitwiseAndSmi_Baseline BitwiseOr_Baseline BitwiseOrSmi_Baseline BitwiseXor_Baseline BitwiseXorSmi_Baseline ShiftLeft_Baseline ShiftLeftSmi_Baseline ShiftRight_Baseline ShiftRightSmi_Baseline ShiftRightLogical_Baseline ShiftRightLogicalSmi_Baseline Add_WithFeedback Subtract_WithFeedback Multiply_WithFeedback Divide_WithFeedback Modulus_WithFeedback Exponentiate_WithFeedback BitwiseAnd_WithFeedback BitwiseOr_WithFeedback BitwiseXor_WithFeedback ShiftLeft_WithFeedback ShiftRight_WithFeedback StrictEqual_Baseline LessThan_Baseline GreaterThan_Baseline LessThanOrEqual_Baseline GreaterThanOrEqual_Baseline StrictEqual_WithFeedback LessThan_WithFeedback GreaterThan_WithFeedback LessThanOrEqual_WithFeedback BitwiseNot_Baseline Decrement_Baseline Increment_Baseline Negate_Baseline BitwiseNot_WithFeedback Decrement_WithFeedback Increment_WithFeedback Negate_WithFeedback ObjectAssign ObjectDefineProperties ObjectGetOwnPropertyNames ObjectGetOwnPropertySymbols ObjectHasOwn ObjectIs ObjectPrototypeHasOwnProperty ObjectPrototypeIsPrototypeOf ObjectPrototypeGetProto ObjectPrototypeSetProto ObjectToString InstanceOf_WithFeedback InstanceOf_Baseline ForInFilter ReflectApply ReflectConstruct RegExpLeftContextGetter RegExpPrototypeCompile RegExpPrototypeToString RegExpRightContextGetter RegExpExecAtom RegExpExecInternal RegExpInterpreterTrampoline RegExpExperimentalTrampoline SetPrototypeEntries SetPrototypeGetSize SetPrototypeForEach SetPrototypeValues SetIteratorPrototypeNext SetOrSetIteratorToList ShadowRealmConstructor ShadowRealmGetWrappedValue ShadowRealmPrototypeEvaluate AtomicsLoad AtomicsStore AtomicsCompareExchange StringFromCharCode StringPrototypeLastIndexOf StringPrototypeMatchAll StringPrototypeLocaleCompare StringPrototypeReplace StringPrototypeSplit TypedArrayBaseConstructor TypedArrayConstructor TypedArrayPrototypeBuffer TypedArrayPrototypeByteLength TypedArrayPrototypeByteOffset TypedArrayPrototypeLength TypedArrayPrototypeCopyWithin TypedArrayPrototypeFill TypedArrayPrototypeIncludes TypedArrayPrototypeIndexOf TypedArrayPrototypeReverse TypedArrayPrototypeMap GenericJSToWasmWrapper WasmReturnPromiseOnSuspend WasmSuspend WasmResume WasmOnStackReplace WasmFloat32ToNumber WasmFloat64ToNumber WasmI32AtomicWait32 WasmI64AtomicWait32 JSToWasmLazyDeoptContinuation WeakMapConstructor WeakMapLookupHashIndex WeakMapGet WeakMapPrototypeHas WeakMapPrototypeSet WeakMapPrototypeDelete WeakSetConstructor WeakSetPrototypeHas WeakSetPrototypeAdd WeakSetPrototypeDelete SharedStructTypeConstructor SharedStructConstructor AsyncGeneratorReturn AsyncGeneratorResumeNext AsyncGeneratorPrototypeNext AsyncGeneratorPrototypeReturn AsyncGeneratorPrototypeThrow AsyncIteratorValueUnwrap DirectCEntry StringAdd_CheckNone SubString GetPropertyWithReceiver MemCopyUint8Uint8 MemMove IsTraceCategoryEnabled AsyncModuleEvaluate CallAsyncModuleFulfilled CallAsyncModuleRejected TemporalNowPlainDateTime TemporalNowPlainDateTimeISO TemporalNowZonedDateTime TemporalNowZonedDateTimeISO TemporalNowPlainDateISO TemporalNowPlainTimeISO TemporalPlainDateConstructor TemporalPlainDateCompare TemporalPlainDatePrototypeDay TemporalPlainDatePrototypeAdd TemporalPlainTimeConstructor TemporalPlainTimeCompare TemporalPlainTimePrototypeAdd TemporalPlainDateTimeFrom TemporalPlainDateTimeCompare TemporalZonedDateTimeFrom TemporalZonedDateTimeCompare TemporalDurationConstructor TemporalDurationCompare TemporalDurationPrototypeDays TemporalDurationPrototypeSign TemporalDurationPrototypeWith TemporalDurationPrototypeAbs TemporalDurationPrototypeAdd TemporalInstantConstructor TemporalInstantCompare TemporalInstantPrototypeAdd TemporalInstantPrototypeUntil TemporalInstantPrototypeSince TemporalInstantPrototypeRound TemporalPlainYearMonthFrom TemporalPlainYearMonthCompare TemporalPlainMonthDayFrom TemporalTimeZoneConstructor TemporalTimeZonePrototypeId TemporalCalendarConstructor TemporalCalendarPrototypeId TemporalCalendarPrototypeYear TemporalCalendarPrototypeDay StringFixedArrayFromIterable AggregateErrorConstructor ArrayPrototypeConcat ArrayEveryLoopContinuation ArrayEvery ArrayFilterLoopContinuation ArrayFilter ArrayFindLoopContinuation ArrayFindLastLoopContinuation ArrayPrototypeFindLastIndex ArrayForEachLoopContinuation ArrayForEach ConvertToLocaleString JoinStackPush JoinStackPop ArrayPrototypeToLocaleString ArrayPrototypeToString TypedArrayPrototypeJoin ArrayPrototypeLastIndexOf ArrayMapLoopContinuation ArrayMap ArrayReduceRight ArrayReduceLoopContinuation ArrayReduce ArrayPrototypeShift ArraySomeLoopContinuation ArraySome ArrayPrototypeSplice ArrayPrototypeUnshift ArrayBufferIsView ToInteger FastCreateDataProperty CheckSameObject BooleanConstructor BooleanPrototypeToString BooleanPrototypeValueOf BigIntAddNoThrow BigIntSubtractNoThrow BigIntUnaryMinus StringPrototypeToString StringPrototypeValueOf StringToList StringPrototypeCharAt StringPrototypeCharCodeAt StringPrototypeCodePointAt StringPrototypeConcat StringConstructor StringAddConvertLeft StringAddConvertRight StringCharAt FastNewClosureBaseline FastNewFunctionContextEval CreateShallowArrayLiteral CreateEmptyArrayLiteral CreateShallowObjectLiteral ObjectConstructor NumberConstructor GenericLazyDeoptContinuation NonNumberToNumber NonNumberToNumeric NumberToString ToBooleanForBaselineJump OrdinaryToPrimitive_Number OrdinaryToPrimitive_String FastConsoleAssert DataViewPrototypeGetBuffer DataViewPrototypeGetUint8 DataViewPrototypeGetInt8 DataViewPrototypeGetUint16 DataViewPrototypeGetInt16 DataViewPrototypeGetUint32 DataViewPrototypeGetInt32 DataViewPrototypeGetFloat32 DataViewPrototypeGetFloat64 DataViewPrototypeGetBigUint64 DataViewPrototypeGetBigInt64 DataViewPrototypeSetUint8 DataViewPrototypeSetInt8 DataViewPrototypeSetUint16 DataViewPrototypeSetInt16 DataViewPrototypeSetUint32 DataViewPrototypeSetInt32 DataViewPrototypeSetFloat32 DataViewPrototypeSetFloat64 DataViewPrototypeSetBigUint64 DataViewPrototypeSetBigInt64 FinalizationRegistryRegister FunctionPrototypeHasInstance FastFunctionPrototypeBind GetImportMetaObjectBaseline GetIteratorWithFeedback GetIteratorBaseline CallIteratorWithFeedback MathAbs MathCeil MathFloor MathRound MathTrunc MathPow MathMax MathMin MathAcos MathAcosh MathAsin MathAsinh MathAtan MathAtan2 MathAtanh MathCbrt MathClz32 MathCos MathCosh MathExp MathExpm1 MathFround MathImul MathLog MathLog1p MathLog10 MathLog2 MathSin MathSign MathSinh MathSqrt MathTan MathTanh MathHypot MathRandom NumberPrototypeToString NumberIsFinite NumberIsInteger NumberIsNaN NumberIsSafeInteger NumberPrototypeValueOf NumberParseFloat NumberParseInt ObjectFromEntries CreateObjectWithoutProperties ObjectPreventExtensions ObjectGetPrototypeOf ObjectSetPrototypeOf ObjectPrototypeToString ObjectPrototypeValueOf ObjectPrototypeToLocaleString NewPromiseCapability PromiseReject PromiseAllSettled PromiseAny PromisePrototypeCatch PromiseValueThunkFinally PromiseThrowerFinally PromiseCatchFinally PromiseThenFinally PromisePrototypeFinally PromiseRace PromiseFulfillReactionJob PromiseRejectReactionJob PromiseResolveTrampoline PromisePrototypeThen PromiseResolveThenableJob ProxyConstructor ProxyDeleteProperty ProxyGetProperty ProxyGetPrototypeOf ProxyHasProperty ProxyIsExtensible ProxyPreventExtensions ProxyRevocable ProxyRevoke ProxySetProperty ProxySetPrototypeOf ReflectIsExtensible ReflectPreventExtensions ReflectGetPrototypeOf ReflectSetPrototypeOf ReflectGet ReflectDeleteProperty ReflectHas RegExpPrototypeExecSlow RegExpPrototypeExec RegExpPrototypeMatchAll RegExpMatchFast RegExpPrototypeMatch RegExpReplace RegExpPrototypeReplace RegExpSearchFast RegExpPrototypeSearch RegExpPrototypeSourceGetter RegExpPrototypeSplit RegExpPrototypeTest RegExpPrototypeTestFast RegExpPrototypeGlobalGetter RegExpPrototypeLinearGetter RegExpPrototypeDotAllGetter RegExpPrototypeStickyGetter RegExpPrototypeUnicodeGetter RegExpPrototypeFlagsGetter StringPrototypeAt StringPrototypeEndsWith CreateHTML StringPrototypeAnchor StringPrototypeBig StringPrototypeBlink StringPrototypeBold StringPrototypeFontcolor StringPrototypeFontsize StringPrototypeFixed StringPrototypeItalics StringPrototypeLink StringPrototypeSmall StringPrototypeStrike StringPrototypeSub StringPrototypeSup StringPrototypeIncludes StringPrototypeIndexOf StringPrototypeIterator StringIteratorPrototypeNext StringPrototypeMatch StringPrototypeSearch StringPrototypePadStart StringPrototypePadEnd StringRepeat StringPrototypeRepeat StringPrototypeReplaceAll StringPrototypeSlice StringPrototypeStartsWith StringPrototypeSubstr StringPrototypeSubstring StringPrototypeTrim StringPrototypeTrimStart StringPrototypeTrimEnd SymbolPrototypeToPrimitive SymbolPrototypeToString SymbolPrototypeValueOf TypedArrayPrototypeAt TypedArrayPrototypeEvery TypedArrayPrototypeEntries TypedArrayPrototypeFilter TypedArrayPrototypeFind TypedArrayPrototypeFindIndex TypedArrayPrototypeFindLast TypedArrayPrototypeForEach TypedArrayFrom TypedArrayPrototypeKeys TypedArrayOf TypedArrayPrototypeReduce TypedArrayPrototypeSet TypedArrayPrototypeSlice TypedArrayPrototypeSome TypedArrayMergeSort TypedArrayPrototypeSort TypedArrayPrototypeSubArray TypedArrayPrototypeValues WeakRefConstructor WeakRefDeref NewSloppyArgumentsElements NewStrictArgumentsElements NewRestArgumentsElements FastNewSloppyArguments FastNewStrictArguments FastNewRestArguments StringSlowFlatten StringIndexOf TestTurbofanType CheckTurbofanType GenericBuiltinTest_JSAny_0 TestHelperPlus1 TestHelperPlus2 NewSmiBox ReturnTwoValues Load_FastSmiElements_0 Load_FastObjectElements_0 Load_FastDoubleElements_0 Store_FastSmiElements_0 Store_FastObjectElements_0 Store_FastDoubleElements_0 Delete_FastSmiElements_0 Delete_FastObjectElements_0 Delete_FastDoubleElements_0 SortCompareDefault SortCompareUserFn MergeAt GallopLeft GallopRight ArrayTimSort StringFastLocaleCompare WasmInt32ToHeapNumber WasmFuncRefToJS WasmTaggedNonSmiToInt32 WasmTaggedToFloat64 WasmTableGet WasmTableSet WasmAllocateFixedArray WasmRethrow WasmRethrowExplicitContext WasmAllocateJSArray WasmAllocateStructWithRtt WasmAllocateArray_InitZero WasmAllocateArray_InitNull WasmArrayInitFromData WasmArrayCopyWithChecks WasmAllocateObjectWrapper WasmSubtypeCheck WasmInt32ToNumber WasmUint32ToNumber UintPtr53ToNumber WasmI32AtomicWait64 WasmI64AtomicWait64 CallRefIC WasmGetOwnProperty WasmTrap ThrowWasmTrapUnreachable ThrowWasmTrapMemOutOfBounds ThrowWasmTrapUnalignedAccess ThrowWasmTrapDivByZero ThrowWasmTrapRemByZero ThrowWasmTrapFuncSigMismatch ThrowWasmTrapTableOutOfBounds ThrowWasmTrapRethrowNull ThrowWasmTrapNullDereference ThrowWasmTrapIllegalCast ThrowWasmTrapArrayOutOfBounds ThrowWasmTrapArrayTooLarge GenericBuiltinTest_Smi_0 CollatorInternalCompare CollatorPrototypeCompare CollatorSupportedLocalesOf DatePrototypeToLocaleString DateTimeFormatConstructor DateTimeFormatInternalFormat DateTimeFormatPrototypeFormat DisplayNamesConstructor DisplayNamesPrototypeOf IntlGetCanonicalLocales ListFormatPrototypeFormat ListFormatSupportedLocalesOf LocalePrototypeBaseName LocalePrototypeCalendar LocalePrototypeCalendars LocalePrototypeCaseFirst LocalePrototypeCollation LocalePrototypeCollations LocalePrototypeHourCycle LocalePrototypeHourCycles LocalePrototypeLanguage LocalePrototypeMaximize LocalePrototypeMinimize LocalePrototypeNumeric LocalePrototypeTextInfo LocalePrototypeTimeZones LocalePrototypeToString LocalePrototypeWeekInfo NumberFormatConstructor PluralRulesConstructor PluralRulesPrototypeSelect PluralRulesSupportedLocalesOf RelativeTimeFormatConstructor SegmenterPrototypeSegment SegmenterSupportedLocalesOf SegmentIteratorPrototypeNext SegmentsPrototypeContaining SegmentsPrototypeIterator StringPrototypeNormalizeIntl StringToLowerCaseIntl TemporalCalendarPrototypeEra TemporalPlainDatePrototypeEra V8BreakIteratorConstructor V8BreakIteratorInternalFirst V8BreakIteratorInternalNext V8BreakIteratorPrototypeFirst V8BreakIteratorPrototypeNext DebugBreakWideHandler DebugBreakExtraWideHandler DebugBreak0Handler DebugBreak1Handler DebugBreak2Handler DebugBreak3Handler DebugBreak4Handler DebugBreak5Handler DebugBreak6Handler LdarHandler LdaZeroHandler LdaSmiHandler LdaUndefinedHandler LdaNullHandler LdaTheHoleHandler LdaTrueHandler LdaFalseHandler LdaConstantHandler LdaContextSlotHandler LdaCurrentContextSlotHandler MovHandler PushContextHandler PopContextHandler TestReferenceEqualHandler TestUndetectableHandler TestNullHandler TestUndefinedHandler TestTypeOfHandler LdaGlobalHandler LdaGlobalInsideTypeofHandler StaGlobalHandler StaContextSlotHandler StaCurrentContextSlotHandler LdaLookupSlotHandler LdaLookupContextSlotHandler LdaLookupGlobalSlotHandler StaLookupSlotHandler GetNamedPropertyHandler GetKeyedPropertyHandler LdaModuleVariableHandler StaModuleVariableHandler SetNamedPropertyHandler DefineNamedOwnPropertyHandler SetKeyedPropertyHandler DefineKeyedOwnPropertyHandler StaInArrayLiteralHandler CollectTypeProfileHandler AddHandler SubHandler MulHandler DivHandler ModHandler ExpHandler BitwiseOrHandler BitwiseXorHandler BitwiseAndHandler ShiftLeftHandler ShiftRightHandler ShiftRightLogicalHandler AddSmiHandler SubSmiHandler MulSmiHandler DivSmiHandler ModSmiHandler ExpSmiHandler BitwiseOrSmiHandler BitwiseXorSmiHandler BitwiseAndSmiHandler ShiftLeftSmiHandler ShiftRightSmiHandler ShiftRightLogicalSmiHandler IncHandler DecHandler NegateHandler BitwiseNotHandler ToBooleanLogicalNotHandler DeletePropertyStrictHandler DeletePropertySloppyHandler GetSuperConstructorHandler CallAnyReceiverHandler CallPropertyHandler CallProperty0Handler CallProperty1Handler CallProperty2Handler CallUndefinedReceiverHandler CallUndefinedReceiver0Handler CallUndefinedReceiver1Handler CallUndefinedReceiver2Handler CallWithSpreadHandler CallRuntimeHandler CallRuntimeForPairHandler CallJSRuntimeHandler InvokeIntrinsicHandler ConstructHandler ConstructWithSpreadHandler TestEqualHandler TestEqualStrictHandler TestLessThanHandler TestGreaterThanHandler TestLessThanOrEqualHandler TestGreaterThanOrEqualHandler TestInstanceOfHandler TestInHandler ToNameHandler ToNumberHandler ToNumericHandler ToObjectHandler ToStringHandler CreateRegExpLiteralHandler CreateArrayLiteralHandler CreateObjectLiteralHandler CloneObjectHandler GetTemplateObjectHandler CreateClosureHandler CreateBlockContextHandler CreateCatchContextHandler CreateFunctionContextHandler CreateEvalContextHandler CreateWithContextHandler CreateMappedArgumentsHandler CreateRestParameterHandler JumpLoopHandler JumpHandler JumpConstantHandler JumpIfNullConstantHandler JumpIfNotNullConstantHandler JumpIfTrueConstantHandler JumpIfFalseConstantHandler JumpIfToBooleanTrueHandler JumpIfToBooleanFalseHandler JumpIfTrueHandler JumpIfFalseHandler JumpIfNullHandler JumpIfNotNullHandler JumpIfUndefinedHandler JumpIfNotUndefinedHandler JumpIfUndefinedOrNullHandler JumpIfJSReceiverHandler SwitchOnSmiNoFeedbackHandler ForInEnumerateHandler ForInPrepareHandler ForInContinueHandler ForInNextHandler ForInStepHandler SetPendingMessageHandler ReThrowHandler ReturnHandler SwitchOnGeneratorStateHandler SuspendGeneratorHandler ResumeGeneratorHandler GetIteratorHandler DebuggerHandler IncBlockCounterHandler AbortHandler ShortStarHandler IllegalHandler DebugBreak1WideHandler DebugBreak2WideHandler DebugBreak3WideHandler DebugBreak4WideHandler DebugBreak5WideHandler DebugBreak6WideHandler LdarWideHandler LdaSmiWideHandler LdaConstantWideHandler LdaContextSlotWideHandler StarWideHandler MovWideHandler PushContextWideHandler PopContextWideHandler TestReferenceEqualWideHandler LdaGlobalWideHandler StaGlobalWideHandler StaContextSlotWideHandler LdaLookupSlotWideHandler StaLookupSlotWideHandler GetNamedPropertyWideHandler GetKeyedPropertyWideHandler LdaModuleVariableWideHandler StaModuleVariableWideHandler SetNamedPropertyWideHandler SetKeyedPropertyWideHandler StaInArrayLiteralWideHandler CollectTypeProfileWideHandler AddWideHandler SubWideHandler MulWideHandler DivWideHandler ModWideHandler ExpWideHandler BitwiseOrWideHandler BitwiseXorWideHandler BitwiseAndWideHandler ShiftLeftWideHandler ShiftRightWideHandler ShiftRightLogicalWideHandler AddSmiWideHandler SubSmiWideHandler MulSmiWideHandler DivSmiWideHandler ModSmiWideHandler ExpSmiWideHandler BitwiseOrSmiWideHandler BitwiseXorSmiWideHandler BitwiseAndSmiWideHandler ShiftLeftSmiWideHandler ShiftRightSmiWideHandler IncWideHandler DecWideHandler NegateWideHandler BitwiseNotWideHandler CallAnyReceiverWideHandler CallPropertyWideHandler CallProperty0WideHandler CallProperty1WideHandler CallProperty2WideHandler CallWithSpreadWideHandler CallRuntimeWideHandler CallRuntimeForPairWideHandler CallJSRuntimeWideHandler InvokeIntrinsicWideHandler ConstructWideHandler TestEqualWideHandler TestEqualStrictWideHandler TestLessThanWideHandler TestGreaterThanWideHandler TestInstanceOfWideHandler TestInWideHandler ToNameWideHandler ToNumberWideHandler ToNumericWideHandler ToObjectWideHandler CreateArrayLiteralWideHandler CloneObjectWideHandler GetTemplateObjectWideHandler CreateClosureWideHandler CreateBlockContextWideHandler CreateCatchContextWideHandler CreateEvalContextWideHandler CreateWithContextWideHandler JumpLoopWideHandler JumpWideHandler JumpConstantWideHandler JumpIfNullConstantWideHandler JumpIfTrueConstantWideHandler JumpIfTrueWideHandler JumpIfFalseWideHandler JumpIfNullWideHandler JumpIfNotNullWideHandler JumpIfUndefinedWideHandler JumpIfNotUndefinedWideHandler JumpIfJSReceiverWideHandler ForInEnumerateWideHandler ForInPrepareWideHandler ForInContinueWideHandler ForInNextWideHandler ForInStepWideHandler SuspendGeneratorWideHandler ResumeGeneratorWideHandler GetIteratorWideHandler IncBlockCounterWideHandler AbortWideHandler DebugBreak1ExtraWideHandler DebugBreak2ExtraWideHandler DebugBreak3ExtraWideHandler DebugBreak4ExtraWideHandler DebugBreak5ExtraWideHandler DebugBreak6ExtraWideHandler LdarExtraWideHandler LdaSmiExtraWideHandler LdaConstantExtraWideHandler StarExtraWideHandler MovExtraWideHandler PushContextExtraWideHandler PopContextExtraWideHandler LdaGlobalExtraWideHandler StaGlobalExtraWideHandler LdaLookupSlotExtraWideHandler StaLookupSlotExtraWideHandler AddExtraWideHandler SubExtraWideHandler MulExtraWideHandler DivExtraWideHandler ModExtraWideHandler ExpExtraWideHandler BitwiseOrExtraWideHandler BitwiseXorExtraWideHandler BitwiseAndExtraWideHandler ShiftLeftExtraWideHandler ShiftRightExtraWideHandler AddSmiExtraWideHandler SubSmiExtraWideHandler MulSmiExtraWideHandler DivSmiExtraWideHandler ModSmiExtraWideHandler ExpSmiExtraWideHandler BitwiseOrSmiExtraWideHandler BitwiseXorSmiExtraWideHandler BitwiseAndSmiExtraWideHandler ShiftLeftSmiExtraWideHandler ShiftRightSmiExtraWideHandler IncExtraWideHandler DecExtraWideHandler NegateExtraWideHandler BitwiseNotExtraWideHandler CallPropertyExtraWideHandler CallProperty0ExtraWideHandler CallProperty1ExtraWideHandler CallProperty2ExtraWideHandler CallRuntimeExtraWideHandler CallJSRuntimeExtraWideHandler ConstructExtraWideHandler TestEqualExtraWideHandler TestLessThanExtraWideHandler TestInExtraWideHandler ToNameExtraWideHandler ToNumberExtraWideHandler ToNumericExtraWideHandler ToObjectExtraWideHandler CloneObjectExtraWideHandler CreateClosureExtraWideHandler JumpLoopExtraWideHandler JumpExtraWideHandler JumpConstantExtraWideHandler JumpIfTrueExtraWideHandler JumpIfFalseExtraWideHandler JumpIfNullExtraWideHandler JumpIfNotNullExtraWideHandler ForInPrepareExtraWideHandler ForInContinueExtraWideHandler ForInNextExtraWideHandler ForInStepExtraWideHandler GetIteratorExtraWideHandler AbortExtraWideHandler                       x~    x~    x~    x~    x~    x~    x~    RecordWriteEmitRememberedSetSaveFP      RecordWriteOmitRememberedSetSaveFP      RecordWriteEmitRememberedSetIgnoreFP    RecordWriteOmitRememberedSetIgnoreFP    CallFunction_ReceiverIsNullOrUndefined  CallFunction_ReceiverIsNotNullOrUndefined       Call_ReceiverIsNullOrUndefined  Call_ReceiverIsNotNullOrUndefined       Call_ReceiverIsNullOrUndefined_Baseline_Compact Call_ReceiverIsNullOrUndefined_Baseline Call_ReceiverIsNotNullOrUndefined_Baseline_Compact      Call_ReceiverIsNotNullOrUndefined_Baseline      Call_ReceiverIsAny_Baseline_Compact     Call_ReceiverIsNullOrUndefined_WithFeedback     Call_ReceiverIsNotNullOrUndefined_WithFeedback  Call_ReceiverIsAny_WithFeedback CallWithArrayLike_WithFeedback  CallFunctionTemplate_CheckAccess        CallFunctionTemplate_CheckCompatibleReceiver    CallFunctionTemplate_CheckAccessAndCompatibleReceiver   ConstructWithSpread_WithFeedback        ConstructWithArrayLike_WithFeedback     ConstructFunctionForwardVarargs InterpreterPushUndefinedAndArgsThenCall InterpreterPushArgsThenCallWithFinalSpread      InterpreterPushArgsThenConstruct        InterpreterPushArgsThenConstructArrayFunction   InterpreterPushArgsThenConstructWithFinalSpread InterpreterEnterAtNextBytecode  BaselineOrInterpreterEnterAtBytecode    BaselineOrInterpreterEnterAtNextBytecode        InterpreterOnStackReplacement_ToBaseline        ContinueToCodeStubBuiltinWithResult     ContinueToJavaScriptBuiltinWithResult   AllocateRegularInYoungGeneration        AllocateRegularInOldGeneration  ToBooleanLazyDeoptContinuation  KeyedStoreIC_SloppyArguments_Standard   KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW  KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB      KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW      StoreFastElementIC_GrowNoTransitionHandleCOW    StoreFastElementIC_NoTransitionIgnoreOOB        StoreFastElementIC_NoTransitionHandleCOW        ElementsTransitionAndStore_Standard     ElementsTransitionAndStore_GrowNoTransitionHandleCOW    ElementsTransitionAndStore_NoTransitionIgnoreOOB        ElementsTransitionAndStore_NoTransitionHandleCOW        CopyDataPropertiesWithExcludedPropertiesOnStack CopyDataPropertiesWithExcludedProperties        ArrayNoArgumentConstructor_PackedSmi_DontOverride       ArrayNoArgumentConstructor_HoleySmi_DontOverride        ArrayNoArgumentConstructor_PackedSmi_DisableAllocationSites     ArrayNoArgumentConstructor_HoleySmi_DisableAllocationSites      ArrayNoArgumentConstructor_Packed_DisableAllocationSites        ArrayNoArgumentConstructor_Holey_DisableAllocationSites ArrayNoArgumentConstructor_PackedDouble_DisableAllocationSites  ArrayNoArgumentConstructor_HoleyDouble_DisableAllocationSites   ArraySingleArgumentConstructor_PackedSmi_DontOverride   ArraySingleArgumentConstructor_HoleySmi_DontOverride    ArraySingleArgumentConstructor_PackedSmi_DisableAllocationSites ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites  ArraySingleArgumentConstructor_Packed_DisableAllocationSites    ArraySingleArgumentConstructor_Holey_DisableAllocationSites     ArraySingleArgumentConstructor_PackedDouble_DisableAllocationSites      ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites       AsyncFunctionLazyDeoptContinuation      AsyncFunctionAwaitRejectClosure AsyncFunctionAwaitResolveClosure        DatePrototypeGetTimezoneOffset  DatePrototypeGetUTCMilliseconds GetIteratorWithFeedbackLazyDeoptContinuation    KeyedLoadICTrampoline_Megamorphic       LookupContextInsideTypeofBaseline       LoadGlobalICInsideTypeofTrampoline      LoadGlobalICInsideTypeofBaseline        LookupGlobalICInsideTypeofBaseline      IterableToListWithSymbolLookup  IterableToFixedArrayWithSymbolLookupSlow        IterableToListMayPreserveHoles  ShiftRightLogical_WithFeedback  GreaterThanOrEqual_WithFeedback ObjectGetOwnPropertyDescriptor  TypedArrayPrototypeToStringTag  AsyncGeneratorAwaitResolveClosure       AsyncGeneratorAwaitRejectClosure        AsyncGeneratorYieldResolveClosure       AsyncGeneratorReturnClosedResolveClosure        AsyncGeneratorReturnClosedRejectClosure AsyncGeneratorReturnResolveClosure      AsyncFromSyncIteratorPrototypeNext      AsyncFromSyncIteratorPrototypeThrow     AsyncFromSyncIteratorPrototypeReturn    CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit   CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit      CEntry_Return1_SaveFPRegs_ArgvOnStack_NoBuiltinExit     CEntry_Return1_SaveFPRegs_ArgvOnStack_BuiltinExit       CEntry_Return2_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit CEntry_Return2_DontSaveFPRegs_ArgvOnStack_BuiltinExit   CEntry_Return2_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit      CEntry_Return2_SaveFPRegs_ArgvOnStack_NoBuiltinExit     CEntry_Return2_SaveFPRegs_ArgvOnStack_BuiltinExit       TemporalInstantFixedArrayFromIterable   ArrayEveryLoopEagerDeoptContinuation    ArrayEveryLoopLazyDeoptContinuation     ArrayFilterLoopEagerDeoptContinuation   ArrayFilterLoopLazyDeoptContinuation    ArrayFindLoopEagerDeoptContinuation     ArrayFindLoopLazyDeoptContinuation      ArrayFindLoopAfterCallbackLazyDeoptContinuation ArrayFindIndexLoopEagerDeoptContinuation        ArrayFindIndexLoopLazyDeoptContinuation ArrayFindIndexLoopAfterCallbackLazyDeoptContinuation    ArrayFindIndexLoopContinuation  ArrayFindLastIndexLoopContinuation      ArrayForEachLoopEagerDeoptContinuation  ArrayForEachLoopLazyDeoptContinuation   LoadJoinElement_DictionaryElements_0    LoadJoinElement_FastSmiOrObjectElements_0       LoadJoinElement_FastDoubleElements_0    TypedArrayPrototypeToLocaleString       ArrayMapPreLoopLazyDeoptContinuation    ArrayMapLoopEagerDeoptContinuation      ArrayMapLoopLazyDeoptContinuation       ArrayReduceRightPreLoopEagerDeoptContinuation   ArrayReduceRightLoopEagerDeoptContinuation      ArrayReduceRightLoopLazyDeoptContinuation       ArrayReduceRightLoopContinuation        ArrayReducePreLoopEagerDeoptContinuation        ArrayReduceLoopEagerDeoptContinuation   ArrayReduceLoopLazyDeoptContinuation    ArraySomeLoopEagerDeoptContinuation     ArraySomeLoopLazyDeoptContinuation      ArrayBufferPrototypeGetByteLength       ArrayBufferPrototypeGetMaxByteLength    ArrayBufferPrototypeGetResizable        SharedArrayBufferPrototypeGetMaxByteLength      SharedArrayBufferPrototypeGetGrowable   FastNewFunctionContextFunction  NonPrimitiveToPrimitive_Default NonPrimitiveToPrimitive_Number  NonPrimitiveToPrimitive_String  DataViewPrototypeGetByteLength  DataViewPrototypeGetByteOffset  FinalizationRegistryConstructor FinalizationRegistryPrototypeCleanupSome        CreateAsyncFromSyncIteratorBaseline     PromiseCapabilityDefaultReject  PromiseCapabilityDefaultResolve PromiseGetCapabilitiesExecutor  PromiseConstructorLazyDeoptContinuation PromiseAllResolveElementClosure PromiseAllSettledResolveElementClosure  PromiseAllSettledRejectElementClosure   PromiseAnyRejectElementClosure  RegExpStringIteratorPrototypeNext       RegExpPrototypeIgnoreCaseGetter RegExpPrototypeMultilineGetter  RegExpPrototypeHasIndicesGetter SymbolPrototypeDescriptionGetter        TypedArrayPrototypeFindLastIndex        TypedArrayPrototypeReduceRight  CanUseSameAccessor_GenericElementsAccessor_0    WasmAllocateArray_Uninitialized ThrowWasmTrapDivUnrepresentable ThrowWasmTrapFloatUnrepresentable       ThrowWasmTrapDataSegmentOutOfBounds     ThrowWasmTrapElemSegmentDropped LoadJoinElement_GenericElementsAccessor_0       LoadJoinTypedElement_Int32Elements_0    LoadJoinTypedElement_Float32Elements_0  LoadJoinTypedElement_Float64Elements_0  LoadJoinTypedElement_Uint8ClampedElements_0     LoadJoinTypedElement_BigUint64Elements_0        LoadJoinTypedElement_BigInt64Elements_0 LoadJoinTypedElement_Uint8Elements_0    LoadJoinTypedElement_Int8Elements_0     LoadJoinTypedElement_Uint16Elements_0   LoadJoinTypedElement_Int16Elements_0    LoadJoinTypedElement_Uint32Elements_0   CanUseSameAccessor_FastDoubleElements_0 CanUseSameAccessor_FastSmiElements_0    CanUseSameAccessor_FastObjectElements_0 Load_GenericElementsAccessor_0  Store_GenericElementsAccessor_0 Delete_GenericElementsAccessor_0        LoadTypedElement_Int32Elements_0        StoreTypedElementNumeric_Int32Elements_0        StoreTypedElementJSAny_Int32Elements_0  LoadTypedElement_Float32Elements_0      StoreTypedElementNumeric_Float32Elements_0      StoreTypedElementJSAny_Float32Elements_0        LoadTypedElement_Float64Elements_0      StoreTypedElementNumeric_Float64Elements_0      StoreTypedElementJSAny_Float64Elements_0        LoadTypedElement_Uint8ClampedElements_0 StoreTypedElementNumeric_Uint8ClampedElements_0 StoreTypedElementJSAny_Uint8ClampedElements_0   LoadTypedElement_BigUint64Elements_0    StoreTypedElementNumeric_BigUint64Elements_0    StoreTypedElementJSAny_BigUint64Elements_0      LoadTypedElement_BigInt64Elements_0     StoreTypedElementNumeric_BigInt64Elements_0     StoreTypedElementJSAny_BigInt64Elements_0       LoadTypedElement_Uint8Elements_0        StoreTypedElementNumeric_Uint8Elements_0        StoreTypedElementJSAny_Uint8Elements_0  LoadTypedElement_Int8Elements_0 StoreTypedElementNumeric_Int8Elements_0 StoreTypedElementJSAny_Int8Elements_0   LoadTypedElement_Uint16Elements_0       StoreTypedElementNumeric_Uint16Elements_0       StoreTypedElementJSAny_Uint16Elements_0 LoadTypedElement_Int16Elements_0        StoreTypedElementNumeric_Int16Elements_0        StoreTypedElementJSAny_Int16Elements_0  LoadTypedElement_Uint32Elements_0       StoreTypedElementNumeric_Uint32Elements_0       StoreTypedElementJSAny_Uint32Elements_0 ListFormatPrototypeFormatToParts        StringPrototypeToLowerCaseIntl  LdaImmutableContextSlotHandler  LdaImmutableCurrentContextSlotHandler   LdaLookupSlotInsideTypeofHandler        LdaLookupContextSlotInsideTypeofHandler LdaLookupGlobalSlotInsideTypeofHandler  GetNamedPropertyFromSuperHandler        DefineKeyedOwnPropertyInLiteralHandler  CreateArrayFromIterableHandler  CreateEmptyArrayLiteralHandler  CreateEmptyObjectLiteralHandler CreateUnmappedArgumentsHandler  JumpIfUndefinedConstantHandler  JumpIfNotUndefinedConstantHandler       JumpIfUndefinedOrNullConstantHandler    JumpIfJSReceiverConstantHandler JumpIfToBooleanTrueConstantHandler      JumpIfToBooleanFalseConstantHandler     ThrowReferenceErrorIfHoleHandler        ThrowSuperNotCalledIfHoleHandler        ThrowSuperAlreadyCalledIfNotHoleHandler ThrowIfNotSuperConstructorHandler       LdaImmutableContextSlotWideHandler      LdaCurrentContextSlotWideHandler        LdaImmutableCurrentContextSlotWideHandler       LdaGlobalInsideTypeofWideHandler        StaCurrentContextSlotWideHandler        LdaLookupContextSlotWideHandler LdaLookupGlobalSlotWideHandler  LdaLookupSlotInsideTypeofWideHandler    LdaLookupContextSlotInsideTypeofWideHandler     LdaLookupGlobalSlotInsideTypeofWideHandler      GetNamedPropertyFromSuperWideHandler    DefineNamedOwnPropertyWideHandler       DefineKeyedOwnPropertyWideHandler       DefineKeyedOwnPropertyInLiteralWideHandler      ShiftRightLogicalSmiWideHandler DeletePropertyStrictWideHandler DeletePropertySloppyWideHandler GetSuperConstructorWideHandler  CallUndefinedReceiverWideHandler        CallUndefinedReceiver0WideHandler       CallUndefinedReceiver1WideHandler       CallUndefinedReceiver2WideHandler       ConstructWithSpreadWideHandler  TestLessThanOrEqualWideHandler  TestGreaterThanOrEqualWideHandler       CreateRegExpLiteralWideHandler  CreateEmptyArrayLiteralWideHandler      CreateObjectLiteralWideHandler  CreateFunctionContextWideHandler        JumpIfNotNullConstantWideHandler        JumpIfUndefinedConstantWideHandler      JumpIfNotUndefinedConstantWideHandler   JumpIfUndefinedOrNullConstantWideHandler        JumpIfFalseConstantWideHandler  JumpIfJSReceiverConstantWideHandler     JumpIfToBooleanTrueConstantWideHandler  JumpIfToBooleanFalseConstantWideHandler JumpIfToBooleanTrueWideHandler  JumpIfToBooleanFalseWideHandler JumpIfUndefinedOrNullWideHandler        SwitchOnSmiNoFeedbackWideHandler        ThrowReferenceErrorIfHoleWideHandler    ThrowIfNotSuperConstructorWideHandler   SwitchOnGeneratorStateWideHandler       LdaContextSlotExtraWideHandler  LdaImmutableContextSlotExtraWideHandler LdaCurrentContextSlotExtraWideHandler   LdaImmutableCurrentContextSlotExtraWideHandler  TestReferenceEqualExtraWideHandler      LdaGlobalInsideTypeofExtraWideHandler   StaContextSlotExtraWideHandler  StaCurrentContextSlotExtraWideHandler   LdaLookupContextSlotExtraWideHandler    LdaLookupGlobalSlotExtraWideHandler     LdaLookupSlotInsideTypeofExtraWideHandler       LdaLookupContextSlotInsideTypeofExtraWideHandler        LdaLookupGlobalSlotInsideTypeofExtraWideHandler GetNamedPropertyExtraWideHandler        GetNamedPropertyFromSuperExtraWideHandler       GetKeyedPropertyExtraWideHandler        LdaModuleVariableExtraWideHandler       StaModuleVariableExtraWideHandler       SetNamedPropertyExtraWideHandler        DefineNamedOwnPropertyExtraWideHandler  SetKeyedPropertyExtraWideHandler        DefineKeyedOwnPropertyExtraWideHandler  StaInArrayLiteralExtraWideHandler       DefineKeyedOwnPropertyInLiteralExtraWideHandler CollectTypeProfileExtraWideHandler      ShiftRightLogicalExtraWideHandler       ShiftRightLogicalSmiExtraWideHandler    DeletePropertyStrictExtraWideHandler    DeletePropertySloppyExtraWideHandler    GetSuperConstructorExtraWideHandler     CallAnyReceiverExtraWideHandler CallUndefinedReceiverExtraWideHandler   CallUndefinedReceiver0ExtraWideHandler  CallUndefinedReceiver1ExtraWideHandler  CallUndefinedReceiver2ExtraWideHandler  CallWithSpreadExtraWideHandler  CallRuntimeForPairExtraWideHandler      InvokeIntrinsicExtraWideHandler ConstructWithSpreadExtraWideHandler     TestEqualStrictExtraWideHandler TestGreaterThanExtraWideHandler TestLessThanOrEqualExtraWideHandler     TestGreaterThanOrEqualExtraWideHandler  TestInstanceOfExtraWideHandler  CreateRegExpLiteralExtraWideHandler     CreateArrayLiteralExtraWideHandler      CreateEmptyArrayLiteralExtraWideHandler CreateObjectLiteralExtraWideHandler     GetTemplateObjectExtraWideHandler       CreateBlockContextExtraWideHandler      CreateCatchContextExtraWideHandler      CreateFunctionContextExtraWideHandler   CreateEvalContextExtraWideHandler       CreateWithContextExtraWideHandler       JumpIfNullConstantExtraWideHandler      JumpIfNotNullConstantExtraWideHandler   JumpIfUndefinedConstantExtraWideHandler JumpIfNotUndefinedConstantExtraWideHandler      JumpIfUndefinedOrNullConstantExtraWideHandler   JumpIfTrueConstantExtraWideHandler      JumpIfFalseConstantExtraWideHandler     JumpIfJSReceiverConstantExtraWideHandler        JumpIfToBooleanTrueConstantExtraWideHandler     JumpIfToBooleanFalseConstantExtraWideHandler    JumpIfToBooleanTrueExtraWideHandler     JumpIfToBooleanFalseExtraWideHandler    JumpIfUndefinedExtraWideHandler JumpIfNotUndefinedExtraWideHandler      JumpIfUndefinedOrNullExtraWideHandler   JumpIfJSReceiverExtraWideHandler        SwitchOnSmiNoFeedbackExtraWideHandler   ForInEnumerateExtraWideHandler  ThrowReferenceErrorIfHoleExtraWideHandler       ThrowIfNotSuperConstructorExtraWideHandler      SwitchOnGeneratorStateExtraWideHandler  SuspendGeneratorExtraWideHandler        ResumeGeneratorExtraWideHandler IncBlockCounterExtraWideHandler         x~                   x~                   y~                   ~                   ~                   ~                   0~                   y~                   8y~                   Ty~                   X~                   ~                   py~                   y~                   y~                   ~                   ~                   y~                   ~                   (~                   P~                   ~                   ~                   y~                   ~                   ~                   @~                   y~                   y~                                      y~                   z~                                      `~                   j                   *z~                   ~                   ~                   ~                   Ez~                   Wz~                   nz~                   ޛ                   z~                                      z~                   ~                                      8~                   ě                   `~                   z~                   z~                   z~                   z~                   {~                   {~                   .{~                   ={~                   E{~                   V{~                   k{~                   }{~                   {~                   {~                   7                   7                   {~                   "8                   {~                   S8                   {~                   |~                   ,|~                   ~                   ~                   ~                    ~                   0~                   H|~                   `~                   c|~                   |~                   |~                   |~                   ~                   ~                   ~                   >&                   |~                   &                   &                   |~                   ~                   |~                   0~                   }~                   *}~                               (     8}~            p-     P}~            -     k}~                   X~                   }~                   ~                   }~                   }~                   }~                   }~                   ~                   ~~                   ~~                   &~~                   ğ                   -                   =~~                   I~~                   Y~~                   e~~                   ~                   u~~                   ~~                   ~~                   ~~                   ~~                   ~~                   ~                   '~                   F*                   9~                   L~                   h~                   ~                   ~                   ~                    ~                   X~                   ~                   ~                   ~                   ~                    ~                   H~                   ~                   ~                   ~                   ~                   ~                   3                   ~                   ~                   /                   e/                   -/                   1                   ~                    ~                   8                   8                               p
                 `
     -~                             
     E~                  |}                   T~                   P~                   ~                   ~                    ~                   @~                   ~                   ~                   ~                   8~                   p~                   ~                   ~                   (~                   h~                   ~                   ~                   i~                               @                 f     ~                   ~                   ~                   Ҁ~                   ~                   ~                   ~                   "                   +            `q     +~                   <                  =~            p     Z            n     X~                   l            pt                      k~                   |~                   ~                   s~                  #~                  ~                  ~                  ǁ~                   ؁~                   ~                   ~                   ~                 @M            `     )~            P     C~            p     (                   (                    )                   8~                   *                   *                   `~                  ~                              P                                       ^~                 |~            p     ~                 (N                 XN                 N                 N                 ~            @     Ȃ~                 8O                  hO            0     O            
     ~                 O                 P                 ~                 ~            p     8~                 P                 Q~                  i~            p     ~            !     ~            $     ~            `&                  A                 A                 @B                 B     *            `C     >            `=     Q            =     g             >     |            C                 D                 E                 >                 >                 @?                 ?                  E     6             @     M            `@     g            0F     {            @                 G                 I                 0K                 P                 P     ׃~                  ~                   ~                  ~                  /~                  L~                  d~                  z~                  ~                  ~                  ~                  ~                  ք~                  ~                  ~                  ~                  &~                  ?~                  Z~                  o~                  
                  *                 G            Y     W                 i            Pb     ~            @e                 i     ~            n     ~             r                 v     օ~            0z                  ~     ~                 ~            0     "~                 R                 ;~                 V~                 o~                 ~                  ~                 ~                                   ֆ~                                              [     )            0     ~                 ~                  B                 ~                   ^                  5~                   K~                                                       e~            `     |~                   ~                   ~                   ~                  ~                   ~                   ~                   |            @     ̇~                                   ~                                              	                 
     ~                  
~                                               0     m~                   y~                   ~                   ~                   ~                   +~                   H~                   T~                   h~                   t~                   ~                   ~                   ~                   ~                   Ĉ~                   ܈~                   <~                   I~                   `~                   ~                   ~                   ~                   7~                   D~                   [~                   p~                   ~                   ~                   ~                   ˉ~                   ~                   @~                   ~                   ~                   %~                   <~                   h~                   ~                   Q~                   ~                   h~                   v~                   ~                   ~                   ~                   ~                   Ԋ~                   ~                   ~                    ~                   0~                   ~                   ~                   +~                   S~                   ~                  ~                  C~                  ~                              (     S~                  g~                  {~                   ~                  ~                  ~                  ̋~                   ދ~                  ~                 ~                 0~                 d!                   K~                   `~                   m~                   }~                   ~                   ~                   ~                   ˌ~                   ی~                   ~                   ~                   ~                   )~                   B~                   V~                   m~                   ~                   ~                   ~                   ~                   ԍ~                   ~                   ~                   ~                   0~                   N~                   _~                   u~                   ~                   ~                   ~                   Ύ~                   ~                   ~                   ~                   ,~                   P~                   ~                   D~                   Y~                   k~                   ~                   ~                   ~                   ~                   Ώ~                   ~                   ~                   p~                   ~                   .~                   A~                   T~                   d~                   |~                   ~                   ~                   ~                   0                   -                 ː~            p     H                  e                 0                                   ~                   U            @     ~                  ~                 ~                  %~                                                      0                              `                      .~                  L~                  U                 i~                 ~            @                 @     ~                   1                  +                                      ~                   ~                   V(                   q                   ԑ~                   ~                   ~                               P     hV            @     *                  A            @     T                 q                             `                 @                                                                           <                 }                  Y                 s                             p                 P     ~            `     ~                  -~                 E~                 ^~                   m~                   ~                   ~                   ǖ~                   ږ~                  ~                  ~                              )     ~                  ͒~                  ~                   ~                  ~                  !~                   8~                  O~                   j~                 @W                 hW            p     W            0     W                 ~                  ~                  #                  ~                  z#                  #                  #                  #                  #                                                                      '                  @                  ~                   ʓ~                 ~                  ~            `     ~                  1~                   \                  n                               p
                  `     F~                  `~                   v~                 ~                  ~                  ̔~                  ~                 ~            `     ~                 8~                 X                 S~                 ~                  n~                   ~                   ~                   ~                   Õ~                   .@                   ~@                   Ε~                   ~                   ~                   	~                   ~                   1~                   O~                   b~                   y~                  ~                  ~                  ~                  Ö~                   ֖~                  ~                  ~                  %                   &                   ~            p     1~            0
     T+                   )                   <)                   I~                   ^~                   Y            @     w~                   ~                   ~                   +                   !+                   ~                  ~                   ~                  H~                  x~                  ~                  ~                   ~                   ~                   Η~                  @~                   x~                   ~                   ~                   (~                   `~                   ~                   ~                   ~                   H~                   ~                   ~                   ~                                      R                   /                   ~                   ~                   I/                   *~                   <~                   D~            P     %ߊ                  Y            @     [~                   o~                 ~            p                  @                       ~            `     ~            0     ՘~                 ~                                   
~                 "~            `     :~                 !                 W~            @     [            p      [            p!     [            "      \            P$     p~            %     X\            0'     \            (     \            *     \            +     ]            ,     H]            `.     x]            /     ]            @1     ]            `     ^            p     H^            3     ~                 ^                 ^                 ^            2     (_                 P_                 x_                 _                 _                 `                  H`                 x`            5     ~            6     /!            >     ə~                  `            p7     (a            p8     Pa            9     a            :     a            ;     a            <     b            =     ~            0     hb            @     b            P     b            `     b            p     c                 8c                 hc                 c                 c            ?     d                 8d                 hd            @     d            A      ~                 ~                 e            C     He            D     xe             F     e            G     e             I     f            0W     8f            @X     hf            PY     f            `Z     f            p[     g            \     @g            pJ     pg            K     g            PM     g            N     h            0P     Hh            Q     h            S     h            T     h                   i                 Xi                  i            U     i            0     i            @     (j            P     Xj            `     j            p     j                 j                 k                 Hk            ^     xk                 k                 k                  l                 Xl                 l            ]     l             u     7~                  Q~                 Hm            u     xm            v     m                  m            0     n            @     8n            P     hn            }     n            0     n                 n            0     0o                 ho            0     o            x     o            z     p            0|     Hp            w     p            `     p            p     p                 q                 Pq                 q                 q                 q                 0r                 hr                 r                  r                  s                  8s            0     ps                 s                 s            @     t            P     @t            `     pt            p     t                 t                  u                 0u                 `u                 u                 u                 u                 0v                 hv                  v            0     v            P     w            p     n~                 M!                 ~                  w                 w                 w                 ~                 0x                 Xx                 x                 x                 x                 y                 ~                 py                 ޚ~            0     y                 ~                 ~            @     @z            P     pz            `     z            p     z                 z                 {                  6~                  j!                 p{                 {            p     {                  {            Ч     Q~                 H|            0     x|            Ь     |            p     |            0     h~                 H}                 ~                 ~                 ~                 }                  ~                 H~                  p~            0     ~            0     ~            @                  _     ޛ~            P     ~            `                 `                 a                 0c                 d     H            f                 g                 h                 `j     (            p     X                                                   聀                                  H                 x                             l     ؂                             k     H            m     ~                               o     Ѓ             p                  pq     0                 `                              0                 @                  t                  P     X            r     1~                 !                 M~                             `                  p     X                                                                    0                 h            p                      i~                  !            @     ~                                  @                 x                                                    ~                 8                  `            0     ~            @                      艀            з                 P     H                 x            в                 P     ؊                                  8            p     `            P                                   `     ܜ~                  ~                  ~                   D~                  ~                   ~                   ~                  ~                  (~                   C~                   ~                   ~           	       N~                   j~                   H~                  p~                  ~                  v~                   ~                   ~                  ~                   ~                  X~                   ~                   ~                   ݯ~                   x~                   ~                   ~                  ~                  ʝ~                   ~                   ~                   "                  ~                   ~                   H~                   ~                   
~                   ~                   ^~                   %~                   B~                   Y~                   p~                   q~                   ~                  ~                  ~                  ~                   ~                   ;~                   ~                  @~                  p~                  ~                   ~                   ~                  ~                   ~                  ~                   ڞ~                   X~                   ~                   y~                   H~                  p~                  ~                   ~                   ~                   3~                   ~                  ~                  ~                  ~                  @~                  I~                  [~                   e~                   |~                   ~                   ~                  ~                  П~                                      ~                   +                   ~                   1                   ~                   ~                  7~                   D~                  Z~                  t~                  ~                   ~                   ~                   ̠~                   ~                   ~                   ~                   h~                   -                   !~                   ;~                   S~                   n~                                      ~                   ~                  .                   ~                   ~                   1                   ԡ~                   X                   ~                   1                   1                   1                   ~                   ~                   ~                   ~                   ~                   2~                   D~                   ~                   ~                   _~                   y~                   ~                   ~                   Ǣ~                   ~                   ~                   ~                   4~                   R~                   o~                   ~                   ~                   ~                   ף~                   ~                   ~                   (~                   D~                   b~                   (~                  ~                   H~                   ~                  ~                   =(                   *                   e                   Ӥ~                   ~                   ~                   x~                   ~                   4~                  <~                  E~                  O~                  Y~                  c~                  k~                   s~                   {~                  ~                  ~                  ~                  ~                  ~                  ~                  ~                  ǥ~                  ѥ~                  ٥~                  ~                  ~                  ~                  ~                  ~                  ~                  ~                  $~                  -~                  5~                  >~                  G~                  P~                  X~                  a~                   k~                  v~                   ~                  ~                  ~                  ~                  ͦ~                  ~                                     ~                  F8                   >                   I                   T                   ]                   g                                      
                                       ,                                                                                               v                                                                            73                   L3                                      3                   ~                   ~                   0                  4~                  L~                  a~                  v~                  ~                  ~                  P                   4                   ç~                   ~                  ~                  a                   ا~                  ~                   ~                  ~                  ~                  (~                  H~                  p~                  ~                  ~                  }                  ~                  ~                  2~                  H~                  \~                  o~                  ~                  ~                   ~                   ƨ~                  v                   4                   ߨ~                  ~                   ~                  ~                   3~                   D~                   X~                   i~                   {~                   ~                  ~                  ~                   ~                   ҩ~                  ~                  ~                  ~                  +~                   6~                  L~                  W~                   o~                  ~                  ~                  ~                   ~                  ~                   Ϊ~                   ~                   ~                  ~                  t5                   (~                   =~                  Q~                   i~                  ~                   ~                   ~                  ~                  ~                  ~                  ٫~                  ~                  ~                  #~                   ;~                   F~                   \~                   o~                   ~                   ~                   ~                   ɬ~                   ެ~                   ~                   	~                   ~                   4~                   G~                   Z~                   r~                   ~                  ~                  ~                  ҭ~                  ~                    ~                   ~                   #~                  9~                  S~                   h~                   ~                   ~                   ~                   Ů~                   ޮ~                   @~                  ~                  ~                  (~                  ?~                  ]                   U~                   n~                   ~                   ~                   ~                   د~                   h~                   ~                   ~                   ~                   6~                   C~                   ~                   ]~                   t~                   ~                   ~                   ~                   Ѱ~                   ~                   ~                  ~                  '~                   B~                   ]~                   v~                   ~                   ~                   ~                   ˱~                   ٱ~                   ~                   ~                   ~                   '~                   7~                   A~                   Q~                   h~                   ~                   ~                   ~                   ϲ~                   ~                   ~                   ~                   ;~                   N~                   ~                   ?                   `~                   h~                   s~                   ~                   ~                   ~                   ~                   ~                   ʳ~                   ~                   >                   ?                   ?                   ?                   ?                   ~                   ~                   d?                   ~                   ?                   '~                   3~                   c@                   ?                   G)                   
B                   A                   A                   N~                   b~                   ~                   |~                   ~                   ~                   ȴ~                   @                   ~                   ~                   ~                   ~                   0~                   >                   B~                   V~                   j~                   t~                   ~                   ~                   ~                   ŵ~                   ~                    ~                   ~                    ~                   ~                   H~                   p~                   -~                   K~                   d~                   ~                   ~                   ~                   ~                   ~                   ~                   ~                   8~                   h~                   ~                   ~                   ~                   ~                   8~                   `~                   Ӷ~                   ~                   ~                   ~                    ~                    ~                   @~                   h~                   ~                   ~                   ~                   ~                   @~                   p~                   ~                   ~                   ~                    ~                   P~                   ~                   ~                   ~                   ~                   0~                   `~                   ~                   ~                   ~                   ~                   0~                   X~                   ~                   ~                   ~                    ~                   (~                   X~                   ~                   ~                   ~                   !            `     ~            e     ~            c     ~            b     X            a                      8~                  ،                 T~             *     n~            `/     ~            0-     x                                                                    @                 ~                 ~            P                  P                 `     ٷ~            0     !            1     !            @2     ~                    ~                   (            3     ~            4     "            5     (~            PI     @~            `J     X~            :     q~            pK     ~            L     ~            ;     ~            M     ָ~            <     ~             F     ~            P8      ~            p9     8~            N     0            O     X            =     2"            @H     P"            0G     O~            ?     g~            0@     ~            P     ~            PA     ~            !     (             (     X            %                 @                      蒀                             $     H                  ȹ~            W                 @Y     ߹~            PZ     蓀            [     ~            _     ~            Q     `            `C                 D     Ȕ            pS                  pB     n"            `i     0            k     6~             m     P~             k     l~            @h     ~            `n     ~            o     ~                 P            T                 V     (~                                   ܺ~                   ~                                   0                 `                 ~            @                      藀                                    P                                                                    (                  X            p                                                                       0     -~            q                 @u                 P                 0     H~            x     e~            |     X            @s                 P                 0}     ~            v     ~            z     0            0r     `                 v~                  ~                 ~                 һ~                 ~                  ~                 ~                 &~                 9~                 L~           	      _~           
      r~                 ~~                 ~           
      ~                 ~                 ~                 м~                 ߼~                 ~                 ~                 H~                 ~                 h~                 i~                 5~                 @~                 S~                 e~                 ~                 ~                 ~                 ~                  ν~           !      ߽~           "      ~           #      
~           $      #~           %      @~           &      U~           '      q~           (      ~           )      ~           *      ~           +      ~           ,      ~           -                  .      ~           /      Ѿ~           0      ~           1      ~           2      ~           3      9~           4      Q~           5      o~           6      0            7      ~           8      ~           9      ~           :      ~           ;      ÿ~           <      ο~           =      ٿ~           >      ~           ?      ~           @      ~           A      ~           B      *~           C      <~           D      U~           E      c~           F      q~           G      ~           H      ~           I      ~           J      ~           K      ~           L      ~           M      ~           N      ~           O      ~           P      ,~           Q      7~           R      B~           S      P~           T      b~           U      k~           V      ~           W      }~           X      ~           Y      ~           Z      ~           [      ~           \      ~           ]      ~           ^      %~           _      :~           `      W~           a      u~           b      ~           c      ~           d      ~           e      ~           f      ~           g      	~           h       ~           i      1~           j      L~           k      ]~           l      t~           m      ~           n      ~           o      ~           p      ~           q      ~           r      ~           s      
~           t      ~           u      +~           v      ;~           w      K~           x      f~           y      X            z      x            {      ~           |                  }      ~           ~      ~                 ~                 ~                 ~                 ~                 -~                 F~                 _~                                   |~                 ~                 ~                 ~                 ~                 ~                                                                       ~                 ~                 H                 h                                  3~                 N~                 j~                 |~                 ~                 ~                 ~                 ~                 ~                 ~                 ~                 9~                 O~                 c~                 x~                 ~                 ~                 ~                 ~                 ~                                                                    0                 ~                 ~                 ~                 ~                 0~                 @~                 W~                 d~                 u~                 ~                 ~                 ~                 ~                 ~           	      ~           
      ~                 ~           
      0~                 G~                 X                                                   a~                 q~                 ~                 ~                 ~                 ~           !                 "      ~           #      ~           $                  %      ~           &      (           '      H           (      h           )                 *                 +      (~           ,      A~           -                 .      ]~           /      y~           0      ~           1      ~           2                 3      ~           4      @           5      ~           6      h           7      ~           8      &~           9      5~           :      D~           ;      S~           <      b~           =      q~           >      ~           ?      ~           @      ~           A      ~           B      ~           C      ~           D      	~           E      ~           F      -~           G      ?~           H      Q~           I      c~           J      u~           K      ~           L      ~           M      ~           N      ~           O                 P      ~           Q      ~           R      ~           S       ~           T                 X                 Y                 Z      6~           [      Q~           \      i~           ]      ~           ^      ~           _                 `      @           a      h           b                 c      ~           d      ~           e      ~           f      ~           g      ~           h      7~           i                 j      L~           k      a~           l      |~           m      ~           n                 o                 p      ~           q      ~           r      ~           s      ~           t      ~           u      ~           v                  x      *~           y      @           {      h           |      H~           ~      _~                 |~                 ~                 ~                                  ~                 ~                 ~                 ~                 /~                 G~                                                                     (                 e~                 X                 x                                                                                     ~                 ~                 ~                 ~                 ~                 ~                 0                 ~                 X                 4~                 N~                 f~                 ~                 ~                                                                    ~                 ~                 ~                 ~                 ~                 #~                 ?~                 [~                 w~                 ~           	      ~           
      ~                 ~           
      ~                                  	                 @	                 h	                 ~                 (~                 <~                 X~                 	                 s~           !      	           "      ~           #      	           $      
           %      ~           &      0
           '      X
           (      
           )      
           *      
           +      ~           ,                 -      @           .      p           /                 0                 1                 2                 3      8           4      `           5                 6                 7                 8      ~           9      ~           :      ~           ;      ~           <      3~           =      G~           >      [~           ?      u~           @      ~           A      ~           B      ~           C      
           D      ~           E      ~           F      ~           G      %~           H      <~           I      S~           J      j~           K      ~           L      ~           M      ~           N      ~           O      0
           P      ~           Q      ~           R      &~           S      =~           T      X
           X      
           Y      
           Z      
           [      X~           \      u~           ]      ~           ^      ~           _      
           `                 a      @           b      h           c                 d      ~           e                 f      ~           g                 h      	~           i                 j      #~           k                  l      =~           m      @           n      `           o                 p                 q      Z~           r      q~           s      ~           t      ~           u      ~           v                 x                 y                  {      H           |      ~           ~      p                 ~                                                                                     8                 ~                 '~                 <~                 `                                                                                     8                 `                                                                                     @                 Y~                 t~                 ~                 ~                 h                                                                                      (                 ~                 ~                 ~                 ~                 H                 x                                                                    8~                                  T~                      @	     !map_->is_iterable()                    +     +     +     p+                         Cannot grow external assembler buffer   X                                                               X                                                               P                    x    X                       3     5              4      5                     1     2     `1     p1     4                     1     1     1     1     1                     P2     3                no reason Expected feedback vector Expected baseline data Input string too long Invalid bytecode Invalid HandleScope level Invalid jump table index The object is not tagged The object is tagged Offset out of range Operand is a smi Operand is cleared Operand is not a constructor Operand is not a fixed array Operand is not a function Operand is not a CodeT Operand is not a smi Promise already settled Stack frame types must match Unexpected FPCR mode. Unexpected negative value Unexpected value Unsupported module operation Code generation failed Function is being debugged Native function literal Optimization disabled    32 bit value in register is not zero-extended   API call returned invalid object        Allocating non-empty packed array       Allocation is not double aligned        Expected optimized code cell or optimization sentinel   Expected undefined or cell in register  The function_data field should be a BytecodeArray on interpreter entry  Cannot advance current bytecode,        invalid parameters and registers in generator   Missing bytecode array from function    Operand is a smi and not a bound function       Operand is a smi and not a constructor  Operand is a smi and not a function     Operand is a smi and not a generator object     Operand is not a bound function Operand is not a callable function      Operand is not a generator object       Received invalid return address Register did not match expected root    Return address not found in frame       Should not directly enter OSR-compiled function Stack access below stack pointer        Unaligned cell in write barrier Unexpected additional pop value Unexpected ElementsKind in array constructor    Unexpected runtime function id for the InvokeIntrinsic bytecode Unexpected initial map for Array function       Unexpected level after return from api call     Unexpectedly returned from dropping frames      Unexpectedly returned from a throw      Should not return after throwing a wasm trap    The stack pointer is not the expected value     Unsupported non-primitive compare       Wrong address or value passed to RecordWrite    Wrong number of arguments for intrinsic Wrong value in code start register passed       Wrong context passed to function        thread_in_wasm flag was already set     thread_in_wasm flag was not set Bailed out due to dependency change     Cyclic object state detected by escape analysis Optimized graph construction failed     Function is too big to be optimized     Not enough virtual registers (regalloc) Optimization is always disabled                         (                    @    x    2    K        b    x                    @                    h                        "    ?    \    8    `    v                            (        P    p                     0        `                            @    p                                    (    8    5    `    L            Z    g                GetCommentSize() == strlen(comment_string) + 1  P     P     P     P     P     P     `Q     pQ     Q     Q     @Q     PQ     hit eval-global eval-contextual                 U                     U                     PU     [%s   (target %s) V8.RecompileSynchronous aborted optimizing  because: %s compiling method  using %s%s   - took %0.3f, %0.3f, %0.3f ms  Compiled: %d functions with %d byte source size in %fms.
 V8.CollectSourcePositions     new function from shared function info   for optimized recompilation because --always-opt [marking  interpreter OptimizedCodeCache::Get found optimized code for  at OSR bytecode offset %d V8.OptimizeCode  later.
 V8.OptimizeConcurrentPrepare   ** Queued  V8.OptimizeNonConcurrent   ** Compilation queue full, will retry optimizing        ** High memory pressure, will retry optimizing         for concurrent optimization.
 ConcurrencyMode::kSynchronous ConcurrencyMode::kConcurrent       [OSR - started. function: %s, osr offset: %d, mode: %s]
        [OSR - unavailable (failed or in progress). function: %s, osr offset: %d, mode: %s]
 V8.OptimizeConcurrentFinalize completed optimizing [OSR - requesting install. function: %s, osr offset: %d]
       V8.FinalizeBackgroundCompileTask        V8.StreamingFinalization.CheckCache     V8.OffThreadFinalization.Publish        V8.StreamingFinalization.AddToCache     V8.StreamingFinalization.Release                  C     "     ,                                             _           using Sparkplug compiling  - took %0.3f ms V8.CompileEval V8.Compile V8.CompileCode V8.CompileDeserialize StressBackgroundCompileThread        background_compile_thread.Start()       main_thread_maybe_result.is_null()      maybe_result.is_null() == main_thread_maybe_result.is_null()    L               _                         {     a     2                    {     .                         D               9          c               D     ~3     g3     P3     1     93     0     "3     0     r0     3     2     2     2     2     l-     value().IsFeedbackVector()  because --always-opt BackgroundCompileTask::Run V8.CompileCodeBackground                    u     u                      u     @u     Pw                     u     v     [     +++;     s     Unknown external reference %p.
 <from api> <unresolved> kSpecialReferenceCount == *index        kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent == *index    kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent + kBuiltinsReferenceCount == *index  kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent + kBuiltinsReferenceCount + kRuntimeReferenceCount == *index kSizeIsolateIndependent == *index       kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent == *index 0 == *index kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent + kIsolateAddressReferenceCount == *index     kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent + kBuiltinsReferenceCount + kRuntimeReferenceCount + kAccessorReferenceCount == *index       kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent + kIsolateAddressReferenceCount + kStubCacheReferenceCount == *index  kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent + kIsolateAddressReferenceCount + kStubCacheReferenceCount + kStatsCountersReferenceCount == *index kSize == index                                                               p     P     p     P          P          @                                                 	   
         
                                                             !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /   0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?   @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _   `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~                                                                                                                                                                                                                                                                                                                                                                                                                         	  
      
                                         !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~                                                                                                                                                                                                                                                                                       	  
      
                                         !  "                      (     p-     -     p
     `
          
     @     f     `q           p     n     pt               `     P     p     P                    p                              @                0     
                         p                     p     !     $     `&      A     A     @B     B     `C     `=     =      >     C     D     E     >     >     @?     ?     E      @     `@     0F     @     G     I     0K     P     P                Y          Pb     @e     i     n      r     v     0z      ~          0                                                              [     0                                `           @                          	     
          0     (                               p                     @                      `                    @     @     P     @     