{"version":3,"file":"index.min.mjs","sources":["../src/by-request.ts","../src/request-binary.ts","../src/request-file.ts","../src/request-text.ts","../src/request-json.ts"],"sourcesContent":["/*\n  Copyright © 2019-2025 Kerry Shetline, kerry@shetline.com\n\n  MIT license: https://opensource.org/licenses/MIT\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\n  documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\n  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\n  persons to whom the Software is furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the\n  Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nimport { RequestOptions } from 'http';\nimport zlib from 'zlib';\nimport { FollowOptions, http, https } from 'follow-redirects';\nimport { parse as parseUrl } from 'url'; // es lint-disable-line node/no-deprecated-api\nimport iconv from 'iconv-lite';\nimport { getReasonPhrase, StatusCodes } from 'http-status-codes';\nimport { Writable } from 'stream';\nimport { SecureContextOptions } from 'tls';\nimport { checksum53, clone, isString, makePlainASCII, processMillis, toNumber, urlEncodeParams } from '@tubular/util';\nimport fs, { StatOptions, Stats } from 'fs';\nimport temp from 'temp';\nimport * as pathUtil from 'path';\nimport { spawn } from 'child_process';\nimport { lstat, mkdir, readFile, writeFile } from 'fs/promises';\n\ntemp.track();\n\nconst MAX_EXAMINE = 2048;\n\nexport interface ResponseInfo {\n  bomDetected?: boolean;\n  bomRemoved?: boolean;\n  cachePath?: string;\n  callback?: string;\n  charset?: string;\n  contentEncoding?: string;\n  contentLength?: number;\n  contentType?: string;\n  fromCache?: boolean;\n  stream?: Writable;\n}\n\ntype ReqOptions = (RequestOptions & SecureContextOptions & { rejectUnauthorized?: boolean; servername?: string } & FollowOptions<RequestOptions>);\n\nexport interface ExtendedRequestOptions extends ReqOptions {\n  autoDecompress?: boolean;\n  body?: Buffer | string;\n  cachePath?: string;\n  dontDecompress?: boolean;\n  dontEndStream?: boolean;\n  followRedirects?: boolean; // follow-redirects\n  forceEncoding?: boolean;\n  ignoreBom?: boolean;\n  json?: any;\n  keepBom?: boolean;\n  maxBodyLength?: number; // follow-redirects\n  maxCacheAge?: number;\n  maxRedirects?: number; // follow-redirects\n  params?: string | Record<string, string | number | boolean | null>;\n  progress?: (bytesRead: number, totalBytes: number | undefined) => void;\n  responseInfo?: (info: ResponseInfo) => void;\n  stream?: Writable; // For internal use only\n  streamCreated?: boolean; // For internal use only\n  trackRedirects?: boolean; // follow-redirects\n}\n\nexport async function safeLstat(path: string, opts?: StatOptions & { bigint?: false }): Promise<Stats> {\n  try {\n    return await lstat(path, opts);\n  }\n  catch {\n    return null;\n  }\n}\n\nasync function ensureDirectory(path: string): Promise<void> {\n  const parent = pathUtil.dirname(path);\n\n  if (parent)\n    await mkdir(parent, { recursive: true });\n}\n\nfunction getCaseInsensitiveProperty(obj: any, key: string) {\n  key = key.toLowerCase();\n\n  for (const k of Object.keys(obj || /* istanbul ignore next: unreached sanity check */ {})) {\n    if (isString(k) && k.toLowerCase() === key)\n      return obj[k];\n  }\n\n  return undefined;\n}\n\nfunction makeError(err: any): Error {\n  /* istanbul ignore next: unreached sanity check */\n  if (err instanceof Error)\n    return err;\n\n  const code = toNumber(err);\n\n  if (code >= 100) {\n    try {\n      return new Error(`Error ${code}: ${getReasonPhrase(code)}`);\n    }\n    catch {\n      return new Error(`Unknown HTTP status code ${code}`);\n    }\n  }\n\n  return new Error(err.toString());\n}\n\nlet checkedGzipShell = false;\nlet hasGzipShell = false;\n\nexport async function request(urlOrOptions: string | ExtendedRequestOptions,\n                       optionsOrEncoding?: ExtendedRequestOptions | string, anEncoding?: string): Promise<string | Buffer | number> {\n  let options: ExtendedRequestOptions;\n  let body: Buffer | string;\n  let cachePath: string;\n  let encoding = anEncoding as BufferEncoding;\n  let fromCache = false;\n\n  if (isString(urlOrOptions)) // noinspection JSDeprecatedSymbols\n    options = parseUrl(urlOrOptions);\n\n  if (isString(optionsOrEncoding))\n    encoding = (optionsOrEncoding.replace('us-ascii', 'ascii')) as BufferEncoding;\n  else if (optionsOrEncoding) {\n    /* istanbul ignore else: unreached sanity check */\n    if (options)\n      Object.assign(options, optionsOrEncoding);\n    else\n      options = clone(optionsOrEncoding);\n  }\n  else if (!options)\n    options = urlOrOptions as ExtendedRequestOptions;\n\n  /* istanbul ignore next: unreached sanity check */\n  if (!options.protocol?.endsWith(':'))\n    options.protocol += ':';\n\n  /* istanbul ignore next: unreached sanity check */\n  if (!options.path?.startsWith('/'))\n    options.path = '/' + (options.path || '');\n\n  if (!options.headers)\n    options.headers = { 'Accept-Encoding': 'gzip,deflate,br' };\n  else if (!getCaseInsensitiveProperty(options.headers, 'accept-encoding'))\n    (options.headers as any)['Accept-Encoding'] = 'gzip,deflate,br';\n\n  let forceEncoding = options.forceEncoding;\n\n  if (!encoding) {\n    encoding = 'utf8';\n    // Only an explicit encoding will be forced, not this default.\n    forceEncoding = false;\n  }\n\n  options.method = options.method || (options.body || options.params || options.json ? 'POST' : 'GET');\n\n  let contentType = getCaseInsensitiveProperty(options.headers, 'Content-Type');\n  const hadContentType = !!contentType;\n  const charset = ((/\\bcharset\\s*=\\s*(\\S+)\\s*$/i.exec(contentType || '') ?? [])[1] ?? 'utf8').toLowerCase() as BufferEncoding;\n\n  if (!contentType) {\n    if (options.params) {\n      body = isString(options.params) ? options.params : urlEncodeParams(options.params);\n      contentType = contentType || 'application/x-www-form-urlencoded; charset=UTF-8';\n    }\n    else if (options.json) {\n      body = isString(options.json) ? options.json : JSON.stringify(options.json);\n      contentType = contentType || 'application/json; charset=UTF-8';\n    }\n    else if (options.body) {\n      body = options.body;\n      contentType = contentType || 'text/plain; charset=UTF-8';\n    }\n  }\n  else\n    body = options.body;\n\n  if (!hadContentType && contentType)\n    (options.headers as any)['Content-Type'] = contentType;\n\n  delete options.body;\n  delete options.json;\n  delete options.params;\n\n  if (options.cachePath) {\n    cachePath = options.cachePath;\n    delete options.cachePath;\n\n    if (/[/\\\\]$/.test(cachePath) || (await safeLstat(cachePath))?.isDirectory()) {\n      const url = isString(urlOrOptions) ? urlOrOptions :\n        options.protocol + (options.hostname || options.host) +\n        (options.port ? ':' + options.port : /* istanbul ignore next: unreached sanity check */ '') + options.path;\n      let base = '';\n      let suffix = '';\n      let $ = /.*\\/([^?&/]+)/.exec(options.path);\n\n      if ($) {\n        base = makePlainASCII($[1], true).replace(/,/g, '-').replace(/^([^a-z])/i, 'X$1');\n\n        if (($ = /^(.+)(\\..+)$/.exec(base))) {\n          base = $[1].substring(0, 20) + '-';\n          suffix = $[2].substring(0, 8);\n        }\n        else\n          base = base.substring(0, 20) + '-';\n      }\n\n      cachePath = pathUtil.join(cachePath, base + checksum53(url + (body ? body.toString() : '')) + suffix);\n    }\n  }\n\n  const protocol = (options.protocol === 'https:' ? https : http);\n  const stream = options.stream;\n  const startTime = processMillis();\n\n  if (!checkedGzipShell) {\n    checkedGzipShell = true;\n    hasGzipShell = true;\n\n    const gzipProc = spawn('gzip', ['-L']);\n\n    await new Promise<void>(resolve => {\n      gzipProc.once('error', /* istanbul ignore next: unreached sanity check */ () => { hasGzipShell = false; resolve(); });\n      gzipProc.stdout.once('end', resolve);\n    });\n  }\n\n  let canUseCache = false;\n\n  if (cachePath) {\n    const stats = await safeLstat(cachePath);\n\n    if (stats && (!options.maxCacheAge || stats.mtimeMs > Date.now() - options.maxCacheAge)) {\n      if (options.maxCacheAge) {\n        try {\n          const contents = await readFile(cachePath, { encoding: encoding === 'binary' ? null : encoding });\n\n          if (options.responseInfo)\n            options.responseInfo({ cachePath, fromCache: true });\n\n          return contents;\n        }\n        catch {}\n      }\n\n      canUseCache = true;\n\n      if (!getCaseInsensitiveProperty(options.headers, 'If-Modified-Since'))\n        options.headers = Object.assign(options.headers, { 'If-Modified-Since': stats.mtime.toUTCString() });\n    }\n  }\n\n  delete options.maxCacheAge;\n\n  return new Promise<string | Buffer | number>((resolve, reject) => {\n    const reject_ = (err: any) => reject(makeError(err));\n    const endStream = ((options.streamCreated && options.dontEndStream !== true) || !options.dontEndStream)\n                      && stream !== process.stdout && stream !== process.stderr;\n    const reportAndResolve = (content: Buffer | string): void => {\n      if (options.responseInfo)\n        options.responseInfo({ cachePath, fromCache });\n\n      resolve(content);\n    };\n    const req = protocol.request(options as any, res => {\n      function getHeader(hdr: string) { return (res.headers[hdr] || '').toString().toLowerCase(); }\n\n      if (200 <= res.statusCode && res.statusCode < 300) {\n        let source = res as any;\n        let postDecompress = false;\n        const contentEncoding = getHeader('content-encoding');\n        const contentType = getHeader('content-type');\n        let contentLength = parseInt(getHeader('content-length'), 10);\n        contentLength = (isNaN(contentLength) ? undefined : contentLength);\n        const binary = (encoding === 'binary' || !!options.stream ||\n          (isBinary(contentType) && (!encoding || !iconv.encodingExists(encoding))));\n        let usingIconv = false;\n        let charset: string;\n        let autodetect = !forceEncoding && !binary;\n        let bytesRead = 0;\n        let bomDetected = false;\n        let removeBom = false;\n\n        if (!options.dontDecompress || !binary) {\n          if (contentEncoding === 'x-gzip' && hasGzipShell)\n            // createGunzip sometimes chokes with \"incorrect header check\" errors on 'x-gzip' content,\n            // whereas command-line gzip (if available) does not.\n            postDecompress = true;\n          else if (contentEncoding === 'gzip' || contentEncoding === 'x-gzip' ||\n              (options.autoDecompress && /\\b(gzip|gzipped|gunzip)\\b/.test(contentType))) {\n            source = zlib.createGunzip({ windowBits: 15 });\n            res.pipe(source);\n          }\n          else if (contentEncoding === 'deflate' || (options.autoDecompress && /\\bdeflate\\b/.test(contentType))) {\n            source = zlib.createInflateRaw();\n            res.pipe(source);\n          }\n          else if (contentEncoding === 'br') {\n            source = zlib.createBrotliDecompress();\n            res.pipe(source);\n          }\n          else if (contentEncoding && contentEncoding !== 'identity') {\n            reject_(StatusCodes.UNSUPPORTED_MEDIA_TYPE);\n            return;\n          }\n        }\n\n        if (res !== source) {\n          res.once('error', /* istanbul ignore next: unreached sanity check */ error => {\n            if (stream && endStream)\n              stream.end();\n\n            reject_(error);\n          });\n\n          res.on('data', (data: Buffer) => {\n            bytesRead += data.length;\n\n            if (options.progress)\n              options.progress(bytesRead, contentLength);\n          });\n        }\n\n        if (!binary) {\n          if (forceEncoding)\n            charset = encoding;\n          else {\n            const $ = /\\bcharset\\s*=\\s*['\"]?\\s*([\\w-]+)\\b/.exec(contentType);\n\n            if ($)\n              charset = $[1].replace('us-ascii', 'ascii');\n            else {\n              charset = encoding;\n              autodetect = true;\n            }\n          }\n\n          if (!/^(ascii|utf8|utf-8|utf16le|ucs2|base64|binary|hex)$/.test(charset)) {\n            if (!iconv.encodingExists(charset)) {\n              reject_(StatusCodes.UNSUPPORTED_MEDIA_TYPE);\n              return;\n            }\n\n            usingIconv = true;\n          }\n        }\n\n        let content = Buffer.alloc(0);\n\n        source.once('error', /* istanbul ignore next: unreached sanity check */ (error: any) => {\n          if (stream && endStream)\n            stream.end();\n\n          reject_(error);\n        });\n\n        source.on('data', (data: Buffer) => {\n          if (res === source) {\n            bytesRead += data.length;\n\n            if (options.progress)\n              options.progress(bytesRead, contentLength);\n          }\n\n          if (content.length === 0 && !binary && !options.ignoreBom) {\n            const bomCharset = checkBOM(data);\n\n            if (bomCharset) {\n              if (!forceEncoding) {\n                /* istanbul ignore next: unreached sanity check */\n                if (!iconv.encodingExists(bomCharset)) {\n                  reject_(StatusCodes.UNSUPPORTED_MEDIA_TYPE);\n                  return;\n                }\n\n                charset = bomCharset;\n                usingIconv = (bomCharset !== 'utf8');\n                autodetect = false;\n              }\n\n              bomDetected = true;\n\n              if (!options.keepBom)\n                removeBom = true;\n            }\n          }\n\n          if (autodetect && content.length === 0) {\n            const embeddedEncoding = lookForEmbeddedEncoding(data);\n\n            if (embeddedEncoding) {\n              if (!iconv.encodingExists(embeddedEncoding)) {\n                reject_(StatusCodes.UNSUPPORTED_MEDIA_TYPE);\n                return;\n              }\n\n              charset = embeddedEncoding;\n              usingIconv = true;\n              autodetect = false;\n            }\n          }\n\n          if (stream) {\n            stream.write(data, error => {\n              /* istanbul ignore next: unreached sanity check */\n              if (error) {\n                stream.end();\n                reject_(error);\n              }\n            });\n          }\n          else\n            content = Buffer.concat([content, data], content.length + data.length);\n        });\n\n        source.once('end', () => {\n          const wrapUp = () => {\n            if (options.progress && contentLength === undefined)\n              options.progress(bytesRead, bytesRead);\n\n            if (options.responseInfo) {\n              options.responseInfo({\n                bomDetected,\n                bomRemoved: removeBom,\n                cachePath,\n                charset: binary ? 'binary' : charset,\n                contentEncoding: contentEncoding || 'identity',\n                contentLength: bytesRead,\n                contentType,\n                fromCache,\n                stream\n              });\n            }\n\n            if (stream) {\n              if (endStream)\n                stream.end();\n\n              resolve(bytesRead);\n            }\n            else if (binary) {\n              if (cachePath)\n                ensureDirectory(cachePath).then(() => writeFile(cachePath, content).finally(() => reportAndResolve(content)));\n              else\n                resolve(content);\n            }\n            else {\n              let text: string;\n\n              if (usingIconv)\n                text = iconv.decode(content, charset, { stripBOM: false });\n              else\n                text = content.toString(charset as BufferEncoding);\n\n              if (removeBom && text.charCodeAt(0) === 0xFEFF)\n                text = text.substring(1);\n\n              if (cachePath)\n                ensureDirectory(cachePath).then(() => writeFile(cachePath, text, { encoding }).finally(() => reportAndResolve(text)));\n              else\n                resolve(text);\n            }\n          };\n\n          if (postDecompress) {\n            // Why take all of this trouble to work with a temp file instead of just piping streams?\n            // Because if I don't, mysterious \"write EPIPE / at WriteWrap.onWriteComplete [as oncomplete]\"\n            // errors occur that can't be caught and cause the code to fail, even after successfully\n            // obtaining the decompressed data. This absurd work-around solves that problem.\n            temp.open('by-request-', (err, file) => {\n              /* istanbul ignore next: unreached sanity check */\n              if (err)\n                reject_(err);\n              else {\n                fs.write(file.fd, content, err => err && reject_(err));\n                fs.close(file.fd, err => {\n                  /* istanbul ignore next: unreached sanity check */\n                  if (err)\n                    reject_(err);\n                  else {\n                    const gzipProc = spawn('gzip', ['-dc', file.path]);\n                    let decompressed = Buffer.alloc(0);\n\n                    gzipProc.stdout.on('data', d => decompressed = Buffer.concat([decompressed, d], decompressed.length + d.length));\n                    gzipProc.stdout.on('error', err => reject_(err));\n                    gzipProc.stdout.on('end', () => {\n                      content = decompressed;\n                      bytesRead = content.length;\n                      fs.unlink(file.path, () => {});\n                      wrapUp();\n                    });\n                  }\n                });\n              }\n            });\n          }\n          else\n            wrapUp();\n        });\n      }\n      else {\n        if (stream && endStream)\n          stream.end();\n\n        if (canUseCache && res.statusCode === StatusCodes.NOT_MODIFIED)\n          readFile(cachePath, { encoding: encoding === 'binary' ? null : encoding })\n            .then((content: any) => {\n              fromCache = true;\n              reportAndResolve(content);\n            }).catch(/* istanbul ignore next: unreached sanity check */ (err: any) => reject_(err));\n        else\n          reject_(res.statusCode);\n      }\n    }).once('error', /* istanbul ignore next: unreached sanity check */ err => reject_(err));\n\n    req.once('timeout', () => {\n      req.abort();\n      reject_(`HTTP timeout after ${Math.round(processMillis() - startTime)} msec`);\n    });\n\n    if (body) {\n      req.write(isString(body) ? Buffer.from(body, charset) : body, err => {\n        /* istanbul ignore next: unreached sanity check */\n        if (err)\n          reject_(err);\n        else\n          req.end();\n      });\n    }\n    else\n      req.end();\n  });\n}\n\nfunction isBinary(contentType: string): boolean {\n  let $: string[];\n\n  if (/;\\s*charset\\s*=/i.test(contentType))\n    return false;\n\n  // Remove anything other than MIME type.\n  contentType = contentType.replace(/;.*$/, '').trim();\n\n  if (/^text\\//i.test(contentType) || /\\+xml$/i.test(contentType))\n    return false;\n  else if (($ = /^application\\/(.+)/i.exec(contentType)))\n    return !/^(javascript|ecmascript|json|ld\\+json|rtf)$/i.test($[1]);\n  else\n    return true;\n}\n\nfunction checkBOM(buffer: Buffer): string {\n  if (!buffer || buffer.length < 2)\n    return null;\n\n  const bom = Array.from(buffer.subarray(0, Math.min(buffer.length, 4)));\n\n  if (bom[0] === 0x00 && bom[1] === 0x00 && bom[2] === 0xFE && bom[3] === 0xFF)\n    return 'utf-32be';\n  else if (bom[0] === 0xFF && bom[1] === 0xFE && bom[2] === 0x00 && bom[3] === 0x00)\n    return 'utf-32le';\n  else if (bom[0] === 0xFE && bom[1] === 0xFF)\n    return 'utf-16be';\n  else if (bom[0] === 0xFF && bom[1] === 0xFE)\n    return 'utf-16le';\n  else if (bom[0] === 0xEF && bom[1] === 0xBB && bom[2] === 0xBF)\n    return 'utf8';\n  else if (bom[0] === 0x2B && bom[1] === 0x2F && bom[2] === 0x76 &&\n           (bom[3] === 0x2B || bom[3] === 0x2F || bom[3] === 0x38 || bom[3] === 0x39)) {\n    buffer[3] = 0x38;\n    return 'utf7';\n  }\n\n  return null;\n}\n\nfunction lookForEmbeddedEncoding(buffer: Buffer): string {\n  // First make sure this isn't likely to be a 16- or 32-bit encoding.\n  const start = Array.from(buffer.subarray(0, Math.min(buffer.length, 4)));\n\n  if (start[0] === 0 && start[1] === 0 && (start[2] !== 0 || start[3] !== 0))\n    return 'utf-32be';\n  else if ((start[0] !== 0 || start[1] !== 0) && start[2] === 0 && start[3] === 0)\n    return 'utf-32le';\n  else if (start[0] === 0 && start[1] !== 0)\n    return 'utf-16be';\n  else if (start[0] !== 0 && start[1] === 0)\n    return 'utf-16le';\n\n  const text = buffer.subarray(0, Math.min(buffer.length, MAX_EXAMINE)).toString('ascii').toLowerCase().replace('\\n', ' ').trim();\n  // Strip line breaks and comments first\n  const tagText = text.replace(/\\n+/g, ' ').replace(/<!--.*?-->/g, '').trim();\n  // Break into tags\n  const tags = tagText.replace(/[^<]*(<[^>]*>)[^<]*/g, '$1\\n').split('\\n').filter(tag => !/^<\\//u.test(tag));\n  let $: string[];\n\n  for (const tag of tags) {\n    if (/^<\\?xml\\b/.test(tag) && ($ = /\\bencoding\\s*=\\s*['\"]\\s*([\\w-]+)\\b/.exec(tag)))\n      return $[1];\n    else if (/^<meta\\b/.test(tag) && ($ = /\\bcharset\\s*=\\s*['\"]?\\s*([\\w-]+)\\b/.exec(tag)))\n      return $[1];\n  }\n\n  // CSS charset must come right at the beginning of a file, so no need to worry about comments confusing the issue.\n  if (($ = /@charset\\s+['\"]\\s*([\\w-]+)\\b/.exec(text)))\n    return $[1];\n\n  return null;\n}\n","import { ExtendedRequestOptions, request } from './by-request';\nimport { isString } from '@tubular/util';\n\nexport function requestBinary(urlOrOptions: string | ExtendedRequestOptions,\n                              options?: ExtendedRequestOptions): Promise<Buffer> {\n  if (urlOrOptions && !isString(urlOrOptions))\n    delete urlOrOptions.stream;\n\n  if (options)\n    delete options.stream;\n\n  return request(urlOrOptions as any, options, 'binary') as Promise<Buffer>;\n}\n","import { ExtendedRequestOptions, request, safeLstat } from './by-request';\nimport { createWriteStream, rename as _rename, unlink as _unlink } from 'fs';\nimport { Writable } from 'stream';\nimport { promisify } from 'util';\nimport { isString, noop } from '@tubular/util';\nimport { parse as parseUrl } from 'url';\n\nconst unlink = promisify(_unlink);\nconst rename = promisify(_rename);\n\nexport async function requestFile(urlOrOptions: string | ExtendedRequestOptions,\n                                  optionsOrPathOrStream?: ExtendedRequestOptions | string | Writable,\n                                  pathOrStream?: string | Writable): Promise<number> {\n  // Stream should only be specified directly as a function argument, not as an option within an argument.\n  if (urlOrOptions && !isString(urlOrOptions))\n    delete urlOrOptions.stream;\n\n  if (optionsOrPathOrStream && !isString(optionsOrPathOrStream) && !(optionsOrPathOrStream as any).write)\n    delete (optionsOrPathOrStream as any).stream;\n\n  let url: string;\n  let options: ExtendedRequestOptions;\n  let path: string;\n  let stream: Writable;\n\n  if (isString(pathOrStream))\n    path = pathOrStream;\n  else if (pathOrStream)\n    stream = pathOrStream;\n\n  if (!path && isString(optionsOrPathOrStream))\n    path = optionsOrPathOrStream;\n  else if (!stream && optionsOrPathOrStream && (optionsOrPathOrStream as any).write && (optionsOrPathOrStream as any).end)\n    stream = optionsOrPathOrStream as Writable;\n  else if (optionsOrPathOrStream)\n    options = optionsOrPathOrStream as ExtendedRequestOptions;\n\n  if (isString(urlOrOptions))\n    url = urlOrOptions;\n  else if (!options)\n    options = urlOrOptions;\n\n  if (!options)\n    options = {};\n\n  const urlPath = url ? parseUrl(url).path : options.path;\n  const urlFile = (urlPath || '').replace(/\\/$/, '').replace(/(?<!:).*\\/+/, '');\n  const pathIsDirectory = path && /\\/$/.test(path);\n\n  if (pathIsDirectory)\n    path += urlFile;\n  else if (!path)\n    path = urlFile;\n\n  if (!path && !stream)\n    throw new Error('A Writable stream, a file path, or a URL from which a file name can be extracted must be provided.');\n\n  let outPath = path;\n  let fromCache = false;\n\n  if (!stream && options.cachePath === path) {\n    let index = 0;\n\n    do {\n      outPath = `${path}.${index++}`;\n    } while (await safeLstat(outPath));\n\n    const responseCallback = options.responseInfo;\n\n    options.responseInfo = info => {\n      fromCache = info.fromCache;\n\n      if (responseCallback)\n        responseCallback(info);\n    };\n  }\n\n  if (!stream) {\n    stream = createWriteStream(outPath);\n    options.streamCreated = true;\n\n    await new Promise<void>((resolve, reject) => {\n      stream.on('open', () => resolve());\n      stream.on('error', error => reject(error));\n    });\n  }\n\n  options.stream = stream;\n\n  const length = await request(url || options, url ? options : undefined, 'binary') as unknown as Promise<number>;\n\n  if (fromCache) {\n    // eslint-disable-next-line @typescript-eslint/await-thenable,@typescript-eslint/unbound-method\n    await promisify(stream.end);\n    await unlink(outPath).catch(noop);\n  }\n  else if (outPath !== path) {\n    await unlink(path).catch(noop);\n    await rename(outPath, path);\n  }\n\n  return length;\n}\n\nexport const wget = requestFile;\n","import { ExtendedRequestOptions, request } from './by-request';\nimport { isString } from '@tubular/util';\n\nexport async function requestText(urlOrOptions: string | ExtendedRequestOptions, encoding?: string): Promise<string>;\nexport async function requestText(url: string, options: ExtendedRequestOptions, encoding?: string): Promise<string>;\nexport async function requestText(urlOrOptions: string | ExtendedRequestOptions,\n                                  optionsOrEncoding?: ExtendedRequestOptions | string, encoding?: string): Promise<string> {\n  if (encoding == null && isString(optionsOrEncoding)) {\n    encoding = optionsOrEncoding;\n    optionsOrEncoding = undefined;\n  }\n\n  if (encoding === 'binary')\n    throw Error('Binary encoding not permitted. Please use requestBinary.');\n\n  if (urlOrOptions && !isString(urlOrOptions))\n    delete urlOrOptions.stream;\n\n  if (optionsOrEncoding && !isString(optionsOrEncoding))\n    delete optionsOrEncoding.stream;\n\n  return await request(urlOrOptions as any, optionsOrEncoding as any, encoding || 'utf-8') as string;\n}\n","import { ExtendedRequestOptions, ResponseInfo } from './by-request';\nimport { requestText } from './request-text';\nimport { isString } from '@tubular/util';\n\nexport async function requestJson(urlOrOptions: string | ExtendedRequestOptions,\n                                  options?: ExtendedRequestOptions): Promise<any> {\n  if (urlOrOptions && !isString(urlOrOptions))\n    delete urlOrOptions.stream;\n\n  if (options)\n    delete options.stream;\n\n  const actualOptions = (options || (isString(urlOrOptions) ? null : urlOrOptions));\n  const savedInfoCallback = actualOptions && actualOptions.responseInfo;\n  let responseInfo: ResponseInfo = null;\n\n  if (savedInfoCallback)\n    actualOptions.responseInfo = info => responseInfo = info;\n\n  let text = await requestText(urlOrOptions as any, options, 'utf8');\n  let json: any;\n  let parsed = false;\n  let callback: string = null;\n\n  if (!text.startsWith('/*')) {\n    try {\n      json = JSON.parse(text);\n      parsed = true;\n    }\n    catch {}\n  }\n\n  if (!parsed) {\n    // Maybe this is JSONP? First, remove any leading comment.\n    text = text.replace(/\\/\\*.*\\*\\/\\s*(?=.*\\()/, '');\n    // Look for callback\n    const $ = /.*?([A-Za-z$_][0-9A-Za-z$_.]*)\\s*\\(([^]*)\\)/u.exec(text);\n\n    if ($) {\n      callback = $[1];\n      text = $[2].trim();\n\n      try {\n        json = JSON.parse(text);\n        parsed = true;\n      }\n      catch {}\n    }\n  }\n\n  if (!parsed)\n    throw new Error('Valid JSON not found');\n\n  if (savedInfoCallback) {\n    if (callback)\n      responseInfo.callback = callback;\n\n    savedInfoCallback(responseInfo);\n  }\n\n  return json;\n}\n"],"names":["temp","track","async","safeLstat","path","opts","lstat","_a","ensureDirectory","parent","pathUtil","dirname","mkdir","recursive","getCaseInsensitiveProperty","obj","key","toLowerCase","k","Object","keys","isString","checkedGzipShell","hasGzipShell","request","urlOrOptions","optionsOrEncoding","anEncoding","options","body","cachePath","encoding","fromCache","parseUrl","replace","assign","clone","protocol","endsWith","_b","startsWith","headers","forceEncoding","method","params","json","contentType","hadContentType","charset","_d","_c","exec","urlEncodeParams","JSON","stringify","test","_e","isDirectory","url","hostname","host","port","base","suffix","$","makePlainASCII","substring","join","checksum53","toString","https","http","stream","startTime","processMillis","gzipProc","spawn","Promise","resolve","once","stdout","canUseCache","stats","maxCacheAge","mtimeMs","Date","now","contents","readFile","responseInfo","_f","mtime","toUTCString","reject","reject_","err","Error","code","toNumber","getReasonPhrase","makeError","endStream","streamCreated","dontEndStream","process","stderr","reportAndResolve","content","req","res","getHeader","hdr","statusCode","source","postDecompress","contentEncoding","contentLength","parseInt","isNaN","undefined","binary","trim","isBinary","iconv","encodingExists","usingIconv","autodetect","bytesRead","bomDetected","removeBom","dontDecompress","autoDecompress","zlib","createGunzip","windowBits","pipe","createInflateRaw","createBrotliDecompress","StatusCodes","UNSUPPORTED_MEDIA_TYPE","error","end","on","data","length","progress","Buffer","alloc","ignoreBom","bomCharset","buffer","bom","Array","from","subarray","Math","min","checkBOM","keepBom","embeddedEncoding","start","text","tags","split","filter","tag","lookForEmbeddedEncoding","write","concat","wrapUp","bomRemoved","then","writeFile","finally","decode","stripBOM","charCodeAt","open","file","fs","fd","close","decompressed","d","unlink","NOT_MODIFIED","catch","abort","round","requestBinary","promisify","_unlink","rename","_rename","requestFile","optionsOrPathOrStream","pathOrStream","urlFile","outPath","index","responseCallback","info","createWriteStream","noop","wget","requestText","requestJson","actualOptions","savedInfoCallback","parsed","callback","parse"],"mappings":";8GAiCAA,EAAKC,QAyCEC,eAAeC,EAAUC,EAAcC,GAC5C,IACE,aAAaC,EAAMF,EAAMC,GAE3B,MAAAE,GACE,OAAO,KAEX,CAEAL,eAAeM,EAAgBJ,GAC7B,MAAMK,EAASC,EAASC,QAAQP,GAE5BK,SACIG,EAAMH,EAAQ,CAAEI,WAAW,GACrC,CAEA,SAASC,EAA2BC,EAAUC,GAC5CA,EAAMA,EAAIC,cAEV,IAAK,MAAMC,KAAKC,OAAOC,KAAKL,GAA0D,CAAA,GACpF,GAAIM,EAASH,IAAMA,EAAED,gBAAkBD,EACrC,OAAOD,EAAIG,EAIjB,CAqBA,IAAII,GAAmB,EACnBC,GAAe,EAEZrB,eAAesB,EAAQC,EACPC,EAAqDC,iBAC1E,IAAIC,EACAC,EACAC,EACAC,EAAWJ,EACXK,GAAY,EAEZX,EAASI,KACXG,EAAUK,EAASR;AAEjBJ,EAASK,GACXK,EAAYL,EAAkBQ,QAAQ,WAAY,SAC3CR,EAEHE,EACFT,OAAOgB,OAAOP,EAASF,GAEvBE,EAAUQ,EAAMV,GAEVE,IACRA,EAAUH,IAGS,QAAhBlB,EAAAqB,EAAQS,gBAAQ,IAAA9B,OAAA,EAAAA,EAAE+B,SAAS,QAC9BV,EAAQS,UAAY,MAGL,QAAZE,EAAAX,EAAQxB,YAAI,IAAAmC,OAAA,EAAAA,EAAEC,WAAW,QAC5BZ,EAAQxB,KAAO,KAAOwB,EAAQxB,MAAQ,KAEnCwB,EAAQa,QAEH3B,EAA2Bc,EAAQa,QAAS,qBACnDb,EAAQa,QAAgB,mBAAqB,mBAF9Cb,EAAQa,QAAU,CAAE,kBAAmB,mBAIzC,IAAIC,EAAgBd,EAAQc,cAEvBX,IACHA,EAAW,OAEXW,GAAgB,GAGlBd,EAAQe,OAASf,EAAQe,SAAWf,EAAQC,MAAQD,EAAQgB,QAAUhB,EAAQiB,KAAO,OAAS,OAE9F,IAAIC,EAAchC,EAA2Bc,EAAQa,QAAS;CAC9D,MAAMM,IAAmBD,EACnBE,GAA0E,QAA/DC,GAAqD,QAApDC,EAAA,6BAA6BC,KAAKL,GAAe,WAAG,IAAAI,EAAAA,EAAI,IAAI,UAAE,IAAAD,EAAAA,EAAI,QAAQhC,cA0B5F,GAxBK6B,EAeHjB,EAAOD,EAAQC,KAdXD,EAAQgB,QACVf,EAAOR,EAASO,EAAQgB,QAAUhB,EAAQgB,OAASQ,EAAgBxB,EAAQgB,QAC3EE,EAAcA,GAAe,oDAEtBlB,EAAQiB,MACfhB,EAAOR,EAASO,EAAQiB,MAAQjB,EAAQiB,KAAOQ,KAAKC,UAAU1B,EAAQiB,MACtEC,EAAcA,GAAe,mCAEtBlB,EAAQC,OACfA,EAAOD,EAAQC,KACfiB,EAAcA,GAAe,8BAM5BC,GAAkBD,IACpBlB,EAAQa,QAAgB,gBAAkBK,UAEtClB,EAAQC,YACRD,EAAQiB,YACRjB,EAAQgB,OAEXhB,EAAQE,YACVA,EAAYF,EAAQE;OACbF,EAAQE,UAEX,SAASyB,KAAKzB,KAA0C,gBAArB3B,EAAU2B,UAAW,IAAA0B,OAAA,EAAAA,EAAEC,gBAAe,CAC3E,MAAMC,EAAMrC,EAASI,GAAgBA,EACnCG,EAAQS,UAAYT,EAAQ+B,UAAY/B,EAAQgC,OAC/ChC,EAAQiC,KAAO,IAAMjC,EAAQiC,KAA0D,IAAMjC,EAAQxB,KACxG,IAAI0D,EAAO,GACPC,EAAS,GACTC,EAAI,gBAAgBb,KAAKvB,EAAQxB,MAEjC4D,IACFF,EAAOG,EAAeD,EAAE,IAAI,GAAM9B,QAAQ,KAAM,KAAKA,QAAQ,aAAc,QAEtE8B,EAAI,eAAeb,KAAKW,KAC3BA,EAAOE,EAAE,GAAGE,UAAU,EAAG,IAAM,IAC/BH,EAASC,EAAE,GAAGE,UAAU,EAAG,IAG3BJ,EAAOA,EAAKI,UAAU,EAAG,IAAM,KAGnCpC,EAAYpB,EAASyD,KAAKrC,EAAWgC,EAAOM,EAAWV,GAAO7B,EAAOA,EAAKwC,WAAa,KAAON,GAIlG,MAAM1B,EAAiC,WAArBT,EAAQS,SAAwBiC,EAAQC,EACpDC,EAAS5C,EAAQ4C,OACjBC,EAAYC,IAElB,IAAKpD,EAAkB,CACrBA,GAAmB,EACnBC,GAAe;CAEf,MAAMoD,EAAWC,EAAM,OAAQ,CAAC,aAE1B,IAAIC,QAAcC,IACtBH,EAASI,KAAK,QAA4D,KAAQxD,GAAe,EAAOuD,MACxGH,EAASK,OAAOD,KAAK,MAAOD,KAIhC,IAAIG,GAAc,EAElB,GAAInD,EAAW,CACb,MAAMoD,QAAc/E,EAAU2B,GAE9B,GAAIoD,KAAWtD,EAAQuD,aAAeD,EAAME,QAAUC,KAAKC,MAAQ1D,EAAQuD,aAAc,CACvF,GAAIvD,EAAQuD,YACV,IACE,MAAMI,QAAiBC,EAAS1D,EAAW,CAAEC,SAAuB,WAAbA,EAAwB,KAAOA,IAKtF,OAHIH,EAAQ6D,cACV7D,EAAQ6D,aAAa,CAAE3D,YAAWE,WAAW,IAExCuD,EAET,MAAAG,GAAM,CAGRT,GAAc,EAETnE,EAA2Bc,EAAQa,QAAS,uBAC/Cb,EAAQa,QAAUtB,OAAOgB,OAAOP,EAAQa,QAAS,CAAE,oBAAqByC,EAAMS,MAAMC,kBAM1F,cAFOhE,EAAQuD;AAER,IAAIN,QAAkC,CAACC,EAASe,KACrD,MAAMC,EAAWC,GAAaF,EAvKlC,SAAmBE,GAEjB,GAAIA,aAAeC,MACjB,OAAOD,EAET,MAAME,EAAOC,EAASH,GAEtB,GAAIE,GAAQ,IACV,IACE,OAAO,IAAID,MAAM,SAASC,MAASE,EAAgBF,MAErD,MAAA1F,GACE,OAAO,IAAIyF,MAAM,4BAA4BC,KAIjD,OAAO,IAAID,MAAMD,EAAI1B,WACvB,CAsJyC+B,CAAUL,IACzCM,GAAczE,EAAQ0E,gBAA2C,IAA1B1E,EAAQ2E,gBAA4B3E,EAAQ2E,gBACpE/B,IAAWgC,QAAQxB,QAAUR,IAAWgC,QAAQC,OAC/DC,EAAoBC,IACpB/E,EAAQ6D,cACV7D,EAAQ6D,aAAa,CAAE3D,YAAWE,cAEpC8C,EAAQ6B,IAEJC,EAAMvE,EAASb,QAAQI,EAAgBiF,IAC3C,SAASC,EAAUC,GAAe,OAAQF,EAAIpE,QAAQsE,IAAQ,IAAI1C,WAAWpD,aAAc;AAE3F,GAAI,KAAO4F,EAAIG,YAAcH,EAAIG,WAAa,IAAK,CACjD,IAAIC,EAASJ,EACTK,GAAiB,EACrB,MAAMC,EAAkBL,EAAU,oBAC5BhE,EAAcgE,EAAU,gBAC9B,IAAIM,EAAgBC,SAASP,EAAU,kBAAmB,IAC1DM,EAAiBE,MAAMF,QAAiBG,EAAYH,EACpD,MAAMI,EAAuB,WAAbzF,KAA2BH,EAAQ4C,QAoQ3D,SAAkB1B,GAChB,IAAIkB,EAEJ,GAAI,mBAAmBT,KAAKT,GAC1B,OAAO,EAKT,OAFAA,EAAcA,EAAYZ,QAAQ,OAAQ,IAAIuF,QAE1C,WAAWlE,KAAKT,KAAgB,UAAUS,KAAKT,OAEzCkB,EAAI,sBAAsBb,KAAKL,MAC/B,+CAA+CS,KAAKS,EAAE,IAGlE,CAlRW0D,CAAS5E,MAAkBf,IAAa4F,EAAMC,eAAe7F,IAChE,IACIiB,EADA6E,GAAa,EAEbC,GAAcpF,IAAkB8E,EAChCO,EAAY,EACZC,GAAc,EACdC,GAAY;CAEhB,IAAKrG,EAAQsG,iBAAmBV,EAC9B,GAAwB,WAApBL,GAAgC5F,EAGlC2F,GAAiB,OACd,GAAwB,SAApBC,GAAkD,WAApBA,GAClCvF,EAAQuG,gBAAkB,4BAA4B5E,KAAKT,GAC9DmE,EAASmB,EAAKC,aAAa,CAAEC,WAAY,KACzCzB,EAAI0B,KAAKtB,QAEN,GAAwB,YAApBE,GAAkCvF,EAAQuG,gBAAkB,cAAc5E,KAAKT,GACtFmE,EAASmB,EAAKI,mBACd3B,EAAI0B,KAAKtB,QAEN,GAAwB,OAApBE,EACPF,EAASmB,EAAKK,yBACd5B,EAAI0B,KAAKtB,QAEN,GAAIE,GAAuC,aAApBA,EAE1B,YADArB,EAAQ4C,EAAYC,wBAqBxB,GAhBI9B,IAAQI,IACVJ,EAAI9B,KAAK,QAA4D6D,IAC/DpE,GAAU6B,GACZ7B,EAAOqE,MAET/C,EAAQ8C,KAGV/B,EAAIiC,GAAG,OAASC,IACdhB,GAAagB,EAAKC,OAEdpH,EAAQqH,UACVrH,EAAQqH,SAASlB,EAAWX;CAI7BI,EAAQ,CACX,GAAI9E,EACFM,EAAUjB,MACP,CACH,MAAMiC,EAAI,qCAAqCb,KAAKL,GAEhDkB,EACFhB,EAAUgB,EAAE,GAAG9B,QAAQ,WAAY,UAEnCc,EAAUjB,EACV+F,GAAa,GAIjB,IAAK,sDAAsDvE,KAAKP,GAAU,CACxE,IAAK2E,EAAMC,eAAe5E,GAExB,YADA8C,EAAQ4C,EAAYC,wBAItBd,GAAa,GAIjB,IAAIlB,EAAUuC,OAAOC,MAAM,GAE3BlC,EAAOlC,KAAK,QAA6D6D,IACnEpE,GAAU6B,GACZ7B,EAAOqE,MAET/C,EAAQ8C,KAGV3B,EAAO6B,GAAG,OAASC,IAQjB,GAPIlC,IAAQI,IACVc,GAAagB,EAAKC,OAEdpH,EAAQqH,UACVrH,EAAQqH,SAASlB,EAAWX,IAGT,IAAnBT,EAAQqC,SAAiBxB,IAAW5F,EAAQwH,UAAW,CACzD,MAAMC,EA0LlB,SAAkBC,GAChB,IAAKA,GAAUA,EAAON,OAAS,EAC7B,OAAO;CAET,MAAMO,EAAMC,MAAMC,KAAKH,EAAOI,SAAS,EAAGC,KAAKC,IAAIN,EAAON,OAAQ,KAElE,GAAe,IAAXO,EAAI,IAA0B,IAAXA,EAAI,IAA0B,MAAXA,EAAI,IAA0B,MAAXA,EAAI,GAC/D,MAAO,WACJ,GAAe,MAAXA,EAAI,IAA0B,MAAXA,EAAI,IAA0B,IAAXA,EAAI,IAA0B,IAAXA,EAAI,GACpE,MAAO,WACJ,GAAe,MAAXA,EAAI,IAA0B,MAAXA,EAAI,GAC9B,MAAO,WACJ,GAAe,MAAXA,EAAI,IAA0B,MAAXA,EAAI,GAC9B,MAAO,WACJ,GAAe,MAAXA,EAAI,IAA0B,MAAXA,EAAI,IAA0B,MAAXA,EAAI,GACjD,MAAO,OACJ,GAAe,KAAXA,EAAI,IAA0B,KAAXA,EAAI,IAA0B,MAAXA,EAAI,KAC9B,KAAXA,EAAI,IAA0B,KAAXA,EAAI,IAA0B,KAAXA,EAAI,IAA0B,KAAXA,EAAI,IAErE,OADAD,EAAO,GAAK,GACL,OAGT,OAAO,IACT,CAjN+BO,CAASd,GAE5B,GAAIM,EAAY,CACd,IAAK3G,EAAe;AAElB,IAAKiF,EAAMC,eAAeyB,GAExB,YADAvD,EAAQ4C,EAAYC,wBAItB3F,EAAUqG,EACVxB,EAA6B,SAAfwB,EACdvB,GAAa,EAGfE,GAAc,EAETpG,EAAQkI,UACX7B,GAAY,IAIlB,GAAIH,GAAiC,IAAnBnB,EAAQqC,OAAc,CACtC,MAAMe,EA4LlB,SAAiCT,GAE/B,MAAMU,EAAQR,MAAMC,KAAKH,EAAOI,SAAS,EAAGC,KAAKC,IAAIN,EAAON,OAAQ,KAEpE,GAAiB,IAAbgB,EAAM,IAAyB,IAAbA,EAAM,KAA0B,IAAbA,EAAM,IAAyB,IAAbA,EAAM,IAC/D,MAAO,WACJ,IAAkB,IAAbA,EAAM,IAAyB,IAAbA,EAAM,KAA0B,IAAbA,EAAM,IAAyB,IAAbA,EAAM,GACrE,MAAO,WACJ,GAAiB,IAAbA,EAAM,IAAyB,IAAbA,EAAM,GAC/B,MAAO,WACJ,GAAiB,IAAbA,EAAM,IAAyB,IAAbA,EAAM,GAC/B,MAAO;CAET,MAAMC,EAAOX,EAAOI,SAAS,EAAGC,KAAKC,IAAIN,EAAON,OAvjB9B,OAujBoD3E,SAAS,SAASpD,cAAciB,QAAQ,KAAM,KAAKuF,OAInHyC,EAFUD,EAAK/H,QAAQ,OAAQ,KAAKA,QAAQ,cAAe,IAAIuF,OAEhDvF,QAAQ,uBAAwB,QAAQiI,MAAM,MAAMC,OAAOC,IAAQ,QAAQ9G,KAAK8G,IACrG,IAAIrG,EAEJ,IAAK,MAAMqG,KAAOH,EAAM,CACtB,GAAI,YAAY3G,KAAK8G,KAASrG,EAAI,qCAAqCb,KAAKkH,IAC1E,OAAOrG,EAAE,GACN,GAAI,WAAWT,KAAK8G,KAASrG,EAAI,qCAAqCb,KAAKkH,IAC9E,OAAOrG,EAAE,GAIb,OAAKA,EAAI,+BAA+Bb,KAAK8G,IACpCjG,EAAE,GAEJ,IACT,CA5NqCsG,CAAwBvB,GAEjD,GAAIgB,EAAkB;AACpB,IAAKpC,EAAMC,eAAemC,GAExB,YADAjE,EAAQ4C,EAAYC,wBAItB3F,EAAU+G,EACVlC,GAAa,EACbC,GAAa,GAIbtD,EACFA,EAAO+F,MAAMxB,EAAMH,IAEbA,IACFpE,EAAOqE,MACP/C,EAAQ8C,MAKZjC,EAAUuC,OAAOsB,OAAO,CAAC7D,EAASoC,GAAOpC,EAAQqC,OAASD,EAAKC,UAGnE/B,EAAOlC,KAAK,MAAO,KACjB,MAAM0F,EAAS,KAkBb,GAjBI7I,EAAQqH,eAA8B1B,IAAlBH,GACtBxF,EAAQqH,SAASlB,EAAWA,GAE1BnG,EAAQ6D,cACV7D,EAAQ6D,aAAa,CACnBuC,cACA0C,WAAYzC,EACZnG,YACAkB,QAASwE,EAAS,SAAWxE,EAC7BmE,gBAAiBA,GAAmB,WACpCC,cAAeW,EACfjF,cACAd,YACAwC,WAIAA,EACE6B,GACF7B,EAAOqE,MAET/D,EAAQiD,QAEL,GAAIP,EACH1F,EACFtB,EAAgBsB,GAAW6I,KAAK,IAAMC,EAAU9I,EAAW6E,GAASkE,QAAQ,IAAMnE,EAAiBC,KAEnG7B,EAAQ6B,OAEP,CACH,IAAIsD,EAGFA,EADEpC,EACKF,EAAMmD,OAAOnE,EAAS3D,EAAS;AAAE+H,UAAU,IAE3CpE,EAAQtC,SAASrB,GAEtBiF,GAAoC,QAAvBgC,EAAKe,WAAW,KAC/Bf,EAAOA,EAAK/F,UAAU,IAEpBpC,EACFtB,EAAgBsB,GAAW6I,KAAK,IAAMC,EAAU9I,EAAWmI,EAAM,CAAElI,aAAY8I,QAAQ,IAAMnE,EAAiBuD,KAE9GnF,EAAQmF,KAIV/C,EAKFlH,EAAKiL,KAAK,cAAe,CAAClF,EAAKmF,KAEzBnF,EACFD,EAAQC,IAERoF,EAAGZ,MAAMW,EAAKE,GAAIzE,EAASZ,GAAOA,GAAOD,EAAQC,IACjDoF,EAAGE,MAAMH,EAAKE,GAAIrF,IAEhB,GAAIA,EACFD,EAAQC,OACL,CACH,MAAMpB,EAAWC,EAAM,OAAQ,CAAC,MAAOsG,EAAK9K,OAC5C,IAAIkL,EAAepC,OAAOC,MAAM,GAEhCxE,EAASK,OAAO8D,GAAG,OAAQyC,GAAKD,EAAepC,OAAOsB,OAAO,CAACc,EAAcC,GAAID,EAAatC,OAASuC,EAAEvC,SACxGrE,EAASK,OAAO8D,GAAG,QAAS/C,GAAOD,EAAQC,IAC3CpB,EAASK,OAAO8D,GAAG,MAAO,KACxBnC,EAAU2E,EACVvD,EAAYpB,EAAQqC,OACpBmC,EAAGK,OAAON,EAAK9K,KAAM,QACrBqK,YAQVA,WAIAjG,GAAU6B,GACZ7B,EAAOqE;AAEL5D,GAAe4B,EAAIG,aAAe0B,EAAY+C,aAChDjG,EAAS1D,EAAW,CAAEC,SAAuB,WAAbA,EAAwB,KAAOA,IAC5D4I,KAAMhE,IACL3E,GAAY,EACZ0E,EAAiBC,KAChB+E,MAA0D3F,GAAaD,EAAQC,IAEpFD,EAAQe,EAAIG,cAEfjC,KAAK,QAA4DgB,GAAOD,EAAQC,IAEnFa,EAAI7B,KAAK,UAAW,KAClB6B,EAAI+E,QACJ7F,EAAQ,sBAAsB6D,KAAKiC,MAAMlH,IAAkBD,aAGzD5C,EACF+E,EAAI2D,MAAMlJ,EAASQ,GAAQqH,OAAOO,KAAK5H,EAAMmB,GAAWnB,EAAMkE,IAExDA,EACFD,EAAQC,GAERa,EAAIiC,QAIRjC,EAAIiC,OAEV,CC9hBM,SAAUgD,EAAcpK,EACAG,GAO5B,OANIH,IAAiBJ,EAASI,WACrBA,EAAa+C,OAElB5C,UACKA,EAAQ4C,OAEVhD,EAAQC,EAAqBG,EAAS,SAC/C,CCLA,MAAM4J,EAASM,EAAUC,GACnBC,EAASF,EAAUG,GAElB/L,eAAegM,EAAYzK,EACA0K,EACAC,GAQhC,IAAI1I,EACA9B,EACAxB,EACAoE,EATA/C,IAAiBJ,EAASI,WACrBA,EAAa+C,QAElB2H,GAA0B9K,EAAS8K,IAA4BA,EAA8B5B,cACvF4B,EAA8B3H;AAOpCnD,EAAS+K,GACXhM,EAAOgM,EACAA,IACP5H,EAAS4H,IAENhM,GAAQiB,EAAS8K,GACpB/L,EAAO+L,GACC3H,GAAU2H,GAA0BA,EAA8B5B,OAAU4B,EAA8BtD,IAClHrE,EAAS2H,EACFA,IACPvK,EAAUuK,GAER9K,EAASI,GACXiC,EAAMjC,EACEG,IACRA,EAAUH,GAEPG,IACHA,EAAU,CAAA,GAEZ,MACMyK,IADU3I,EAAMzB,EAASyB,GAAKtD,KAAOwB,EAAQxB,OACvB,IAAI8B,QAAQ,MAAO,IAAIA,QAAQ,cAAe,IAQ1E,GAPwB9B,GAAQ,MAAMmD,KAAKnD,GAGzCA,GAAQiM,EACAjM,IACRA,EAAOiM,IAEJjM,IAASoE,EACZ,MAAM,IAAIwB,MAAM,sGAElB,IAAIsG,EAAUlM,EACV4B,GAAY,EAEhB,IAAKwC,GAAU5C,EAAQE,YAAc1B,EAAM,CACzC,IAAImM,EAAQ,EAEZ,GACED,EAAU,GAAGlM,KAAQmM,kBACRpM,EAAUmM,IAEzB,MAAME,EAAmB5K,EAAQ6D,aAEjC7D,EAAQ6D,aAAegH,IACrBzK,EAAYyK,EAAKzK,UAEbwK,GACFA,EAAiBC,IAIlBjI,IACHA,EAASkI,EAAkBJ,GAC3B1K,EAAQ0E,eAAgB;MAElB,IAAIzB,QAAc,CAACC,EAASe,KAChCrB,EAAOsE,GAAG,OAAQ,IAAMhE,KACxBN,EAAOsE,GAAG,QAASF,GAAS/C,EAAO+C,OAIvChH,EAAQ4C,OAASA,EAEjB,MAAMwE,QAAexH,EAAQkC,GAAO9B,EAAS8B,EAAM9B,OAAU2F,EAAW,UAYxE,OAVIvF,SAEI8J,EAAUtH,EAAOqE,WACjB2C,EAAOc,GAASZ,MAAMiB,IAErBL,IAAYlM,UACboL,EAAOpL,GAAMsL,MAAMiB,SACnBX,EAAOM,EAASlM,IAGjB4I,CACT,CAEO,MAAM4D,EAAOV,ECnGbhM,eAAe2M,EAAYpL,EACAC,EAAqDK,GAMrF,GALgB,MAAZA,GAAoBV,EAASK,KAC/BK,EAAWL,EACXA,OAAoB6F,GAGL,WAAbxF,EACF,MAAMiE,MAAM,4DAQd,OANIvE,IAAiBJ,EAASI,WACrBA,EAAa+C,OAElB9C,IAAsBL,EAASK,WAC1BA,EAAkB8C,aAEdhD,EAAQC,EAAqBC,EAA0BK,GAAY,QAClF,CClBO7B,eAAe4M,EAAYrL,EACAG,GAC5BH,IAAiBJ,EAASI,WACrBA,EAAa+C;AAElB5C,UACKA,EAAQ4C,OAEjB,MAAMuI,EAAiBnL,IAAYP,EAASI,GAAgB,KAAOA,GAC7DuL,EAAoBD,GAAiBA,EAActH,aACzD,IAAIA,EAA6B,KAE7BuH,IACFD,EAActH,aAAegH,GAAQhH,EAAegH,GAEtD,IACI5J,EADAoH,QAAa4C,EAAYpL,EAAqBG,EAAS,QAEvDqL,GAAS,EACTC,EAAmB,KAEvB,IAAKjD,EAAKzH,WAAW,MACnB,IACEK,EAAOQ,KAAK8J,MAAMlD,GAClBgD,GAAS,EAEX,MAAA1M,GAAM,CAGR,IAAK0M,EAAQ,CAEXhD,EAAOA,EAAK/H,QAAQ,wBAAyB,IAE7C,MAAM8B,EAAI,+CAA+Cb,KAAK8G,GAE9D,GAAIjG,EAAG,CACLkJ,EAAWlJ,EAAE,GACbiG,EAAOjG,EAAE,GAAGyD,OAEZ,IACE5E,EAAOQ,KAAK8J,MAAMlD,GAClBgD,GAAS,EAEX,MAAA1K,GAAM,GAIV,IAAK0K,EACH,MAAM,IAAIjH,MAAM,wBASlB,OAPIgH,IACEE,IACFzH,EAAayH,SAAWA,GAE1BF,EAAkBvH,IAGb5C,CACT;"}