{"version":3,"file":"binaryParsers.cjs","names":["requireTemporal"],"sources":["../../src/drivers/binaryParsers.ts"],"sourcesContent":["import { requireTemporal } from \"joist-core\";\n\n/**\n * Joist's registry of PostgreSQL *binary-format* cell parsers, used by `WireRowData` for lazy\n * `em.find`/`em.load` results (which request binary output; see `executeRowDataQuery`).\n *\n * This registry is deliberately **separate from `pg.types`**: `pg.types.setTypeParser` and\n * pool/client `TypeOverrides` continue to govern classic *text* results (knex, `pool.query`,\n * non-lazy drivers), while binary cells decode wire-bytes -> values directly — ints via\n * `readInt32BE`, timestamps via µs arithmetic, Temporal values constructed without ever\n * materializing a string. There is no fallback from one registry to the other:\n *\n * - Built-in parsers cover the standard scalar/array types below; `setupLatestPgTypes`\n *   registers the date/time parsers appropriate to Date-vs-Temporal mode.\n * - Custom/extension types (native enums, citext, domains, hstore, ...) must be registered\n *   explicitly with {@link setBinaryTypeParser} — text-like types can use\n *   {@link binaryTextParser}, arrays of registered elements can use {@link binaryArrayParser}.\n * - A query selecting a column whose oid has no registered parser **fails** with a descriptive\n *   error (see `WireRowData.setRowDescription`), rather than guessing at a lossy decoding.\n *\n * Values produced here should match what the classic text path produces for the same column\n * (i.e. `numeric` stays a string, `int8` stays a string, Date-mode timestamps become `Date`s),\n * so entities hydrate identically in either mode; Temporal-mode parsers construct\n * `Temporal.PlainDate`/`ZonedDateTime`/etc. directly, and the temporal mappers pass\n * already-constructed instances through.\n */\nexport function setBinaryTypeParser(oid: number, parse: BinaryParse): void {\n  parsers.set(oid, parse);\n}\n\n/** Returns the registered binary parser for `oid`, i.e. for tests to save/restore. */\nexport function getBinaryTypeParser(oid: number): BinaryParse | undefined {\n  return parsers.get(oid);\n}\n\n/** Decodes one binary cell directly from the payload chunk; `length` is the cell's byte length. */\nexport type BinaryParse = (chunk: Buffer, start: number, length: number) => any;\n\n/**\n * Auto-registers binary parsers for the database's text-like dynamic-oid types — native enums\n * and citext, plus their array types — so apps get those for free.\n *\n * `PostgresDriver` calls this lazily before its first lazy query; apps can also call it\n * directly (i.e. at boot) if they want the registrations eagerly. Explicit\n * `setBinaryTypeParser` registrations are never overwritten.\n */\nexport async function registerDatabaseBinaryParsers(pool: {\n  query(sql: string): Promise<{ rows: any[] }>;\n}): Promise<void> {\n  // Also capture the session's TimeZone, which zones temporal-mode timestamptz loads to match\n  // what classic text parsing would have produced (pg renders timestamps in the session zone)\n  const [{ rows: settings }, { rows }] = await Promise.all([\n    pool.query(`select current_setting('TimeZone') as tz`),\n    pool.query(\n      `select t.oid, t.typarray\n       from pg_type t\n       where t.typtype = 'e'\n          or t.typname = 'citext'\n          or (t.typtype = 'd' and (select b.typcategory from pg_type b where b.oid = t.typbasetype) = 'S')`,\n    ),\n  ]);\n  setSessionTimeZone(settings[0].tz);\n  for (const row of rows) {\n    const oid = Number(row.oid);\n    if (getBinaryTypeParser(oid) === undefined) setBinaryTypeParser(oid, binaryTextParser);\n    const arrayOid = Number(row.typarray);\n    if (arrayOid !== 0 && getBinaryTypeParser(arrayOid) === undefined) {\n      setBinaryTypeParser(arrayOid, binaryArrayParser);\n    }\n  }\n}\n\n/**\n * Sets the session `TimeZone` used to zone temporal-mode `timestamptz` loads; normally captured\n * automatically by {@link registerDatabaseBinaryParsers}. One zone per process — pools with\n * differing session TimeZones are not supported by the binary path.\n */\nexport function setSessionTimeZone(timeZone: string): void {\n  sessionTimeZone = timeZone === \"Etc/UTC\" ? \"UTC\" : timeZone;\n}\n\nlet sessionTimeZone = \"UTC\";\n\n/** Decodes a cell's bytes as utf8 text, i.e. for text-like custom types (enums, citext, domains). */\nexport function binaryTextParser(chunk: Buffer, start: number, length: number): string {\n  return chunk.toString(\"utf8\", start, start + length);\n}\n\n/**\n * Decodes a binary array cell into a JS array of element values.\n *\n * The element oid is embedded in the wire format, and each element decodes through this\n * registry — so arrays of any registered type (including custom-registered oids and the\n * mode-appropriate temporal types) work without separate element wiring. Registered for the\n * standard `_type` oids below; register it for custom array oids as needed.\n */\nexport function binaryArrayParser(chunk: Buffer, start: number, length: number): any[] {\n  const nDims = chunk.readInt32BE(start);\n  if (nDims === 0) return [];\n  const elemOid = chunk.readInt32BE(start + 8);\n  const parse =\n    parsers.get(elemOid) ??\n    fail(`joist-orm: no binary type parser registered for array element oid ${elemOid}; see setBinaryTypeParser`);\n  const dims: number[] = [];\n  for (let d = 0; d < nDims; d++) dims.push(chunk.readInt32BE(start + 12 + d * 8));\n  let pos = start + 12 + nDims * 8;\n  function readDim(dim: number): any[] {\n    const values: any[] = [];\n    for (let i = 0; i < dims[dim]; i++) {\n      if (dim < nDims - 1) {\n        values.push(readDim(dim + 1));\n      } else {\n        const len = chunk.readInt32BE(pos);\n        pos += 4;\n        if (len === -1) {\n          values.push(null);\n        } else {\n          values.push(parse(chunk, pos, len));\n          pos += len;\n        }\n      }\n    }\n    return values;\n  }\n  return readDim(0);\n}\n\n/** Decodes binary `date` cells to `Date`s, matching postgres-date's text semantics; Date mode. */\nexport function binaryDateToDate(chunk: Buffer, start: number): any {\n  const days = chunk.readInt32BE(start);\n  if (days === INFINITY_DAYS) return Infinity;\n  if (days === NEG_INFINITY_DAYS) return -Infinity;\n  const [year, month, day] = civilFromDays(days + PG_EPOCH_DAYS);\n  const date = new Date(year, month - 1, day);\n  // Mirror postgres-date's fixup for years 0-99 being interpreted as 1900-1999\n  if (year < 100) date.setFullYear(year);\n  return date;\n}\n\n/** Decodes binary `timestamp` (without zone) cells to local-time `Date`s; Date mode. */\nexport function binaryTimestampToDate(chunk: Buffer, start: number): any {\n  const pgMicros = chunk.readBigInt64BE(start);\n  if (pgMicros === INFINITY_US) return Infinity;\n  if (pgMicros === NEG_INFINITY_US) return -Infinity;\n  const { days, us } = splitPgMicros(pgMicros);\n  const [year, month, day] = civilFromDays(days);\n  const seconds = Math.floor(us / 1_000_000);\n  const date = new Date(\n    year,\n    month - 1,\n    day,\n    Math.floor(seconds / 3600),\n    Math.floor((seconds / 60) % 60),\n    seconds % 60,\n    Math.floor((us % 1_000_000) / 1000),\n  );\n  if (year < 100) date.setFullYear(year);\n  return date;\n}\n\n/** Decodes binary `timestamptz` cells to `Date`s (µs floor to ms, like the text parse); Date mode. */\nexport function binaryTimestamptzToDate(chunk: Buffer, start: number): any {\n  const pgMicros = chunk.readBigInt64BE(start);\n  if (pgMicros === INFINITY_US) return Infinity;\n  if (pgMicros === NEG_INFINITY_US) return -Infinity;\n  const epochMicros = pgMicros + PG_EPOCH_US;\n  let ms = epochMicros / 1000n;\n  if (epochMicros % 1000n < 0n) ms -= 1n;\n  return new Date(Number(ms));\n}\n\n/**\n * Registers the Temporal-mode binary parsers: date/time/timestamp/timestamptz cells construct\n * `Temporal` values *directly* from the wire µs/days — no intermediate strings, no\n * `temporalMappers.fromDb` parsing (the mappers pass already-constructed instances through).\n *\n * `timestamptz` matches the text path's zoning exactly: classic parsing zones the value by the\n * offset the session's `TimeZone` rendered (normalizing `+00` to `UTC`), so we compute the\n * session zone's offset at each instant (see `setSessionTimeZone`; the configured\n * `temporal.timeZone` only governs `now`-conversions, not loads).\n */\nexport function registerTemporalBinaryParsers(): void {\n  const { Temporal: t } = requireTemporal();\n  setBinaryTypeParser(oids.DATE, (chunk, start) => {\n    const days = chunk.readInt32BE(start);\n    if (days === INFINITY_DAYS || days === NEG_INFINITY_DAYS) failTemporalInfinity(\"date\");\n    const [year, month, day] = civilFromDays(days + PG_EPOCH_DAYS);\n    return new t.PlainDate(year, month, day);\n  });\n  setBinaryTypeParser(1083 /* time */, (chunk, start) => {\n    const us = Number(chunk.readBigInt64BE(start));\n    const seconds = Math.floor(us / 1_000_000);\n    return new t.PlainTime(\n      Math.floor(seconds / 3600),\n      Math.floor((seconds / 60) % 60),\n      seconds % 60,\n      Math.floor((us % 1_000_000) / 1000),\n      us % 1000,\n    );\n  });\n  setBinaryTypeParser(oids.TIMESTAMP, (chunk, start) => {\n    const pgMicros = chunk.readBigInt64BE(start);\n    if (pgMicros === INFINITY_US || pgMicros === NEG_INFINITY_US) failTemporalInfinity(\"timestamp\");\n    const { days, us } = splitPgMicros(pgMicros);\n    const [year, month, day] = civilFromDays(days);\n    const seconds = Math.floor(us / 1_000_000);\n    return new t.PlainDateTime(\n      year,\n      month,\n      day,\n      Math.floor(seconds / 3600),\n      Math.floor((seconds / 60) % 60),\n      seconds % 60,\n      Math.floor((us % 1_000_000) / 1000),\n      us % 1000,\n    );\n  });\n  setBinaryTypeParser(oids.TIMESTAMPTZ, (chunk, start) => {\n    const pgMicros = chunk.readBigInt64BE(start);\n    if (pgMicros === INFINITY_US || pgMicros === NEG_INFINITY_US) failTemporalInfinity(\"timestamptz\");\n    const instant = t.Instant.fromEpochNanoseconds((pgMicros + PG_EPOCH_US) * 1000n);\n    if (sessionTimeZone === \"UTC\") return instant.toZonedDateTimeISO(\"UTC\");\n    // Zone by the session zone's offset at this instant, i.e. what pg's text rendering carries\n    const zoned = instant.toZonedDateTimeISO(sessionTimeZone);\n    const { offset } = zoned;\n    return offset === \"+00:00\" ? zoned.withTimeZone(\"UTC\") : zoned.withTimeZone(offset);\n  });\n}\n\n// Microseconds between the Postgres epoch (2000-01-01) and the Unix epoch (1970-01-01)\nconst PG_EPOCH_US = 946_684_800_000_000n;\nconst PG_EPOCH_DAYS = 10_957;\nconst US_PER_DAY = 86_400_000_000n;\n// The wire sentinels for `infinity` / `-infinity` timestamps and dates\nconst INFINITY_US = 0x7fffffffffffffffn;\nconst NEG_INFINITY_US = -0x8000000000000000n;\nconst INFINITY_DAYS = 0x7fffffff;\nconst NEG_INFINITY_DAYS = -0x80000000;\n\n// pg's builtin oids, inlined to avoid importing pg here (these are protocol constants)\nconst oids = {\n  BOOL: 16,\n  BYTEA: 17,\n  INT8: 20,\n  INT2: 21,\n  INT4: 23,\n  TEXT: 25,\n  OID: 26,\n  JSON: 114,\n  FLOAT4: 700,\n  FLOAT8: 701,\n  BPCHAR: 1042,\n  VARCHAR: 1043,\n  DATE: 1082,\n  TIMESTAMP: 1114,\n  TIMESTAMPTZ: 1184,\n  NUMERIC: 1700,\n  UUID: 2950,\n  JSONB: 3802,\n};\n\nconst parsers = new Map<number, BinaryParse>();\n\n// The standard scalar builtins; values match what the classic text path produces for the same\n// column, i.e. int8/numeric stay strings, bytea stays a Buffer (byte-exact, where classic pg's\n// binary handling is utf8-lossy)\nsetBinaryTypeParser(oids.BOOL, (chunk, start) => chunk[start] !== 0);\nsetBinaryTypeParser(oids.INT2, (chunk, start) => chunk.readInt16BE(start));\nsetBinaryTypeParser(oids.INT4, (chunk, start) => chunk.readInt32BE(start));\nsetBinaryTypeParser(oids.OID, (chunk, start) => chunk.readUInt32BE(start));\nsetBinaryTypeParser(oids.INT8, (chunk, start) => chunk.readBigInt64BE(start).toString());\nsetBinaryTypeParser(oids.FLOAT4, (chunk, start) => readFloat4(chunk, start));\nsetBinaryTypeParser(oids.FLOAT8, (chunk, start) => chunk.readDoubleBE(start));\nsetBinaryTypeParser(oids.TEXT, binaryTextParser);\nsetBinaryTypeParser(oids.VARCHAR, binaryTextParser);\nsetBinaryTypeParser(oids.BPCHAR, binaryTextParser);\nsetBinaryTypeParser(19 /* name */, binaryTextParser);\nsetBinaryTypeParser(oids.UUID, (chunk, start) => renderUuid(chunk, start));\nsetBinaryTypeParser(oids.BYTEA, copyBytes);\nsetBinaryTypeParser(oids.JSON, (chunk, start, length) => JSON.parse(chunk.toString(\"utf8\", start, start + length)));\n// jsonb payloads have a 1-byte version prefix before the JSON text\nsetBinaryTypeParser(oids.JSONB, (chunk, start, length) =>\n  JSON.parse(chunk.toString(\"utf8\", start + 1, start + length)),\n);\nsetBinaryTypeParser(oids.NUMERIC, renderNumeric);\nsetBinaryTypeParser(3614 /* tsvector */, renderTsVector);\nsetBinaryTypeParser(3910 /* tstzrange */, (chunk, start) =>\n  renderRange(chunk, start, (c, s) => {\n    // pg quotes finite bounds (they contain spaces) but renders infinity bounds bare\n    const text = renderTimestamp(c.readBigInt64BE(s), \"+00\");\n    return text === \"infinity\" || text === \"-infinity\" ? text : `\"${text}\"`;\n  }),\n);\n// Rendered like pg's text output, which is also what the classic text path yields (no parser)\nsetBinaryTypeParser(1083 /* time */, (chunk, start) => renderTimeOfDay(Number(chunk.readBigInt64BE(start))));\n\n// The standard `_type` array oids; elements decode through the registry (see binaryArrayParser)\nfor (const arrayOid of [\n  1000, // bool[]\n  1001, // bytea[]\n  1005, // int2[]\n  1007, // int4[]\n  1009, // text[]\n  1014, // bpchar[]\n  1015, // varchar[]\n  1016, // int8[]\n  1021, // float4[]\n  1022, // float8[]\n  1182, // date[]\n  1183, // time[]\n  1115, // timestamp[]\n  1185, // timestamptz[]\n  1231, // numeric[]\n  2951, // uuid[]\n  199, // json[]\n  3807, // jsonb[]\n  3643, // tsvector[]\n  3911, // tstzrange[]\n]) {\n  setBinaryTypeParser(arrayOid, binaryArrayParser);\n}\n\n// Default the date/time oids to Date-mode semantics; `setupLatestPgTypes` re-registers the\n// Temporal-mode parsers when the app runs with `temporal` configured\nsetBinaryTypeParser(oids.DATE, binaryDateToDate);\nsetBinaryTypeParser(oids.TIMESTAMP, binaryTimestampToDate);\nsetBinaryTypeParser(oids.TIMESTAMPTZ, binaryTimestamptzToDate);\n\n/** Splits pg timestamp µs into days-since-1970 and µs-within-day, flooring correctly pre-epoch. */\nfunction splitPgMicros(pgMicros: bigint): { days: number; us: number } {\n  const epochMicros = pgMicros + PG_EPOCH_US;\n  let days = epochMicros / US_PER_DAY;\n  let micros = epochMicros % US_PER_DAY;\n  if (micros < 0n) {\n    days -= 1n;\n    micros += US_PER_DAY;\n  }\n  return { days: Number(days), us: Number(micros) };\n}\n\n/** Fails on the ±infinity wire sentinels, which have no Temporal representation. */\nfunction failTemporalInfinity(type: string): never {\n  return fail(`joist-orm: cannot represent an 'infinity' ${type} as a Temporal value`);\n}\n\n/** Reads a float4 as its shortest round-trip decimal, matching pg's shortest text output. */\nfunction readFloat4(chunk: Buffer, start: number): number {\n  const value = chunk.readFloatBE(start);\n  if (!Number.isFinite(value)) return value;\n  // ±0 as-is: toPrecision would drop -0's sign, and === cannot tell the zeros apart\n  if (value === 0) return value;\n  // The raw float32 -> float64 widening (i.e. 0.1f -> 0.10000000149...) diverges from the text\n  // path, which parses pg's shortest repr; find the shortest decimal that round-trips instead\n  // (binary32 needs at most 9 significant decimal digits)\n  for (let precision = 1; precision <= 9; precision++) {\n    const shortest = Number(value.toPrecision(precision));\n    if (Math.fround(shortest) === value) return shortest;\n  }\n  return value;\n}\n\n/** Copies the exact cell bytes, i.e. for bytea values. */\nfunction copyBytes(chunk: Buffer, start: number, length: number): Buffer {\n  const cell = Buffer.allocUnsafe(length);\n  chunk.copy(cell, 0, start, start + length);\n  return cell;\n}\n\n/** Renders a binary uuid (16 bytes) as the canonical dashed-hex string. */\nfunction renderUuid(chunk: Buffer, start: number): string {\n  const hex = chunk.toString(\"hex\", start, start + 16);\n  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\n/** Renders a binary numeric (base-10000 digit groups) to pg's text form, i.e. `-12.340`. */\nfunction renderNumeric(chunk: Buffer, start: number): string {\n  const nDigits = chunk.readInt16BE(start);\n  const weight = chunk.readInt16BE(start + 2);\n  const sign = chunk.readUInt16BE(start + 4);\n  const dscale = chunk.readUInt16BE(start + 6);\n  if (sign === 0xc000) return \"NaN\";\n  if (sign === 0xd000) return \"Infinity\";\n  if (sign === 0xf000) return \"-Infinity\";\n  // Integer part: digit groups from `weight` down to 0 (missing groups are zero)\n  let integer = \"\";\n  for (let w = weight, i = 0; w >= 0; w--, i++) {\n    const group = i < nDigits ? chunk.readUInt16BE(start + 8 + i * 2) : 0;\n    integer += integer === \"\" ? String(group) : String(group).padStart(4, \"0\");\n  }\n  if (integer === \"\") integer = \"0\";\n  if (dscale === 0) return sign === 0x4000 ? `-${integer}` : integer;\n  // Fraction part: the group at weight -k is digits[weight + k]; pad/trim to exactly `dscale` digits\n  let fraction = \"\";\n  for (let k = 1; fraction.length < dscale; k++) {\n    const i = weight + k;\n    const group = i >= 0 && i < nDigits ? chunk.readUInt16BE(start + 8 + i * 2) : 0;\n    fraction += String(group).padStart(4, \"0\");\n  }\n  fraction = fraction.slice(0, dscale);\n  return `${sign === 0x4000 ? \"-\" : \"\"}${integer}.${fraction}`;\n}\n\n/** Renders a binary tsvector (lexeme cstrings + position/weight words) to pg's text form, i.e. `'new':2A`. */\nfunction renderTsVector(chunk: Buffer, start: number): string {\n  const count = chunk.readInt32BE(start);\n  let pos = start + 4;\n  const lexemes: string[] = [];\n  for (let i = 0; i < count; i++) {\n    const end = chunk.indexOf(0, pos);\n    // pg's output doubles both backslashes and quotes inside lexemes\n    const word = chunk.toString(\"utf8\", pos, end).replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"''\");\n    pos = end + 1;\n    const nPositions = chunk.readUInt16BE(pos);\n    pos += 2;\n    const positions: string[] = [];\n    for (let p = 0; p < nPositions; p++) {\n      // Each word entry packs the weight in the top 2 bits (3=A, 2=B, 1=C, 0=D/default)\n      const entry = chunk.readUInt16BE(pos);\n      pos += 2;\n      positions.push(`${entry & 0x3fff}${weightSuffixes[entry >> 14]}`);\n    }\n    lexemes.push(positions.length > 0 ? `'${word}':${positions.join(\",\")}` : `'${word}'`);\n  }\n  return lexemes.join(\" \");\n}\n\nconst weightSuffixes = [\"\", \"C\", \"B\", \"A\"];\n\n/** Renders a binary range (flags byte + length-prefixed bounds) to pg's text form, i.e. `[\"a\",\"b\")`. */\nfunction renderRange(chunk: Buffer, start: number, bound: (c: Buffer, s: number) => string): string {\n  const flags = chunk[start];\n  if (flags & 0x01) return \"empty\";\n  let pos = start + 1;\n  let lower = \"\";\n  let upper = \"\";\n  if (!(flags & 0x08)) {\n    const len = chunk.readInt32BE(pos);\n    lower = bound(chunk, pos + 4);\n    pos += 4 + len;\n  }\n  if (!(flags & 0x10)) {\n    upper = bound(chunk, pos + 4);\n  }\n  return `${flags & 0x02 ? \"[\" : \"(\"}${lower},${upper}${flags & 0x04 ? \"]\" : \")\"}`;\n}\n\n/** Renders days-since-1970 as pg's date text, i.e. `2020-01-02` or `0001-01-01 BC`. */\nfunction renderDate(epochDays: number): string {\n  const { text, bc } = renderDatePart(epochDays);\n  return bc ? `${text} BC` : text;\n}\n\n/**\n * Renders the `YYYY-MM-DD` part, converting astronomical years to pg's BC numbering\n * (astronomical year 0 = `0001 BC`); timestamps append the ` BC` marker after the time/zone.\n */\nfunction renderDatePart(epochDays: number): { text: string; bc: boolean } {\n  const [year, month, day] = civilFromDays(epochDays);\n  const bc = year <= 0;\n  const displayYear = bc ? 1 - year : year;\n  return {\n    text: `${String(displayYear).padStart(4, \"0\")}-${String(month).padStart(2, \"0\")}-${String(day).padStart(2, \"0\")}`,\n    bc,\n  };\n}\n\n/** Renders a binary timestamp (µs since 2000-01-01) to pg's text form, i.e. `2020-01-02 03:04:05.678+00`. */\nfunction renderTimestamp(pgMicros: bigint, suffix: string): string {\n  if (pgMicros === INFINITY_US) return \"infinity\";\n  if (pgMicros === NEG_INFINITY_US) return \"-infinity\";\n  const { days, us } = splitPgMicros(pgMicros);\n  const { text: date, bc } = renderDatePart(days);\n  return `${date} ${renderTimeOfDay(us)}${suffix}${bc ? \" BC\" : \"\"}`;\n}\n\n/** Renders µs-since-midnight to pg's time text, i.e. `03:04:05.678` with trailing zeros trimmed. */\nfunction renderTimeOfDay(us: number): string {\n  const seconds = Math.floor(us / 1_000_000);\n  const hh = String(Math.floor(seconds / 3600)).padStart(2, \"0\");\n  const mm = String(Math.floor((seconds / 60) % 60)).padStart(2, \"0\");\n  const ss = String(seconds % 60).padStart(2, \"0\");\n  // pg renders up to 6 fractional digits with trailing zeros trimmed, and no \".\" when zero\n  let fraction = \"\";\n  const usPart = us % 1_000_000;\n  if (usPart > 0) fraction = `.${String(usPart).padStart(6, \"0\")}`.replace(/0+$/, \"\");\n  return `${hh}:${mm}:${ss}${fraction}`;\n}\n\n/** Converts days-since-1970 to a civil [year, month, day], i.e. Howard Hinnant's algorithm. */\nfunction civilFromDays(epochDays: number): [number, number, number] {\n  const z = epochDays + 719_468;\n  const era = Math.floor(z / 146_097);\n  const doe = z - era * 146_097;\n  const yoe = Math.floor((doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365);\n  const y = yoe + era * 400;\n  const doy = doe - (365 * yoe + Math.floor(yoe / 4) - Math.floor(yoe / 100));\n  const mp = Math.floor((5 * doy + 2) / 153);\n  const d = doy - Math.floor((153 * mp + 2) / 5) + 1;\n  const m = mp < 10 ? mp + 3 : mp - 9;\n  return [m <= 2 ? y + 1 : y, m, d];\n}\n\n/** Throws an `Error` with `message`. */\nfunction fail(message: string): never {\n  throw new Error(message);\n}\n"],"mappings":"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"}