{"version":3,"sources":["../src/index.ts","../src/temporalProvider.ts","../src/errors.ts","../src/localeVocab.ts","../src/isoWeek.ts","../src/tokens.ts","../src/tokenize.ts","../src/constants.ts","../src/numbering.ts","../src/format.ts","../src/pattern.ts","../src/parsePattern.ts","../src/parse.ts","../src/relativeGrammar.ts","../src/parseRelative.ts","../src/tokenMetadata.ts","../src/analyze.ts","../src/calendarUtils.ts","../src/comparison.ts","../src/rounding.ts","../src/serialization.ts","../src/formatDuration.ts","../src/duration.ts","../src/localeRegistry.ts","../src/config.ts","../src/interval.ts","../src/arithmetic.ts","../src/recurrence.ts","../src/businessCalendar.ts","../src/holidays.ts","../src/timezone.ts","../src/ideData.ts","../src/codemod.ts","../src/runtime.ts","../src/formatDistance.ts","../src/typeGuards.ts","../src/relativeTime.ts","../src/extensibility.ts","../src/modApi.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport { formatToParts, type FormattedPart, type CompiledFormat } from './format.js';\nexport { safeParse, tryParse, parseToParts, type SafeParseResult, type ParsedPart, type CompiledParser } from './parse.js';\n\n// format() and parse() specifically (not formatToParts/safeParse/etc.)\n// are re-exported through the override registry instead of straight\n// from format.ts/parse.ts, so a mod's overrideFormat()/overrideParse()\n// is visible to anyone importing these two functions the normal way —\n// see runtime.ts for why only these two, and modApi.ts for how a mod\n// installs one.\nimport { getFormatImpl, getParseImpl } from './runtime.js';\nexport const format: typeof import('./format.js').format = (...args) => getFormatImpl()(...args);\nexport const parse: typeof import('./parse.js').parse = (...args) => getParseImpl()(...args);\n\nexport { setTemporal } from './temporalProvider.js';\nexport { formatDuration } from './formatDuration.js';\nexport { formatDistance, formatDistanceToNow } from './formatDistance.js';\n\nexport { registerLocaleVocab } from './localeVocab.js';\nexport type { LocaleVocab } from './localeVocab.js';\nexport type { TemporalLike, FormatOptions } from './tokens.js';\nexport type { DurationFormatOptions } from './formatDuration.js';\nexport type { FormatDistanceOptions, DistanceCutoffs } from './formatDistance.js';\nexport type { ParseRelativeOptions } from './parseRelative.js';\nexport type { TemporalNamespace } from './temporalProvider.js';\n\n// type guards\nexport { isTemporal, isInstant, isPlainDate, isPlainTime, isPlainDateTime, isZonedDateTime, isPlainYearMonth, isPlainMonthDay, isDuration, assertTemporal, assertInstant, assertPlainDate, assertPlainTime, assertPlainDateTime, assertZonedDateTime, assertPlainYearMonth, assertPlainMonthDay, assertDuration } from './typeGuards.js';\n\n// typed errors\nexport { TemporalFmtError, FormatSyntaxError, UnknownTokenError, ParseMismatchError, InvalidDateError, InvalidTimeError, InvalidOffsetError, InvalidTimeZoneError, InvalidCalendarError, AmbiguousInputError, InvalidLocaleError, InvalidDurationError, type TemporalFmtErrorFields, type TemporalFmtErrorCode } from './errors.js';\n\n// analyzer / introspection\nexport { analyzeFormat, type FormatAnalysis, type AnalyzedToken, type TokenMetadata, type TemporalType } from './analyze.js';\n\n// token metadata (re-exported as a top-level surface for\n// callers like the ESLint plugin that want the table directly without\n// going through analyzeFormat)\nexport { TOKEN_METADATA, ALL_TOKEN_NAMES } from './tokenMetadata.js';\nexport { FORMAT_ONLY_TOKENS } from './pattern.js';\n\n// calendar utilities\nexport { daysInMonth, daysInYear, dayOfYearHelper as dayOfYear, getQuarter, startOf, endOf, asDateFieldView, type DateFieldView, type StartOfUnit, type QuarterOptions } from './calendarUtils.js';\n\n// date arithmetic\nexport { add, subtract, difference, addYears, addMonths, addWeeks, addDays, addHours, addMinutes, addSeconds, addMilliseconds, subtractYears, subtractMonths, subtractWeeks, subtractDays, subtractHours, subtractMinutes, subtractSeconds, subtractMilliseconds, differenceInYears, differenceInMonths, differenceInWeeks, differenceInDays, differenceInHours, differenceInMinutes, differenceInSeconds, differenceInMilliseconds, type AddUnit, type DiffUnit } from './arithmetic.js';\n\n// comparison\nexport { compare, min, max, isWeekend } from './comparison.js';\n\n// rounding\nexport { round, roundDuration, type RoundOptions, type DurationFields } from './rounding.js';\n\n// serialization\nexport { parseISO, formatISO, formatRFC2822, formatHTTPDate, fromUnixSeconds, fromUnixMilliseconds } from './serialization.js';\n\n// duration (extended)\nexport { totalDuration, addDuration } from './duration.js';\nexport { roundDuration as roundDurationAlias } from './rounding.js';\n\n// relative time\nexport { formatRelative, formatRelativeToNow, type FormatRelativeOptions } from './relativeTime.js';\n\n// locale registration\nexport { registerLocale, type ExtendedLocaleVocab } from './localeRegistry.js';\n\n// numbering systems\nexport { convertDigits, convertDigitsToAscii, applyNumbering, applyParseNumbering, SUPPORTED_NUMBERING_SYSTEMS, type NumberingSystem, type NumberingSystemOption, type NumberingFormatOptions } from './numbering.js';\n\n// config\nexport { DEFAULT_CONFIG, type TemporalFmtConfig } from './config.js';\n\n// relative-grammar registration\nexport { registerRelativeGrammar, type RelativeGrammar, type RelativeGrammarMatch } from './relativeGrammar.js';\n\n// intervals\nexport { contains as intervalContains, intersects, isBefore as intervalIsBefore, isAfter as intervalIsAfter, difference as intervalDifference, subtract as intervalSubtract, splitInterval, formatRange, type Interval, type IntervalBounds } from './interval.js';\n\n// recurrence\nexport { recurrence, take, skip, type RecurrenceRule, type RecurrenceFrequency, type RecurrenceIterator } from './recurrence.js';\n\n// business calendar\nexport { isBusinessDay, addBusinessDays, differenceInBusinessDays, nextBusinessDay, previousBusinessDay, type BusinessCalendar, type BusinessCalendarOptions } from './businessCalendar.js';\n\n// holiday framework\nexport { createHolidayCalendar, holidaysBetween, type HolidayCalendar, type HolidaySpec } from './holidays.js';\n\n// timezone subsystem\nexport { getTimeZone, getOffset, getOffsetNanoseconds, isDST, getTransitions, type DisambiguationMode, type ResolveZonedOptions } from './timezone.js';\n\n// extensibility\nexport { createFormatter, type Formatter, type FormatterOptions, type CustomToken, type TokenHandler, type TokenField } from './extensibility.js';\n\n// IDE tooling data\nexport { DAYJS_TO_TEMPORAL_FMT, DATE_FNS_TO_TEMPORAL_FMT, type TokenAutocompleteEntry, type TokenHoverDoc, type InlineDiagnostic, type TokenConversionHint } from './ideData.js';\n\n// Day.js / date-fns translation — backs the CLI's `translate` subcommand\n// (see scripts/cli.mjs)\nexport { translateDayjsFormatString } from './codemod.js';\n\n// mod contract — see README -> Writing Mods. The loader that actually\n// reads a mods/ folder off disk is Node-only and lives in\n// scripts/loadMods.mjs, not here; this is just the shape a mod matches.\nexport { buildModContext, buildModContextFor, buildTrackedModContext, isMod, GRANTABLE_PERMISSIONS, type Mod, type ModContext, type ModRegistrationKey } from './modApi.js';\nexport { OverrideConflictError } from './runtime.js';\n\n\n// The 81 functions below have no internal fan-out (nothing else in\n// this library calls them directly), so unlike round()/compare()/etc.\n// above, a mod overriding one of these can't be silently bypassed by\n// some other module's cached direct import — these are re-exported\n// through the override registry the same way format()/parse() are.\n// See runtime.ts and modApi.ts.\nimport { getCompileFormatImpl, getCompileParserImpl, getParseRelativeImpl, getExplainFormatImpl, getTokenizeFormatImpl, getListTokensImpl, getTokenInfoImpl, getIsValidFormatImpl, getValidateFormatImpl, getFieldForTokenImpl, getMonthsInYearImpl, getIsLeapYearImpl, getIsLeapMonthImpl, getWeekOfYearImpl, getWeekYearImpl, getGetMonthImpl, getGetWeekdayImpl, getIsEqualImpl, getIsBeforeImpl, getIsAfterImpl, getClampImpl, getIsBetweenImpl, getIsTodayImpl, getIsTomorrowImpl, getIsYesterdayImpl, getIsSameDayImpl, getIsSameWeekImpl, getIsSameMonthImpl, getIsSameQuarterImpl, getIsSameYearImpl, getIsWeekdayImpl, getFloorImpl, getCeilImpl, getTruncateImpl, getParseRFC3339Impl, getFormatRFC3339Impl, getParseRFC2822Impl, getParseHTTPDateImpl, getFromUnixMicrosecondsImpl, getFromUnixNanosecondsImpl, getToUnixSecondsImpl, getToUnixMillisecondsImpl, getToUnixMicrosecondsImpl, getToUnixNanosecondsImpl, getParseSQLImpl, getFormatSQLImpl, getFormatDurationToPartsImpl, getParseDurationImpl, getParseISODurationImpl, getFormatISODurationImpl, getBalanceDurationImpl, getCompareDurationImpl, getSubtractDurationImpl, getGetLocaleImpl, getHasLocaleImpl, getCreateConfigImpl, getMergeWithConfigImpl, getListRegisteredGrammarsImpl, getIntervalImpl, getOverlapsImpl, getIntersectionImpl, getUnionImpl, getMergeIntervalsImpl, getFormatRangeToPartsImpl, getBetweenImpl, getParseRRuleImpl, getFormatRRuleImpl, getCreateBusinessCalendarImpl, getSubtractBusinessDaysImpl, getNextHolidayImpl, getPreviousHolidayImpl, getResolveZonedImpl, getGetNextTransitionImpl, getGetPreviousTransitionImpl, getPossibleInstantsForImpl, getGetAutocompleteDataImpl, getGetHoverDocsImpl, getGetInlineDiagnosticsImpl, getPreviewFormatImpl, getGetDocUrlImpl, getTranslateDateFnsFormatStringImpl } from './runtime.js';\nexport const compileFormat: typeof import('./format.js').compileFormat = (...args) => getCompileFormatImpl()(...args);\nexport const compileParser: typeof import('./parse.js').compileParser = (...args) => getCompileParserImpl()(...args);\nexport const parseRelative: typeof import('./parseRelative.js').parseRelative = (...args) => getParseRelativeImpl()(...args);\nexport const explainFormat: typeof import('./analyze.js').explainFormat = (...args) => getExplainFormatImpl()(...args);\nexport const tokenizeFormat: typeof import('./analyze.js').tokenizeFormat = (...args) => getTokenizeFormatImpl()(...args);\nexport const listTokens: typeof import('./analyze.js').listTokens = (...args) => getListTokensImpl()(...args);\nexport const tokenInfo: typeof import('./analyze.js').tokenInfo = (...args) => getTokenInfoImpl()(...args);\nexport const isValidFormat: typeof import('./analyze.js').isValidFormat = (...args) => getIsValidFormatImpl()(...args);\nexport const validateFormat: typeof import('./analyze.js').validateFormat = (...args) => getValidateFormatImpl()(...args);\nexport const fieldForToken: typeof import('./analyze.js').fieldForToken = (...args) => getFieldForTokenImpl()(...args);\nexport const monthsInYear: typeof import('./calendarUtils.js').monthsInYear = (...args) => getMonthsInYearImpl()(...args);\nexport const isLeapYear: typeof import('./calendarUtils.js').isLeapYear = (...args) => getIsLeapYearImpl()(...args);\nexport const isLeapMonth: typeof import('./calendarUtils.js').isLeapMonth = (...args) => getIsLeapMonthImpl()(...args);\nexport const weekOfYear: typeof import('./calendarUtils.js').weekOfYear = (...args) => getWeekOfYearImpl()(...args);\nexport const weekYear: typeof import('./calendarUtils.js').weekYear = (...args) => getWeekYearImpl()(...args);\nexport const getMonth: typeof import('./calendarUtils.js').getMonth = (...args) => getGetMonthImpl()(...args);\nexport const getWeekday: typeof import('./calendarUtils.js').getWeekday = (...args) => getGetWeekdayImpl()(...args);\nexport const isEqual: typeof import('./comparison.js').isEqual = (...args) => getIsEqualImpl()(...args);\nexport const isBefore: typeof import('./comparison.js').isBefore = (...args) => getIsBeforeImpl()(...args);\nexport const isAfter: typeof import('./comparison.js').isAfter = (...args) => getIsAfterImpl()(...args);\nexport const clamp: typeof import('./comparison.js').clamp = (...args) => getClampImpl()(...args);\nexport const isBetween: typeof import('./comparison.js').isBetween = (...args) => getIsBetweenImpl()(...args);\nexport const isToday: typeof import('./comparison.js').isToday = (...args) => getIsTodayImpl()(...args);\nexport const isTomorrow: typeof import('./comparison.js').isTomorrow = (...args) => getIsTomorrowImpl()(...args);\nexport const isYesterday: typeof import('./comparison.js').isYesterday = (...args) => getIsYesterdayImpl()(...args);\nexport const isSameDay: typeof import('./comparison.js').isSameDay = (...args) => getIsSameDayImpl()(...args);\nexport const isSameWeek: typeof import('./comparison.js').isSameWeek = (...args) => getIsSameWeekImpl()(...args);\nexport const isSameMonth: typeof import('./comparison.js').isSameMonth = (...args) => getIsSameMonthImpl()(...args);\nexport const isSameQuarter: typeof import('./comparison.js').isSameQuarter = (...args) => getIsSameQuarterImpl()(...args);\nexport const isSameYear: typeof import('./comparison.js').isSameYear = (...args) => getIsSameYearImpl()(...args);\nexport const isWeekday: typeof import('./comparison.js').isWeekday = (...args) => getIsWeekdayImpl()(...args);\nexport const floor: typeof import('./rounding.js').floor = (...args) => getFloorImpl()(...args);\nexport const ceil: typeof import('./rounding.js').ceil = (...args) => getCeilImpl()(...args);\nexport const truncate: typeof import('./rounding.js').truncate = (...args) => getTruncateImpl()(...args);\nexport const parseRFC3339: typeof import('./serialization.js').parseRFC3339 = (...args) => getParseRFC3339Impl()(...args);\nexport const formatRFC3339: typeof import('./serialization.js').formatRFC3339 = (...args) => getFormatRFC3339Impl()(...args);\nexport const parseRFC2822: typeof import('./serialization.js').parseRFC2822 = (...args) => getParseRFC2822Impl()(...args);\nexport const parseHTTPDate: typeof import('./serialization.js').parseHTTPDate = (...args) => getParseHTTPDateImpl()(...args);\nexport const fromUnixMicroseconds: typeof import('./serialization.js').fromUnixMicroseconds = (...args) => getFromUnixMicrosecondsImpl()(...args);\nexport const fromUnixNanoseconds: typeof import('./serialization.js').fromUnixNanoseconds = (...args) => getFromUnixNanosecondsImpl()(...args);\nexport const toUnixSeconds: typeof import('./serialization.js').toUnixSeconds = (...args) => getToUnixSecondsImpl()(...args);\nexport const toUnixMilliseconds: typeof import('./serialization.js').toUnixMilliseconds = (...args) => getToUnixMillisecondsImpl()(...args);\nexport const toUnixMicroseconds: typeof import('./serialization.js').toUnixMicroseconds = (...args) => getToUnixMicrosecondsImpl()(...args);\nexport const toUnixNanoseconds: typeof import('./serialization.js').toUnixNanoseconds = (...args) => getToUnixNanosecondsImpl()(...args);\nexport const parseSQL: typeof import('./serialization.js').parseSQL = (...args) => getParseSQLImpl()(...args);\nexport const formatSQL: typeof import('./serialization.js').formatSQL = (...args) => getFormatSQLImpl()(...args);\nexport const formatDurationToParts: typeof import('./duration.js').formatDurationToParts = (...args) => getFormatDurationToPartsImpl()(...args);\nexport const parseDuration: typeof import('./duration.js').parseDuration = (...args) => getParseDurationImpl()(...args);\nexport const parseISODuration: typeof import('./duration.js').parseISODuration = (...args) => getParseISODurationImpl()(...args);\nexport const formatISODuration: typeof import('./duration.js').formatISODuration = (...args) => getFormatISODurationImpl()(...args);\nexport const balanceDuration: typeof import('./duration.js').balanceDuration = (...args) => getBalanceDurationImpl()(...args);\nexport const compareDuration: typeof import('./duration.js').compareDuration = (...args) => getCompareDurationImpl()(...args);\nexport const subtractDuration: typeof import('./duration.js').subtractDuration = (...args) => getSubtractDurationImpl()(...args);\nexport const getLocale: typeof import('./localeRegistry.js').getLocale = (...args) => getGetLocaleImpl()(...args);\nexport const hasLocale: typeof import('./localeRegistry.js').hasLocale = (...args) => getHasLocaleImpl()(...args);\nexport const createConfig: typeof import('./config.js').createConfig = (...args) => getCreateConfigImpl()(...args);\nexport const mergeWithConfig: typeof import('./config.js').mergeWithConfig = (...args) => getMergeWithConfigImpl()(...args);\nexport const listRegisteredGrammars: typeof import('./relativeGrammar.js').listRegisteredGrammars = (...args) => getListRegisteredGrammarsImpl()(...args);\nexport const interval: typeof import('./interval.js').interval = (...args) => getIntervalImpl()(...args);\nexport const overlaps: typeof import('./interval.js').overlaps = (...args) => getOverlapsImpl()(...args);\nexport const intersection: typeof import('./interval.js').intersection = (...args) => getIntersectionImpl()(...args);\nexport const union: typeof import('./interval.js').union = (...args) => getUnionImpl()(...args);\nexport const mergeIntervals: typeof import('./interval.js').mergeIntervals = (...args) => getMergeIntervalsImpl()(...args);\nexport const formatRangeToParts: typeof import('./interval.js').formatRangeToParts = (...args) => getFormatRangeToPartsImpl()(...args);\nexport const between: typeof import('./recurrence.js').between = (...args) => getBetweenImpl()(...args);\nexport const parseRRule: typeof import('./recurrence.js').parseRRule = (...args) => getParseRRuleImpl()(...args);\nexport const formatRRule: typeof import('./recurrence.js').formatRRule = (...args) => getFormatRRuleImpl()(...args);\nexport const createBusinessCalendar: typeof import('./businessCalendar.js').createBusinessCalendar = (...args) => getCreateBusinessCalendarImpl()(...args);\nexport const subtractBusinessDays: typeof import('./businessCalendar.js').subtractBusinessDays = (...args) => getSubtractBusinessDaysImpl()(...args);\nexport const nextHoliday: typeof import('./holidays.js').nextHoliday = (...args) => getNextHolidayImpl()(...args);\nexport const previousHoliday: typeof import('./holidays.js').previousHoliday = (...args) => getPreviousHolidayImpl()(...args);\nexport const resolveZoned: typeof import('./timezone.js').resolveZoned = (...args) => getResolveZonedImpl()(...args);\nexport const getNextTransition: typeof import('./timezone.js').getNextTransition = (...args) => getGetNextTransitionImpl()(...args);\nexport const getPreviousTransition: typeof import('./timezone.js').getPreviousTransition = (...args) => getGetPreviousTransitionImpl()(...args);\nexport const possibleInstantsFor: typeof import('./timezone.js').possibleInstantsFor = (...args) => getPossibleInstantsForImpl()(...args);\nexport const getAutocompleteData: typeof import('./ideData.js').getAutocompleteData = (...args) => getGetAutocompleteDataImpl()(...args);\nexport const getHoverDocs: typeof import('./ideData.js').getHoverDocs = (...args) => getGetHoverDocsImpl()(...args);\nexport const getInlineDiagnostics: typeof import('./ideData.js').getInlineDiagnostics = (...args) => getGetInlineDiagnosticsImpl()(...args);\nexport const previewFormat: typeof import('./ideData.js').previewFormat = (...args) => getPreviewFormatImpl()(...args);\nexport const getDocUrl: typeof import('./ideData.js').getDocUrl = (...args) => getGetDocUrlImpl()(...args);\nexport const translateDateFnsFormatString: typeof import('./codemod.js').translateDateFnsFormatString = (...args) => getTranslateDateFnsFormatStringImpl()(...args);\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tsconfig here is lib: [\"ESNext\"] only, so there's no ambient Temporal\n// namespace type to lean on. everywhere else in the codebase we just read\n// fields off whatever Temporal-like object gets passed in (see TemporalLike\n// in tokens.ts) but this file is the one place that actually touches the\n// Temporal namespace itself — PlainDate.from and friends. parse() uses it\n// to build results, tokens.ts uses it to check native Intl<->Temporal\n// support. you can hand us your own implementation via setTemporal(), or\n// we just grab globalThis.Temporal if there is one\ninterface TemporalFactory {\n  from(fields: Record<string, number | string | undefined>, options?: { overflow?: 'constrain' | 'reject'; disambiguation?: 'compatible' | 'earlier' | 'later' | 'reject'; offset?: 'use' | 'ignore' | 'prefer' | 'reject' }): unknown;\n  // compare() is on the namespace, not instances (Temporal.PlainDate.compare).\n  // made optional since someone might hand us a stripped-down shim that\n  // doesn't bother implementing it\n  compare?(one: unknown, two: unknown): number;\n}\n\n// Instant doesn't use from(fields) like the others, it's\n// fromEpochMilliseconds / fromEpochNanoseconds. needs its own shape.\ninterface InstantFactory {\n  from(iso: string): unknown;\n  fromEpochMilliseconds(ms: number): unknown;\n  fromEpochMicroseconds(µs: number): unknown;\n  fromEpochNanoseconds(ns: bigint): unknown;\n}\n\n// Duration uses from(fields) too, but also has round() and compare()\ninterface DurationFactory extends TemporalFactory {\n  compare?(one: unknown, two: unknown): number;\n  prototype?: { round(options: unknown): unknown };\n}\n\n// PlainYearMonth / PlainMonthDay also just use from(fields) — same shape\n// as TemporalFactory really, kept as its own type so callers can narrow\nexport interface TemporalNamespace {\n  PlainDate: TemporalFactory;\n  PlainTime: TemporalFactory;\n  PlainDateTime: TemporalFactory;\n  ZonedDateTime: TemporalFactory;\n  Instant?: InstantFactory;\n  Duration?: DurationFactory;\n  PlainYearMonth?: TemporalFactory;\n  PlainMonthDay?: TemporalFactory;\n}\n\nlet injectedTemporal: TemporalNamespace | undefined;\n\n// anything caching something tied to WHICH Temporal impl is active\n// (right now just tokens.ts's native-Intl probe) registers a listener\n// here so it knows to invalidate when setTemporal() swaps things out —\n// see setTemporal() below for why that matters. kept this as a plain\n// array instead of a full event emitter since all we need is \"call\n// everyone back, in order, no payload\" — didn't need unsubscribe either\nconst onTemporalChanged: Array<() => void> = [];\n\nexport function subscribeToTemporalChanges(listener: () => void): void {\n  onTemporalChanged.push(listener);\n}\n\n/**\n * Explicitly hand temporal-fmt the Temporal implementation to use, instead\n * of relying on a global `Temporal`. Call this once, before your first\n * `format()`/`parse()`/`parseISO()`/etc.\n *\n * Call with no argument (or `undefined`) to clear the override and fall\n * back to `globalThis.Temporal` again.\n *\n * @example\n * import { Temporal } from 'temporal-polyfill';\n * import { setTemporal } from 'temporal-fmt';\n * setTemporal(Temporal);\n */\nexport function setTemporal(temporal?: TemporalNamespace): void {\n  injectedTemporal = temporal;\n  // tokens.ts caches its native-Intl probe result based on whatever\n  // Temporal was active the first time it ran. if that changes later\n  // (native -> polyfill, say) the cached result goes stale. so just reset\n  // everyone on any setTemporal() call — costs one extra probe re-run,\n  // worth it to not silently use a stale answer\n  for (const listener of onTemporalChanged) listener();\n}\n\nfunction resolveTemporal(): TemporalNamespace | undefined {\n  return injectedTemporal ?? (globalThis as unknown as { Temporal?: TemporalNamespace }).Temporal;\n}\n\nexport function getTemporal(): TemporalNamespace {\n  const temporal = resolveTemporal();\n  if (!temporal) {\n    throw new Error(\n      'temporal-fmt: parse() needs a Temporal implementation to construct its result. ' +\n      'Call setTemporal(Temporal) once at startup, or assign one to globalThis.Temporal ' +\n      '(native on Node 26+, or a polyfill like temporal-polyfill).'\n    );\n  }\n  return temporal;\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// structured error classes for parse()/format() failures.\n//\n// as of 0.9.0 every throw site on the parse/format data path —\n// tokenize.ts, pattern.ts, format.ts, parse.ts (parse/safeParse/tryParse/\n// parseToParts/compileParser), plus the two data-path throws in\n// localeVocab.ts (partValue/assertNoCollision on the getLocaleVocab side)\n// — throws one of these typed classes directly instead of a plain\n// `new Error(message)`. every site we migrated kept its exact pre-0.9.0\n// message text, and since subclasses of TemporalFmtError still pass\n// `instanceof Error` and match the same message regexes (e.g.\n// `/token \"HH\" requires/`), this didn't need a semver-major bump for\n// either of those checks. what DOES break in 0.9.0: if anyone was\n// specifically checking `err.constructor === Error` or `err.name ===\n// 'Error'`, that'll now see a different name (e.g. 'FormatSyntaxError').\n// noted in the 0.9.0 changelog.\n//\n// deliberately did NOT migrate:\n//  - localeVocab.ts's registration-time throws (assertValidVocab,\n//    registerLocaleVocab itself) — these are config-time API-misuse\n//    errors on data a developer hands in once at startup, not runtime\n//    parse/format failures, so they don't really fit this module's\n//    TemporalFmtErrorCode taxonomy as-is. assertNoCollision is shared\n//    between the registration path and the data path (getLocaleVocab)\n//    though, so its throw stays a plain Error for both until that gets\n//    split apart — see the tracking note where it's called.\n//\n// wrapUntypedError() below is still around for localeVocab.ts's\n// registration throws, and for anything a caller passes into\n// safeParse()/tryParse() from outside this package. on the data path\n// itself, safeParse's `if (err instanceof TemporalFmtError) return { ok:\n// false, error: err }` catches everything before it'd even reach the\n// classifier here, so honestly the regex branches below are dead for\n// parse/format/tokenize/pattern at this point — kept as the fallback for\n// whatever hasn't been migrated to a typed throw site yet\n\nexport type TemporalFmtErrorCode =\n  | 'FORMAT_SYNTAX_ERROR'\n  | 'UNKNOWN_TOKEN'\n  | 'PARSE_MISMATCH'\n  | 'INVALID_DATE'\n  | 'INVALID_TIME'\n  | 'INVALID_OFFSET'\n  | 'INVALID_TIME_ZONE'\n  | 'INVALID_CALENDAR'\n  | 'AMBIGUOUS_INPUT'\n  | 'INVALID_LOCALE'\n  | 'INVALID_DURATION';\n\nexport interface TemporalFmtErrorFields {\n  code: TemporalFmtErrorCode;\n  input?: string;\n  format?: string;\n  token?: string;\n  position?: number;\n  expected?: string;\n  actual?: string;\n  reason?: string;\n}\n\n// base class. `message` is the human-readable summary, the structured\n// fields are the machine-readable bits a linter or codemod would report\n// on. calling Error.captureStackTrace manually (where it exists) so the\n// stack points at wherever this got thrown from, not at this constructor\n// — same trick Node uses for its own error classes\nexport class TemporalFmtError extends Error {\n  readonly code: TemporalFmtErrorCode;\n  readonly input?: string;\n  readonly format?: string;\n  readonly token?: string;\n  readonly position?: number;\n  readonly expected?: string;\n  readonly actual?: string;\n  readonly reason?: string;\n\n  constructor(message: string, fields: TemporalFmtErrorFields) {\n    super(message);\n    this.name = 'TemporalFmtError';\n    this.code = fields.code;\n    this.input = fields.input;\n    this.format = fields.format;\n    this.token = fields.token;\n    this.position = fields.position;\n    this.expected = fields.expected;\n    this.actual = fields.actual;\n    this.reason = fields.reason;\n    // don't want the stack pointing at this constructor line — captureStackTrace\n    // is V8-only though, so on other engines callers just get the default\n    // stack (pointing here) since there's nothing better to do about it\n    const capture = (Error as unknown as { captureStackTrace?: (target: Error, ctor?: Function) => void }).captureStackTrace;\n    if (typeof capture === 'function') {\n      capture(this, this.constructor);\n    }\n  }\n\n  // lets callers just call err.toJSON() for logging. plain Error doesn't\n  // serialize its non-enumerable fields on its own, so this picks them\n  // up explicitly\n  toJSON(): TemporalFmtErrorFields & { name: string; message: string } {\n    return {\n      name: this.name,\n      message: this.message,\n      code: this.code,\n      input: this.input,\n      format: this.format,\n      token: this.token,\n      position: this.position,\n      expected: this.expected,\n      actual: this.actual,\n      reason: this.reason,\n    };\n  }\n}\n\n// each subclass just fixes `code` so callers can switch on it without\n// having to re-check message text. the constructor only takes the\n// fields that actually vary per call; `code` and the default message\n// template come from the subclass itself\n\nexport class FormatSyntaxError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `format string \"${fields.format ?? ''}\" has a syntax error${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'FORMAT_SYNTAX_ERROR', ...rest },\n    );\n    this.name = 'FormatSyntaxError';\n  }\n}\n\nexport class UnknownTokenError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `token \"${fields.token ?? ''}\" is not a recognized temporal-fmt token${fields.format ? ` in format string \"${fields.format}\"` : ''}.`,\n      { code: 'UNKNOWN_TOKEN', ...rest },\n    );\n    this.name = 'UnknownTokenError';\n  }\n}\n\nexport class ParseMismatchError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `input \"${fields.input ?? ''}\" does not match format \"${fields.format ?? ''}\"${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'PARSE_MISMATCH', ...rest },\n    );\n    this.name = 'ParseMismatchError';\n  }\n}\n\nexport class InvalidDateError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `input \"${fields.input ?? ''}\" does not describe a valid date${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_DATE', ...rest },\n    );\n    this.name = 'InvalidDateError';\n  }\n}\n\n/* c8 ignore start @preserve -- InvalidTimeError is part of the public\n   error-class surface (exported from index.ts, code 'INVALID_TIME') but\n   nothing in this package actually constructs one. went and checked\n   whether it could get wired in the same way InvalidTimeZoneError just\n   was (see parse.ts's zzz-validation loop) — does hour/minute/second have\n   a post-match semantic range check the way zone ids do? nope.\n   pattern.ts's regex fragments for HH/H/hh/h/mm/m/ss/s already enforce\n   their valid ranges right at the regex level (e.g. HH is\n   '(?:[01]\\d|2[0-3])', which literally can't match \"99\"), so an\n   out-of-range time just gets rejected as a plain shape mismatch before\n   any semantic check would even run. no live gap to hook this into\n   without inventing a redundant check purely to give this class a body.\n   leaving it unconstructed until the library actually hits a real\n   invalid-time case worth reporting */\nexport class InvalidTimeError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `input \"${fields.input ?? ''}\" does not describe a valid time${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_TIME', ...rest },\n    );\n    this.name = 'InvalidTimeError';\n  }\n}\n/* c8 ignore stop @preserve */\n\nexport class InvalidOffsetError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `offset \"${fields.actual ?? ''}\" is invalid${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_OFFSET', ...rest },\n    );\n    this.name = 'InvalidOffsetError';\n  }\n}\n\nexport class InvalidTimeZoneError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `time zone \"${fields.actual ?? ''}\" is not a recognized IANA time zone or fixed offset${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_TIME_ZONE', ...rest },\n    );\n    this.name = 'InvalidTimeZoneError';\n  }\n}\n\n/* c8 ignore start @preserve -- InvalidCalendarError is part of the\n   public error-class surface (exported from index.ts, code\n   'INVALID_CALENDAR') but same story as InvalidTimeError above — nothing\n   in this package constructs one. checked for a wiring opportunity the\n   same way: there's no user-supplied calendar identifier anywhere in the\n   library that we'd validate against a supported list. resolveCalendar()\n   in parse.ts derives the calendar entirely from Intl's own resolution\n   of the locale string — it's never handed an arbitrary \"calendar\" value\n   a caller could actually get wrong. no live input to reject here.\n   leaving it unconstructed until the library accepts an actual calendar\n   parameter that could be invalid */\nexport class InvalidCalendarError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `calendar \"${fields.actual ?? ''}\" is not supported${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_CALENDAR', ...rest },\n    );\n    this.name = 'InvalidCalendarError';\n  }\n}\n/* c8 ignore stop @preserve */\n\nexport class AmbiguousInputError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `input \"${fields.input ?? ''}\" is ambiguous${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'AMBIGUOUS_INPUT', ...rest },\n    );\n    this.name = 'AmbiguousInputError';\n  }\n}\n\nexport class InvalidLocaleError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `locale \"${fields.actual ?? ''}\" is not a valid BCP-47 tag${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_LOCALE', ...rest },\n    );\n    this.name = 'InvalidLocaleError';\n  }\n}\n\nexport class InvalidDurationError extends TemporalFmtError {\n  constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n    const { message, ...rest } = fields;\n    super(\n      message ?? `duration is invalid${fields.reason ? `: ${fields.reason}` : ''}.`,\n      { code: 'INVALID_DURATION', ...rest },\n    );\n    this.name = 'InvalidDurationError';\n  }\n}\n\n// wraps a plain Error thrown from a code path that hasn't been migrated\n// to typed errors yet. keeps the original message around in `reason` so\n// callers reading the typed surface still see what actually failed.\n// used by safeParse() in parse.ts.\n//\n// after the 0.9.0 migration, every throw site on the parse/format data\n// path throws a TemporalFmtError directly, so safeParse's `instanceof\n// TemporalFmtError` check always passes before this function would even\n// get called — nothing in the current test suite actually reaches any\n// branch below. kept as the safety net for whenever someone adds an\n// unmigrated throw site down the line (see the c8-ignored call in\n// parse.ts's safeParse) — same reasoning as that call site: removing\n// this would silently break the \"safeParse always returns a\n// TemporalFmtError\" contract the moment anyone adds a bare\n// `throw new Error(...)` without wiring up a typed class for it\n/* c8 ignore start @preserve -- unreachable from the current test suite,\n   see rationale above */\nexport function wrapUntypedError(err: Error, context: { input?: string; format?: string }): TemporalFmtError {\n  // try to classify by looking at the message — covers the existing\n  // parse()/format() throw sites without having to touch them. anything\n  // that doesn't match a known pattern falls through to a generic\n  // ParseMismatchError, still with the structured fields intact\n  const msg = err.message;\n  if (/unknown token|isn't a recognized token/.test(msg)) {\n    return new UnknownTokenError({ input: context.input, format: context.format, reason: msg });\n  }\n  if (/ambiguous/i.test(msg)) {\n    return new AmbiguousInputError({ input: context.input, format: context.format, reason: msg });\n  }\n  if (/offset/.test(msg) && /out of range|exceeds|doesn't match the shape/i.test(msg)) {\n    return new InvalidOffsetError({ input: context.input, format: context.format, reason: msg });\n  }\n  if (/no valid pattern matches/i.test(msg)) {\n    return new ParseMismatchError({ input: context.input, format: context.format, reason: msg });\n  }\n  if (/doesn't describe a valid date\\/time|incomplete date|weekday token|quarter token/.test(msg)) {\n    return new InvalidDateError({ input: context.input, format: context.format, reason: msg });\n  }\n  const lowerMsg = msg.toLowerCase();\n  const mentionsLocale = lowerMsg.includes('locale');\n  if (\n    (mentionsLocale && (lowerMsg.includes('produced no') || lowerMsg.includes('not a valid'))) ||\n    lowerMsg.includes('cutoffs must be')\n  ) {\n    return new InvalidLocaleError({ input: context.input, format: context.format, reason: msg });\n  }\n  if (/format string exceeds maximum length|input exceeds maximum length|unterminated quote|isn't a recognized token/i.test(msg)) {\n    return new FormatSyntaxError({ input: context.input, format: context.format, reason: msg });\n  }\n  return new ParseMismatchError({ input: context.input, format: context.format, reason: msg });\n}\n/* c8 ignore stop @preserve */","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Name lists for the locale-aware tokens (MMMM, MMM, EEEE, EEE, a). Each\n// list is small and fixed (12 months, 7 weekdays, 2 day periods), so we\n// generate the real Intl strings for a locale once and cache them.\n\nimport { InvalidLocaleError } from './errors.js';\n\nexport interface LocaleVocab {\n  monthLong: string[]; // index 0 = January\n  monthShort: string[];\n  weekdayLong: string[]; // index 0 = Monday, per Temporal's dayOfWeek numbering\n  weekdayShort: string[];\n  dayPeriod: string[]; // typically [AM-ish, PM-ish], deduped\n}\n\n// Custom vocabs registered by callers for locales Intl doesn't cover well\n// (e.g. a 13-month Hebrew leap year, where Intl's 12-month vocabulary\n// silently loses a whole month). Keyed by canonical cache key so the\n// same locale string spelling variants fold together — same convention\n// as the Intl-derived vocab cache above.\nconst customVocabs = new Map<string, LocaleVocab>();\nconst MAX_CUSTOM_VOCABS = 500;\nconst MAX_LOCALE_TAG_LENGTH = 256;\nconst MAX_VOCAB_ENTRY_LENGTH = 256;\n\nfunction assertValidVocab(vocab: Partial<LocaleVocab>, locale: string): void {\n  // Strict shape validation at registration time, not lazily on first\n  // use — the README's promise is that a malformed registration throws\n  // descriptively here, rather than failing later inside format()/parse()\n  // with a confusing \"no month part\" or wrong-month error the caller\n  // can't trace back to the bad registration.\n  const required: Array<{ key: keyof LocaleVocab; length: number; label: string }> = [\n    { key: 'monthLong', length: 12, label: 'long month names' },\n    { key: 'monthShort', length: 12, label: 'short month names' },\n    { key: 'weekdayLong', length: 7, label: 'long weekday names' },\n    { key: 'weekdayShort', length: 7, label: 'short weekday names' },\n    { key: 'dayPeriod', length: 2, label: 'day period markers (AM/PM-equivalent)' },\n  ];\n\n  for (const { key, length, label } of required) {\n    const value = vocab[key];\n    if (value === undefined) {\n      throw new Error(\n        `temporal-fmt: registerLocaleVocab for locale \"${locale}\" is missing required field \"${key}\" (${label}).`\n      );\n    }\n    if (!Array.isArray(value)) {\n      throw new Error(\n        `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}\" must be an array, got ${typeof value}.`\n      );\n    }\n    if (value.length !== length) {\n      throw new Error(\n        `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}\" must have exactly ${length} entries (got ${value.length}) — ${label}.`\n      );\n    }\n    value.forEach((entry, i) => {\n      if (typeof entry !== 'string' || entry.length === 0) {\n        throw new Error(\n          `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}[${i}]\" must be a non-empty string, got ${String(entry)}.`\n        );\n      }\n      if (entry.length > MAX_VOCAB_ENTRY_LENGTH) {\n        throw new RangeError(\n          `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}[${i}]\" is too long (maximum ${MAX_VOCAB_ENTRY_LENGTH} characters).`\n        );\n      }\n    });\n  }\n\n  // Reuse the same collision check the Intl-derived path uses — a\n  // duplicate month name is just as ambiguous when supplied by a caller\n  // as when produced by Intl.\n  assertNoCollision(vocab.monthLong!, 'MMMM month', locale);\n  assertNoCollision(vocab.monthShort!, 'MMM month', locale);\n  assertNoCollision(vocab.weekdayLong!, 'EEEE weekday', locale);\n  assertNoCollision(vocab.weekdayShort!, 'EEE weekday', locale);\n\n  // dayPeriod entries must differ from each other, or parse()'s\n  // isPM check (raw === vocab.dayPeriod[1]) can never return true and\n  // every 12-hour parse silently resolves to AM. The Intl-derived path\n  // dedupes a same-AM/PM collision to length 1, but a caller passing\n  // both entries identical is a real bug to surface — not something to\n  // dedupe around.\n  if (vocab.dayPeriod![0] === vocab.dayPeriod![1]) {\n    throw new Error(\n      `temporal-fmt: registerLocaleVocab for locale \"${locale}\": dayPeriod entries must differ ` +\n      `(both are \"${vocab.dayPeriod![0]}\"); otherwise parse() can't tell AM from PM.`\n    );\n  }\n}\n\n// Anything that caches a result derived from *which* vocabulary is\n// active for a locale (right now: parse.ts's compiled pattern cache,\n// whose MMMM/MMM/EEEE/EEE/a fragments embed the vocab's alternations)\n// subscribes here so it gets invalidated when a registration swaps the\n// vocab — mirrors temporalProvider.ts's subscribeToTemporalChanges.\nconst onVocabChanged: Array<() => void> = [];\n\nexport function subscribeToVocabChanges(listener: () => void): void {\n  onVocabChanged.push(listener);\n}\n\n/**\n * Supply a custom month/weekday/day-period vocabulary for a locale key,\n * overriding the Intl-derived vocab this library would otherwise build\n * for that key. Useful for locales Intl doesn't cover well — the\n * Parsing section of the README (\"MMMM/MMM assume a 12-month calendar\")\n * calls out the Hebrew leap-month gap as a specific case this addresses.\n *\n * Throws descriptively on malformed input (wrong array lengths, empty\n * strings, duplicate entries, missing fields) rather than failing later\n * during format/parse.\n *\n * Registered vocab takes precedence over the Intl-derived vocab for that\n * locale key, including for already-cached entries — registering\n * invalidates the prior cache entry for that locale so the next call\n * picks up the new vocab.\n *\n * @example\n * registerLocaleVocab('en-u-ca-hebrew-leap', {\n *   monthLong: ['Nisan','Iyar','Sivan','Tammuz','Av','Elul','Tishrei','Marcheshvan','Kislev','Tevet','Shevat','Adar I','Adar II'],\n *   monthShort: ['Nis','Iyy','Siv','Tam','Av','Elu','Tish','Chesh','Kis','Tev','Shv','Ad1','Ad2'],\n *   weekdayLong: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'],\n *   weekdayShort: ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],\n *   dayPeriod: ['AM','PM'],\n * });\n */\nexport function registerLocaleVocab(locale: string, vocab: Partial<LocaleVocab>): void {\n  if (typeof locale !== 'string' || locale.length === 0) {\n    throw new Error(`temporal-fmt: registerLocaleVocab requires a non-empty locale string, got ${String(locale)}.`);\n  }\n  if (locale.length > MAX_LOCALE_TAG_LENGTH) {\n    throw new RangeError(`temporal-fmt: registerLocaleVocab locale is too long (maximum ${MAX_LOCALE_TAG_LENGTH} characters).`);\n  }\n  assertValidVocab(vocab, locale);\n\n  const cacheKey = canonicalCacheKey(locale);\n  if (!customVocabs.has(cacheKey) && customVocabs.size >= MAX_CUSTOM_VOCABS) {\n    throw new RangeError(`temporal-fmt: registerLocaleVocab reached the ${MAX_CUSTOM_VOCABS}-locale limit.`);\n  }\n  customVocabs.set(cacheKey, {\n    monthLong: [...vocab.monthLong!],\n    monthShort: [...vocab.monthShort!],\n    weekdayLong: [...vocab.weekdayLong!],\n    weekdayShort: [...vocab.weekdayShort!],\n    dayPeriod: [...vocab.dayPeriod!],\n  });\n  // Invalidate the Intl-derived cache entry so any prior format/parse\n  // result cached for this locale is rebuilt against the new vocab. Not\n  // strictly necessary (getLocaleVocab checks customVocabs first), but\n  // cheap and keeps the two caches from drifting out of sync.\n  vocabCache.delete(cacheKey);\n  // Also invalidate downstream caches that baked the previous vocab in\n  // at build time (parse.ts's pattern cache is the one that matters:\n  // without this, a cached pattern would keep matching the OLD month /\n  // weekday names while format() renders the new ones, so the library's\n  // own format() output would fail to parse back).\n  for (const listener of onVocabChanged) listener();\n}\n\n// Every locale-keyed cache in this library (this one, formatterCache in\n// tokens.ts, patternCache/calendarCache in parse.ts) used to key on the\n// exact locale string a caller passed in. Intl treats spelling variants of\n// the same locale as equivalent ('en-US' / 'en-us' / 'en_US' all resolve\n// the same way), but a plain string-keyed Map doesn't — so callers mixing\n// spellings for what's really one locale would silently fragment across\n// separate cache entries instead of sharing one, making the bounded\n// eviction limits (MAX_*_CACHE_SIZE) less effective than they look. This\n// doesn't change any cache's *correctness* (each entry is still built from\n// -- and valid for -- whatever locale string produced it), only how many\n// distinct entries equivalent spellings end up costing. Falls back to the\n// original string on a malformed/unrecognized tag rather than throwing —\n// cache-key normalization shouldn't be where a bad locale first surfaces\n// as an error; whatever actually calls `new Intl.DateTimeFormat(locale)`\n// downstream is the right place for that.\n// Intl constructors (DateTimeFormat/NumberFormat/RelativeTimeFormat)\n// reject underscore-separated tags like 'en_US' outright, while\n// canonicalCacheKey and every locale-parsing path in this library\n// tolerates them by normalizing to BCP-47 hyphens. Centralize that\n// normalization so every `new Intl.*(locale)` construction site\n// accepts the same spellings the cache keys do. Genuinely malformed\n// tags still throw downstream, unchanged.\nexport function normalizeLocaleTag(locale: string): string {\n  return locale.replace(/_/g, '-');\n}\n\n// Memoized so hot paths (parse()'s resolveCalendar keys off this on\n// every call, and every locale-keyed cache re-derives it) don't build a\n// fresh Intl.Locale per invocation — construction is comparatively\n// expensive. Bounded like every other cache in this library.\nconst canonicalKeyCache = new Map<string, string>();\nconst MAX_CANONICAL_KEY_CACHE = 500;\n\nexport function canonicalCacheKey(locale: string): string {\n  const hit = canonicalKeyCache.get(locale);\n  if (hit !== undefined) return hit;\n  let key: string;\n  try {\n    // Intl.Locale requires BCP-47 hyphens and rejects underscore-separated\n    // tags like 'en_US' outright (RangeError), rather than normalizing\n    // them — so without this replace, that spelling would just fall\n    // through to the catch below and never fold with 'en-US'.\n    key = new Intl.Locale(locale.replace(/_/g, '-')).toString().toLowerCase();\n  } catch {\n    // Malformed tag: key on the raw string. Callers that must reject\n    // malformed tags do it via assertValidLocaleTag() before/instead of\n    // relying on this function — cache-key normalization isn't where a\n    // bad locale should surface as an error (unchanged behavior).\n    key = locale;\n  }\n  if (canonicalKeyCache.size >= MAX_CANONICAL_KEY_CACHE) {\n    const oldestKey = canonicalKeyCache.keys().next().value;\n    if (oldestKey !== undefined) canonicalKeyCache.delete(oldestKey);\n  }\n  canonicalKeyCache.set(locale, key);\n  return key;\n}\n\n// Single validation choke point for locale tags at public boundaries.\n// Intl constructors reject malformed tags with a bare engine RangeError\n// (\"Incorrect locale information provided\") that carries none of the\n// library's structured error context; this rethrows as the typed\n// InvalidLocaleError with the offending tag in its fields. Accepts the\n// same spellings as canonicalCacheKey (underscore tags normalized).\nexport function assertValidLocaleTag(locale: string): void {\n  try {\n    new Intl.Locale(normalizeLocaleTag(locale));\n  } catch {\n    throw new InvalidLocaleError({\n      actual: locale,\n      reason: 'not a valid BCP-47 locale tag',\n    });\n  }\n}\n\nconst vocabCache = new Map<string, LocaleVocab>();\nconst MAX_VOCAB_CACHE_SIZE = 500;\n\n// Some locales (ja-JP) split a field across two parts — month \"8\" plus a\n// counter suffix \"月\" as a separate sibling \"literal\" — while format()'s\n// post-1582 tokens go through toLocaleString(), which concatenates\n// everything into \"8月\", and the pre-1582 path in tokens.ts\n// (preCutoverGregorianName) formats one field at a time the same way this\n// does. Reading only the type-tagged part used to drop that suffix, so\n// this locale's vocab never matched what format() actually produced.\n// Only merges *adjacent* literals, not the whole string, since the\n// dayPeriod/weekday formatters below carry an extra hour part that a\n// join-everything approach would wrongly absorb.\nexport function partValue(formatter: Intl.DateTimeFormat, date: Date, type: Intl.DateTimeFormatPartTypes): string {\n  const parts = formatter.formatToParts(date);\n  const index = parts.findIndex((p) => p.type === type);\n  /* c8 ignore start @preserve -- defensive guard against a real but\n     unreproducible failure mode: an Intl implementation that omits the\n     requested part type entirely for some locale. Checked every locale\n     with unusual dayPeriod/weekday/month rendering available in this\n     runtime's ICU data (ja-JP, zh-CN, th-TH, he-IL, ar-SA, ko-KR, fa-IR)\n     against the exact formatter options getLocaleVocab uses (notably\n     hour12: true for the dayPeriod formatter, which is what makes every\n     locale here actually emit a dayPeriod part — omitting it is what\n     produced a false \"gap\" during investigation). None omit their part\n     on this runtime. A different ICU version or a non-Node Intl\n     implementation could plausibly behave differently, so this stays a\n     real check rather than an assertion. */\n  /* c8 ignore start @preserve */\n  if (index === -1) {\n    throw new InvalidLocaleError({\n      message: `temporal-fmt: locale produced no \"${type}\" part while building match vocabulary.`,\n    });\n  }\n  /* c8 ignore stop @preserve */\n  let value = parts[index]!.value;\n  const prev = parts[index - 1];\n  const next = parts[index + 1];\n  // skip whitespace literals (the separator before \"AM\") — only a\n  // no-space suffix like ja-JP's \"月\" should get folded in\n  if (prev?.type === 'literal' && !/\\s/.test(prev.value)) value = prev.value + value;\n  if (next?.type === 'literal' && !/\\s/.test(next.value)) value = value + next.value;\n  return value;\n}\n\n// Two entries rendering identically means parse()'s reverse lookup\n// (indexOf) can never tell them apart. Weekday collisions already surface\n// via parse()'s dayOfWeek cross-check, but with a confusing same-string\n// error; months have no equivalent cross-check, so a collision there would\n// otherwise resolve silently to the wrong month. Catching both here, once\n// at build time, gives one clear error instead.\nfunction assertNoCollision(names: string[], label: string, locale: string): void {\n  const seen = new Map<string, number>();\n  for (let i = 0; i < names.length; i++) {\n    const prior = seen.get(names[i]!);\n    if (prior !== undefined) {\n      // Not migrated to a typed error: this function is shared between\n      // getLocaleVocab's Intl-derived path (data-path error, would be a\n      // good InvalidLocaleError candidate) and assertValidVocab's\n      // registration-time check (out of scope for this pass — see the\n      // localeVocab.ts registration-error follow-up). Splitting this into\n      // two near-duplicate functions just to route error types\n      // differently isn't worth it for one throw; revisit together with\n      // the registration-error work instead.\n      throw new Error(\n        `temporal-fmt: locale \"${locale}\" renders ${label} index ${prior} and ${i} identically ` +\n        `(\"${names[i]}\"). parse() can't reliably tell these apart for this locale/token, so this ` +\n        `combination isn't supported.`\n      );\n    }\n    seen.set(names[i]!, i);\n  }\n}\n\n// Exposed for tokens.ts: when a custom vocab is registered for this\n// locale, format()'s locale-aware tokens (MMMM/MMM/EEEE/EEE/a) read\n// straight from the registered array instead of going through\n// Intl.DateTimeFormat. Without this override, format() would silently\n// keep producing Intl's strings while parse() matched against the\n// registered vocab — the two would round-trip-fail.\nexport function getCustomVocab(locale: string): LocaleVocab | undefined {\n  const cacheKey = canonicalCacheKey(locale);\n  return customVocabs.get(cacheKey);\n}\n\nexport function getLocaleVocab(locale: string): LocaleVocab {\n  // Validate before building vocab: a malformed tag used to surface as a\n  // raw RangeError from the first new Intl.DateTimeFormat below.\n  assertValidLocaleTag(locale);\n  const cacheKey = canonicalCacheKey(locale);\n  // Registered vocabs take precedence over the Intl-derived one — this\n  // is the override mechanism registerLocaleVocab() promises. Checking\n  // here, before the Intl cache lookup, means a registration that\n  // happens *after* the first Intl-derived vocab was built still takes\n  // effect on the next call.\n  const custom = customVocabs.get(cacheKey);\n  if (custom) {\n    return custom;\n  }\n  const cached = vocabCache.get(cacheKey);\n  if (cached) {\n    return cached;\n  }\n\n  const intlLocale = normalizeLocaleTag(locale);\n  const monthLongFmt = new Intl.DateTimeFormat(intlLocale, { month: 'long', timeZone: 'UTC' });\n  const monthShortFmt = new Intl.DateTimeFormat(intlLocale, { month: 'short', timeZone: 'UTC' });\n  const monthLong: string[] = [];\n  const monthShort: string[] = [];\n  for (let m = 0; m < 12; m++) {\n    const date = new Date(Date.UTC(2020, m, 1));\n    monthLong.push(partValue(monthLongFmt, date, 'month'));\n    monthShort.push(partValue(monthShortFmt, date, 'month'));\n  }\n  assertNoCollision(monthLong, 'MMMM month', locale);\n  assertNoCollision(monthShort, 'MMM month', locale);\n\n  const weekdayLongFmt = new Intl.DateTimeFormat(intlLocale, { weekday: 'long', timeZone: 'UTC' });\n  const weekdayShortFmt = new Intl.DateTimeFormat(intlLocale, { weekday: 'short', timeZone: 'UTC' });\n  const weekdayLong: string[] = [];\n  const weekdayShort: string[] = [];\n  // 2024-01-01 is a Monday (UTC) — walk 7 days from there for weekday names\n  for (let d = 0; d < 7; d++) {\n    const date = new Date(Date.UTC(2024, 0, 1 + d));\n    weekdayLong.push(partValue(weekdayLongFmt, date, 'weekday'));\n    weekdayShort.push(partValue(weekdayShortFmt, date, 'weekday'));\n  }\n  // redundant with parse()'s dayOfWeek cross-check, but gives a clearer error\n  assertNoCollision(weekdayLong, 'EEEE weekday', locale);\n  assertNoCollision(weekdayShort, 'EEE weekday', locale);\n\n  const dayPeriodFmt = new Intl.DateTimeFormat(intlLocale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n  const am = partValue(dayPeriodFmt, new Date(Date.UTC(2020, 0, 1, 1)), 'dayPeriod');\n  const pm = partValue(dayPeriodFmt, new Date(Date.UTC(2020, 0, 1, 13)), 'dayPeriod');\n  const dayPeriod = [...new Set([am, pm])];\n\n  const vocab: LocaleVocab = { monthLong, monthShort, weekdayLong, weekdayShort, dayPeriod };\n  if (vocabCache.size >= MAX_VOCAB_CACHE_SIZE) {\n    const oldestKey = vocabCache.keys().next().value;\n    if (oldestKey !== undefined) vocabCache.delete(oldestKey);\n  }\n  vocabCache.set(cacheKey, vocab);\n  return vocab;\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// ISO week stuff. week runs Mon-Sun, and week 1 is whichever week has\n// the year's first Thursday in it (same as saying \"the week with Jan 4\").\n// took me a minute to wrap my head around this but the upshot is late-Dec\n// dates can land in week 1 of NEXT year, and early-Jan dates can land in\n// week 52/53 of the PREVIOUS year. that adjacent year is what RRRR prints,\n// not the plain calendar year.\n//\n// doing this with plain year/month/day + dayOfWeek math instead of asking\n// Temporal for it, since format() only has whatever fields got handed in\n// and dragging in a whole Temporal implementation just for week numbers\n// felt like overkill (also breaks for people not on setTemporal()).\n\nconst DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst CUMULATIVE_DAYS_BY_MONTH = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n\nexport function isGregorianLeapYear(year: number): boolean {\n  // divisible by 4, unless it's a century, then it also needs /400.\n  // Temporal's iso8601 calendar never switches to Julian, so this rule\n  // just applies all the way back, even for BCE years.\n  return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\nfunction daysInYear(year: number): 365 | 366 {\n  return isGregorianLeapYear(year) ? 366 : 365;\n}\n\nexport function dayOfYear(year: number, month: number, day: number): number {\n  let doy = CUMULATIVE_DAYS_BY_MONTH[month - 1]! + day;\n  if (month > 2 && isGregorianLeapYear(year)) doy += 1;\n  return doy;\n}\n\n// Jan 1 2000 was a Saturday (ISO dow 6). picked this as an anchor point\n// since it's easier than reaching for Zeller's congruence every time,\n// and obviously this fact about Jan 1 2000 isn't going to change on us\nconst REFERENCE_YEAR = 2000;\nconst REFERENCE_JAN1_DAY_OF_WEEK = 6;\n\n// Howard Hinnant's days_from_civil: O(1) day count for a proleptic\n// Gregorian y/m/d, correct for negative years and year 0 (the (y2>=0?\n// y2 : y2-399)/400 offset form relies on truncating division, which JS\n// doesn't have — Math.floor on the *un-offset* numerator is the exact\n// JS equivalent, see the matching formulas in arithmetic.ts). Shared by\n// dayOfWeekOfJan1 and any caller needing days between two arbitrary\n// dates without a year-by-year walk (those walks were O(|year − 2000|)\n// per call — a field bag claiming year 2e8 hung formatDistance for\n// ~400ms per call and worse for bigger values).\nexport function daysFromCivil(year: number, month: number, day: number): number {\n  const y2 = month <= 2 ? year - 1 : year;\n  const era = Math.floor(y2 / 400);\n  const yoe = y2 - era * 400; // [0, 399]\n  const m2 = month > 2 ? month - 3 : month + 9; // [0, 11]\n  const doy = Math.floor((153 * m2 + 2) / 5) + day - 1; // [0, 365]\n  const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy; // [0, 146096]\n  return era * 146097 + doe - 719468;\n}\n\n// Day of week (ISO, 1=Mon..7=Sun) for a proleptic Gregorian y/m/d, in\n// O(1). 1970-01-01 was a Thursday (dow 4), so dow = (days + 3) mod 7\n// shifted to 1..7. Replaces the Date.UTC(year, month-1, day) idiom used\n// elsewhere in this library, which silently remaps years 0-99 to\n// 1900-1999 per the ECMAScript spec and produces the wrong weekday for\n// first-century dates.\nexport function dayOfWeekFromCivil(year: number, month: number, day: number): number {\n  const days = daysFromCivil(year, month, day);\n  // days=0 is 1970-01-01 (Thursday, dow 4): (0 + 3) % 7 = 3 → 4 ✓\n  return (((days + 3) % 7) + 7) % 7 + 1;\n}\n\nfunction dayOfWeekOfJan1(year: number): number {\n  // O(1) via daysFromCivil: Jan 1 of `year` is `days` after Jan 1 2000\n  // (a Saturday, dow 6), so dow = (6 - 1 + days) mod 7, bumped to 1-indexed.\n  // The old year-by-year walk from 2000 was O(|year − 2000|) — correct\n  // but linear, and unbounded for hostile field-bag years.\n  const days = daysFromCivil(year, 1, 1) - daysFromCivil(REFERENCE_YEAR, 1, 1);\n  const zeroIndexed = (((REFERENCE_JAN1_DAY_OF_WEEK - 1 + days) % 7) + 7) % 7;\n  return zeroIndexed + 1;\n}\n\nexport interface IsoWeekDate {\n  isoYear: number;\n  week: number; // goes 1 to 53\n}\n\nexport function isoWeekYearAndWeek(year: number, month: number, day: number, dayOfWeek: number): IsoWeekDate {\n  // step 1: figure out the Thursday of this week — whatever calendar year\n  // that Thursday's in IS the ISO week-numbering year. doing this with\n  // day-of-year offsets so we don't need an actual Temporal.PlainDate here\n  const doy = dayOfYear(year, month, day);\n  const thursdayDoyRelative = doy + (4 - dayOfWeek); // can go negative or past daysInYear, that's fine\n\n  let isoYear: number;\n  let thursdayDoy: number;\n  if (thursdayDoyRelative < 1) {\n    isoYear = year - 1;\n    thursdayDoy = thursdayDoyRelative + daysInYear(isoYear);\n  } else if (thursdayDoyRelative > daysInYear(year)) {\n    isoYear = year + 1;\n    thursdayDoy = thursdayDoyRelative - daysInYear(year);\n  } else {\n    isoYear = year;\n    thursdayDoy = thursdayDoyRelative;\n  }\n\n  // step 2: find the first Thursday of isoYear, that one's week 1 by definition.\n  // depends entirely on which weekday Jan 1 lands on\n  const jan1Dow = dayOfWeekOfJan1(isoYear);\n  const firstThursdayDoy = 1 + ((4 - jan1Dow + 7) % 7); // always lands somewhere 1-7\n\n  // step 3: just count how many full weeks between the two Thursdays\n  const week = 1 + Math.floor((thursdayDoy - firstThursdayDoy) / 7);\n  return { isoYear, week };\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getTemporal, subscribeToTemporalChanges } from './temporalProvider.js';\nimport { canonicalCacheKey, getCustomVocab, normalizeLocaleTag, partValue } from './localeVocab.js';\nimport { InvalidLocaleError, FormatSyntaxError } from './errors.js';\nimport { isoWeekYearAndWeek, dayOfYear } from './isoWeek.js';\n\n// Throws the library's standard typed missing-field error for tokens\n// that READ more fields than their TOKENS-table `field` entry declares\n// (the table only drives format()'s single-field precheck). ww/RRRR read\n// year/month/day/dayOfWeek but precheck only dayOfWeek; D/DD/DDD read\n// year/month/day but precheck only day. Without this, a bag carrying the\n// declared field but missing the rest fed undefined into the math and\n// produced literal \"NaN\" output instead of the descriptive error every\n// other token throws.\nfunction requireFields(t: TemporalLike, token: string, ...fields: Array<keyof TemporalLike>): void {\n  for (const field of fields) {\n    if (t[field] === undefined) {\n      throw new FormatSyntaxError({\n        token,\n        message:\n          `temporal-fmt: token \"${token}\" requires \"${field}\", ` +\n          `which this Temporal object doesn't have. ` +\n          `(e.g. PlainDate has no time fields, PlainTime has no date fields)`,\n      });\n    }\n  }\n}\n\nexport function pad(n: number, len: number): string {\n  // padStart pads the whole string, sign included, so pad(-45, 4) used to\n  // come out \"0-45\" instead of \"-045\" — split the sign off first.\n  const negative = n < 0;\n  const digits = String(Math.abs(n)).padStart(len, '0');\n  return negative ? '-' + digits : digits;\n}\n\n// Combines the three sub-second fields Temporal exposes into one 9-digit\n// nanosecond-of-second value, then truncates (never rounds) to the\n// requested width. Truncating matches what every digit-width token in\n// this library already does elsewhere (yy, MM, dd, ...) — the token\n// asked for N digits of precision, not a rounded N-digit approximation.\n// A caller asking for SSS on a value with nanosecond precision gets the\n// leading 3 digits of it, same as they'd get the leading 3 digits of any\n// other multi-digit field this library formats.\n//\n// Attached to pad() rather than declared standalone: the bundler's\n// per-function coverage instrumentation attributes hits to each of the\n// 9 fraction-token arrow functions individually but not to a shared\n// helper they all close over, so a correctly-exercised helper still\n// shows as 0 hits under c8. pad() itself is called directly all over\n// this file and is reliably attributed — routing through it here keeps\n// the coverage numbers honest without duplicating the slice logic\n// across every token entry below.\npad.fraction = function formatFraction(t: TemporalLike, width: number): string {\n  const nanoOfSecond = t.millisecond! * 1_000_000 + (t.microsecond ?? 0) * 1_000 + (t.nanosecond ?? 0);\n  return pad(nanoOfSecond, 9).slice(0, width);\n};\n\n// Not every field exists on every Temporal type (PlainDate has no .hour,\n// etc). Callers check for undefined before formatting a token.\nexport interface TemporalLike {\n  year?: number;\n  month?: number;\n  day?: number;\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n  microsecond?: number;\n  nanosecond?: number;\n  timeZoneId?: string;\n  // ZonedDateTime.prototype.offset — `±HH:MM` (6 chars) for any modern\n  // date, but pre-1900 local-mean-time zones (e.g. America/New_York\n  // before 1883) surface a seconds component too: `±HH:MM:SS` (9\n  // chars). Format-side offset tokens must check the length rather\n  // than assume 6. Parse-side writes a canonicalized `+HH:MM` here\n  // before handing it to Temporal.ZonedDateTime.from as the\n  // `timeZone` value.\n  offset?: string;\n  dayOfWeek?: number; // 1=Mon, 7=Sun, per Temporal spec\n  calendarId?: string;\n  toInstant?: () => unknown;\n  toLocaleString?: (locale: string, options: Intl.DateTimeFormatOptions) => string;\n}\n\nexport interface FormatOptions {\n  /** BCP 47 locale tag, e.g. 'en-US', 'fr-FR', 'ar-EG'. Defaults to 'en-US'. */\n  locale?: string;\n  /**\n   * When set on parse(), opts into the lenient split heuristic for ambiguous\n   * glued numeric runs (e.g. \"121\" against \"Md\"). Default (false) keeps\n   * parse()'s strict behavior — throw on ambiguity rather than guess.\n   * See README \"Lenient parse mode\" for the heuristic and why it's opt-in.\n   */\n  lenient?: boolean;\n}\n\nexport const DEFAULT_LOCALE = 'en-US';\n\n// Intl.DateTimeFormat is expensive to construct and format() can run in a\n// loop (rendering a table of dates), so cache by (locale, options).\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n  const key = JSON.stringify([canonicalCacheKey(locale), options]);\n  let formatter = formatterCache.get(key);\n  if (formatter) {\n    return formatter;\n  }\n  if (formatterCache.size >= MAX_CACHE_SIZE) {\n    // not real LRU, just evicts oldest insertion — fine for this key space\n    const oldestKey = formatterCache.keys().next().value;\n    if (oldestKey !== undefined) formatterCache.delete(oldestKey);\n  }\n  try {\n    formatter = new Intl.DateTimeFormat(normalizeLocaleTag(locale), options);\n  } catch (err) {\n    // Malformed locale tags reach Intl as a bare RangeError; surface the\n    // library's typed error instead (reached via dayPeriodPart — the\n    // 'a' token — on any runtime, and the native-Intl path for the rest).\n    // Every failure mode of this constructor with a string locale is a\n    // RangeError, so converting unconditionally preserves the original\n    // message in `reason` either way.\n    throw new InvalidLocaleError({ actual: locale, reason: (err as Error).message });\n  }\n  formatterCache.set(key, formatter);\n  return formatter;\n}\n\n// Passing a Temporal object straight into `new Intl.DateTimeFormat().formatToParts()`\n// only works when the engine's Intl implementation has special-cased support for\n// *native* Temporal instances (checked via internal slots and/or gated behind a V8 flag,\n// not tied to a specific Node version).\n//\n// A Temporal polyfill's instances don't have those slots, so the engine falls back to ToNumber() -> .valueOf(),\n// which the polyfill deliberately throws on (\"Cannot use valueOf\").\n// Probed once and memoized and only from intlPart(), so it never\n// runs unless a format string actually uses a locale-aware token.\nlet nativeSupport: boolean | undefined;\n// Invalidate the memoized probe whenever setTemporal() swaps the active\n// implementation — otherwise a probe result from \"is native Temporal\n// supported\" could keep being used after the active implementation is\n// no longer the one that was probed. See setTemporal() in\n// temporalProvider.ts for the other half of this.\nsubscribeToTemporalChanges(() => { nativeSupport = undefined; });\n\nfunction intlSupportsNativeTemporal(): boolean {\n  if (nativeSupport === undefined) {\n    nativeSupport = false;\n      try {\n        const temporal = getTemporal();\n        new Intl.DateTimeFormat('en-US', { day: 'numeric' })\n          .formatToParts(temporal.PlainDate.from({ year: 1970, month: 1, day: 1 }) as Date);\n        // Version-gated, not dead — see the matching note on the\n        // !intlSupportsNativeTemporal() branch in intlPart() below for\n        // why this can't be exercised from this environment.\n        /* c8 ignore next */\n        nativeSupport = true;\n      /* c8 ignore start */\n      } catch {\n        // native Temporal absent, or present but not recognized by Intl — fall back.\n        // Version-gated, not dead: this catch only fires on runtimes where the\n        // probe above throws (no native Temporal, or Intl doesn't recognize it).\n        // On a runtime with full native support (e.g. Node builds where Intl\n        // accepts native Temporal instances directly) the try succeeds and this\n        // branch is unreachable — mirror case of the block below.\n      }\n      /* c8 ignore stop */\n  }\n  return nativeSupport;\n}\n\n// The Julian → Gregorian cutover, as ICU applies it. ICU's gregory\n// calendar (unlike Temporal's, which is proleptic Gregorian throughout)\n// treats every date before October 15, 1582 as a Julian-calendar date:\n// the Julian calendar ran ~10 days behind proleptic Gregorian in that\n// era, so a date Temporal correctly calls 1500-07-05 gets silently\n// reinterpreted by Intl as Julian 1500-06-25 — the wrong month near\n// boundaries, and a weekday shifted by 10 mod 7 = 3 slots everywhere.\n// See tc39/ecma402#1003. Whether the cutover is even observable varies\n// by engine and entry point (V8's plain-Date path disables it; the\n// native-Temporal formatToParts path on some Node 26 builds does not),\n// so this can't be probed reliably at runtime — pre-cutover dates have\n// to be routed around Intl's calendar math entirely.\nconst GREGORIAN_CUTOVER_YEAR = 1582;\nconst GREGORIAN_CUTOVER_MONTH = 10;\nconst GREGORIAN_CUTOVER_DAY = 15;\n\n// True when the Temporal object's own (proleptic-Gregorian, hence\n// trustworthy) fields place it before the ICU cutover. Deliberately\n// NaN-tolerant rather than undefined-checking: a Temporal type that\n// lacks one of these fields (PlainMonthDay has no year, PlainYearMonth\n// no day) feeds undefined into Number(), every NaN comparison is false,\n// and the object falls out as \"not before the cutover\" onto its existing\n// formatting path — no undefined-specific branches to keep covered, and\n// no behavior change for field-partial types.\nfunction isBeforeGregorianCutover(t: TemporalLike): boolean {\n  if (t.year !== GREGORIAN_CUTOVER_YEAR) return Number(t.year) < GREGORIAN_CUTOVER_YEAR;\n  if (t.month !== GREGORIAN_CUTOVER_MONTH) return Number(t.month) < GREGORIAN_CUTOVER_MONTH;\n  return Number(t.day) < GREGORIAN_CUTOVER_DAY;\n}\n\n// Renders a locale-aware month/weekday name for a pre-cutover date\n// WITHOUT ever handing the date itself to Intl. Intl is used purely as a\n// name lookup table indexed by month/weekday number — never as the thing\n// that computes which month/weekday a historical date falls on, which is\n// the computation the Julian cutover corrupts. The number comes straight\n// off the Temporal object's own fields (proleptic-Gregorian-correct by\n// construction, since that's what Temporal is), and the name comes from\n// formatting a safe modern reference date carrying that same number.\n//\n// The reference dates are deliberately the same ones getLocaleVocab()\n// (localeVocab.ts) uses to build the parse-side vocabulary — 2020-mm-01\n// for months, the Monday-anchored 2024-01-01..07 week for weekdays — so\n// format() output for a pre-cutover date is byte-identical to what\n// parse() matches against, and round-trips keep working. partValue()\n// gives us the same adjacent-literal merging (ja-JP's \"8月\") the vocab\n// builder uses, for the same reason.\nfunction preCutoverGregorianName(\n  temporal: TemporalLike,\n  locale: string,\n  formatterOptions: Intl.DateTimeFormatOptions,\n  partType: 'month' | 'weekday'\n): string {\n  // timeZone: 'UTC' matters: the references are built via Date.UTC\n  // (midnight UTC), and without pinning the formatter's zone a host\n  // timezone behind UTC would shift them to the previous local day.\n  // month/dayOfWeek are guaranteed present — format()'s field precheck\n  // for MMMM/MMM ('month') and EEEE/EEE ('dayOfWeek') ran before the\n  // token handler was invoked at all.\n  const reference = partType === 'month'\n    ? new Date(Date.UTC(2020, temporal.month! - 1, 1))\n    : new Date(Date.UTC(2024, 0, temporal.dayOfWeek!));\n  const formatter = getFormatter(locale, { ...formatterOptions, timeZone: 'UTC' });\n  return partValue(formatter, reference, partType);\n}\n\nfunction intlPart(\n  temporal: TemporalLike,\n  locale: string,\n  options: Intl.DateTimeFormatOptions,\n  partType: Intl.DateTimeFormatPartTypes\n): string {\n  // Intl throws \"Mismatching Calendars\" if the formatter's calendar doesn't\n  // match the object's own (e.g. en-US formatter defaults to gregory, but\n  // a hebrew/islamic PlainDate needs its own calendar passed through).\n  //\n  // For iso8601 specifically, force 'gregory' rather than leaving calendar\n  // unset: numeric fields (yyyy/dd, see tokens' pad()-based handlers) are\n  // always pulled straight off the object's own ISO fields — so if the\n  // *locale* carries a `-u-ca-*` extension (e.g. 'en-u-ca-hebrew') and this\n  // step left calendar unset, the formatter would resolve its own default\n  // calendar from the locale and format MMMM/EEEE in that calendar while\n  // yyyy/dd stay ISO, producing a date that looks internally consistent\n  // (a real Hebrew month name next to a real-looking day/year) but names a\n  // completely different day than the object actually represents. Forcing\n  // 'gregory' here keeps every field of an ISO object's output anchored to\n  // the same (ISO/Gregorian) calendar — a locale's calendar extension only\n  // takes effect when the object itself already carries a non-ISO calendar\n  // (via `.withCalendar()`), matching what the README documents.\n  //\n  // 'gregory' specifically, not 'iso8601' — passing `calendar: 'iso8601'`\n  // explicitly alongside a single-field options object makes\n  // formatToParts() come back empty for some reason, but 'gregory' doesn't\n  // have that problem and Temporal's iso8601 calendar is Gregorian-shaped\n  // (proleptic Gregorian throughout, no Julian cutover) so the two agree\n  // on every numeric field this library ever reads.\n  const calendar = temporal?.calendarId;\n  const formatterOptions: Intl.DateTimeFormatOptions = {\n    ...options,\n    calendar: calendar && calendar !== 'iso8601' ? calendar : 'gregory',\n  };\n\n  // Field-bag guard: a plain { year, month, day } object only has\n  // Object.prototype.toLocaleString, which ignores both arguments and\n  // returns \"[object Object]\". On engines without native Temporal\n  // support in Intl this used to be caught below, but on engines where\n  // Intl *does* recognize native Temporal instances (Node 26+), a bag\n  // skips that branch entirely and reaches formatToParts() directly —\n  // which doesn't throw \"[object Object]\", it throws a bare\n  // \"RangeError: Invalid time value\" once the bag fails ToNumber()\n  // coercion. Neither failure mode is useful to a caller, so check for\n  // a real toLocaleString up front, before branching on native support,\n  // so the descriptive error fires on every engine.\n  const ls = temporal.toLocaleString;\n  if (typeof ls !== 'function' || ls === Object.prototype.toLocaleString) {\n    throw new Error(\n      `temporal-fmt: locale-aware part \"${partType}\" needs a value that implements ` +\n      `toLocaleString (a real Temporal object). A plain field bag cannot render ` +\n      `locale-aware names — pass a Temporal.PlainDate/PlainDateTime/ZonedDateTime.`\n    );\n  }\n\n  // Pre-1582 cutover guard. ICU's gregory calendar reinterprets dates\n  // before October 15, 1582 under Julian-calendar rules (see the long\n  // comment on isBeforeGregorianCutover above for the why), so for those\n  // dates Intl must never be handed the Temporal object itself — neither\n  // through formatToParts() below nor through toLocaleString() in the\n  // polyfill branch — since either route lets ICU's calendar math decide\n  // which month/weekday the date falls on, and that's exactly what the\n  // cutover corrupts. Route month/weekday name lookups through a safe\n  // modern reference date instead (preCutoverGregorianName above). Only\n  // month/weekday parts are affected: era is AD/CE either way for CE\n  // dates, and timeZoneName depends on the instant, not the calendar.\n  // Only Gregorian-shaped objects take this path — a Temporal object\n  // carrying a non-Gregorian calendar (hebrew, islamic, ...) has its\n  // month/weekday fields in that calendar already, and ICU's\n  // non-Gregorian calendars don't apply the Julian cutover at all, so\n  // feeding one through a gregory-keyed reference lookup would index the\n  // wrong month number into the wrong calendar. Custom vocabs never\n  // reach here (localeAwareName resolves them before calling intlPart).\n  if (\n    (partType === 'month' || partType === 'weekday') &&\n    formatterOptions.calendar === 'gregory' &&\n    isBeforeGregorianCutover(temporal)\n  ) {\n    return preCutoverGregorianName(temporal, locale, formatterOptions, partType);\n  }\n\n  // Temporal.prototype.toLocaleString() is part of the Temporal spec itself:\n  // polyfills implement the ICU formatting internally without needing the\n  // engine to recognize the object, so it works without native Intl support.\n  //\n  // Everything from here to the end of this function is genuinely\n  // reachable — NOT dead code — but only on a Node build where a global\n  // `Temporal` exists AND Intl.DateTimeFormat.formatToParts() recognizes\n  // native Temporal instances directly (this is real, observed to vary\n  // across Node versions: absent on the Node 22/24 builds this suite has\n  // been run against, present on at least one Node 26 build). This\n  // environment has no native Temporal (`typeof globalThis.Temporal ===\n  // 'undefined'`), so intlSupportsNativeTemporal() always returns false\n  // here and this branch can't be exercised from this test suite without\n  // faking native-instance recognition, which turned out to be\n  // impractical (Intl's native-Temporal detection isn't spoofable via a\n  // Proxy or valueOf() shim — see the M-02 regression test in\n  // temporalProvider.test.js for the same conclusion reached about the\n  // sibling probe function). Coverage numbers for this block will differ\n  // between Node versions for that reason; that's expected, not a\n  // regression.\n  /* c8 ignore start */\n  if (!intlSupportsNativeTemporal()) {\n    // normalizeLocaleTag: the active Temporal implementation's\n    // toLocaleString forwards the locale to Intl.DateTimeFormat, which\n    // (unlike this library's cache keys) rejects underscore-separated\n    // tags like 'en_US' outright.\n    // (Field-bag guard now runs unconditionally above, before this\n    // native-support branch, so it's not repeated here.)\n    try {\n      return ls.call(temporal, normalizeLocaleTag(locale), formatterOptions);\n    } catch (err) {\n      // The active Temporal implementation forwards the tag to Intl, which\n      // throws a bare RangeError for a malformed one — rethrow typed.\n      if (err instanceof RangeError) {\n        throw new InvalidLocaleError({ actual: locale, reason: err.message });\n      }\n      throw err;\n    }\n  }\n\n  // formatToParts() throws on ZonedDateTime directly (per spec), so convert\n  // to Instant and pass the zone via `timeZone` instead. Don't convert to\n  // PlainDateTime — that drops the zone, which breaks 'MMMM' + 'zzz' combos.\n  const { toInstant, timeZoneId } = temporal;\n  const isZoned = typeof toInstant === 'function' && typeof timeZoneId === 'string';\n  // has to be called as temporal.toInstant() because destructuring it off breaks\n  // the receiver and throws\n  const intlSafeTemporal = isZoned ? temporal.toInstant!() : temporal;\n  const nativeOptions: Intl.DateTimeFormatOptions = {\n    ...formatterOptions,\n    ...(isZoned ? { timeZone: timeZoneId } : {}),\n  };\n\n  const formatter = getFormatter(locale, nativeOptions);\n  const parts = formatter.formatToParts(intlSafeTemporal as Date | number);\n  const index = parts.findIndex((p) => p.type === partType);\n  if (index === -1) {\n    throw new Error(\n      `temporal-fmt: locale \"${locale}\" produced no \"${partType}\" part for this token. ` +\n      `This usually means the Temporal object is missing the field the token needs.`\n    );\n  }\n  // some locales (ja-JP) split a field across two parts — e.g. month \"8\"\n  // plus a counter suffix \"月\" as a separate sibling literal part. Merge in\n  // an adjacent literal only if it has no whitespace, so a genuine suffix\n  // gets folded in but an ordinary separator (the space before \"AM\") stays\n  // a separator. Mirrors partValue() in localeVocab.ts, which builds the\n  // vocab this token's output needs to match for parse() to round-trip.\n  let value = parts[index]!.value;\n  const prev = parts[index - 1];\n  const next = parts[index + 1];\n  if (prev?.type === 'literal' && !/\\s/.test(prev.value)) value = prev.value + value;\n  if (next?.type === 'literal' && !/\\s/.test(next.value)) value = value + next.value;\n  return value;\n}\n/* c8 ignore stop */\n\n// Temporal.prototype.toLocaleString() can't isolate a single field the way\n// formatToParts() can — asking for `hour` + `dayPeriod` together returns one\n// joined string (e.g. \"3 in the afternoon\"), and `dayPeriod` alone resolves\n// against a different, non-hour-anchored set of periods (\"in the\n// afternoon\"/\"昼\" instead of \"PM\"/\"午後\"). Day period only depends on the\n// hour anyway, so route it through a plain UTC Date and Intl.DateTimeFormat\n// instead — that's worked the same on every engine regardless of whether\n// Temporal itself is native or polyfilled.\nfunction dayPeriodPart(hour: number, locale: string): string {\n  // Custom vocab (when registered) takes precedence over Intl — same\n  // contract as the other locale-aware tokens. Intl won't know about a\n  // caller-supplied AM/PM string for a made-up locale key, so going\n  // through Intl would produce something other than what the caller\n  // registered.\n  const custom = getCustomVocab(locale);\n  if (custom) {\n    return hour < 12 ? custom.dayPeriod[0]! : custom.dayPeriod[1]!;\n  }\n  const date = new Date(Date.UTC(1970, 0, 1, hour));\n  const formatter = getFormatter(locale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n  const part = formatter.formatToParts(date).find((p) => p.type === 'dayPeriod');\n  // Defensive guard, confirmed unreachable on this ICU build: forcing\n  // hour12: true (as this call always does) produces a dayPeriod part\n  // for every locale checked, including 24-hour-clock locales (ja-JP,\n  // zh-CN, th-TH, he-IL) and a wide sweep of less-common tags (dz-BT,\n  // bo-CN, am-ET, etc.). Same finding as partValue()'s twin guard in\n  // localeVocab.ts. Kept in case a future ICU/locale-data update\n  // produces a locale that genuinely omits it.\n  /* c8 ignore start */\n  if (!part) {\n    throw new Error(`temporal-fmt: locale \"${locale}\" produced no \"dayPeriod\" part for token \"a\".`);\n  }\n  /* c8 ignore stop */\n  return part.value;\n}\n\n// Resolves a locale-aware month/weekday name from the registered custom\n// vocab when one exists for this locale, falling through to Intl otherwise.\n// Without this, format() would silently keep producing Intl's strings while\n// parse() matched against the registered vocab — the two would round-trip-fail\n// against each other.\nfunction localeAwareName(\n  temporal: TemporalLike,\n  locale: string,\n  options: Intl.DateTimeFormatOptions,\n  partType: Intl.DateTimeFormatPartTypes,\n  customArray: string[] | undefined,\n  customIndex: number | undefined,\n): string {\n  if (customArray && customIndex !== undefined && customIndex >= 0 && customIndex < customArray.length) {\n    return customArray[customIndex]!;\n  }\n  return intlPart(temporal, locale, options, partType);\n}\n\n// Formats a `±HH:MM` offset string (the shape Temporal exposes on\n// ZonedDateTime.prototype.offset) into one of the six offset-token widths.\n// Width and Z-handling come from the variant letter+case:\n//\n//   X / x   — short form: minutes omitted when zero, no colon otherwise\n//   XX / xx — hours + minutes, no colon\n//   XXX / xxx — hours + minutes, with colon\n//\n// Uppercase (X) collapses +00:00 to \"Z\"; lowercase (x) always emits a\n// numeric offset, even for UTC. Mirrors the date-fns/Unicode-LDML offset\n// family — see README for the full variant table.\nfunction formatOffset(offset: string, variant: 'X' | 'XX' | 'XXX' | 'x' | 'xx' | 'xxx'): string {\n  if (offset === '+00:00' && (variant === 'X' || variant === 'XX' || variant === 'XXX')) {\n    return 'Z';\n  }\n  // Most offsets are 6 chars: sign + HH + ':' + MM. Pre-1900 local-mean-time\n  // zones can surface a seconds component too, 9 chars: sign + HH + ':' +\n  // MM + ':' + SS. \"xxx\" is the one variant with a always-signed,\n  // never-\"Z\" colon-separated shape wide enough to carry that unchanged,\n  // so it passes a sub-minute offset through verbatim. Every other\n  // variant has no seconds slot and must throw rather than silently\n  // truncate them away.\n  if (offset.length > 6) {\n    if (variant === 'xxx') {\n      return offset;\n    }\n    throw new Error(\n      `temporal-fmt: token \"${variant}\" cannot represent the offset \"${offset}\", ` +\n      `which has a seconds component. None of the X/XX/XXX/x/xx tokens ` +\n      `support offset seconds; use \"xxx\" instead, which formats the full ` +\n      `offset unchanged.`\n    );\n  }\n  const sign = offset[0]!;\n  const hours = offset.slice(1, 3);\n  const minutes = offset.slice(4, 6);\n  switch (variant) {\n    case 'X': case 'x':\n      // minutes only matter when they're non-zero — otherwise drop them\n      // entirely. Matches LDML: \"With a single X, the hours field is\n      // required. The minutes field is optional, but only if the\n      // minutes value is 0.\"\n      return minutes === '00' ? `${sign}${hours}` : `${sign}${hours}${minutes}`;\n    case 'XX': case 'xx':\n      return `${sign}${hours}${minutes}`;\n    case 'XXX': case 'xxx':\n      return `${sign}${hours}:${minutes}`;\n  }\n}\n\ntype TokenHandler = (t: TemporalLike, locale: string) => string;\n\n// Longest-first — tokenizer is greedy, \"yyyy\" has to be tried before \"yy\".\n//\n// Numeric tokens always render in ASCII digits, never locale-native\n// (Arabic-Indic, Devanagari, etc). Padding non-ASCII digits isn't as simple\n// as padding \"3\", and most consumers parsing these back out want plain\n// digits anyway.\nexport const TOKENS: Array<[string, TokenHandler, keyof TemporalLike]> = [\n  ['yyyy', (t) => pad(t.year!, 4), 'year'],\n  ['yy', (t) => {\n    // -45 % 100 === -45, so truncating negative years to 2 digits doesn't\n    // work and Math.abs() would make 45 CE and 45 BCE render the same.\n    if (t.year! < 0) {\n      throw new Error(\n        `temporal-fmt: token \"yy\" doesn't support negative years (got ${t.year}), ` +\n        `since truncating to 2 digits would make it indistinguishable from a ` +\n        `positive year. Use \"yyyy\" instead.`\n      );\n    }\n    return pad(t.year! % 100, 2);\n  }, 'year'],\n  // Unpadded year — no minimum width, unlike yyyy's fixed 4 digits.\n  // pad(n, 0) still does the right thing here: Math.abs(n) with no\n  // padStart floor just yields the plain digit string, and the sign\n  // handling (split off before padding) already covers negative years,\n  // so this doesn't need its own sign branch the way \"yy\" does.\n  ['y', (t) => pad(t.year!, 0), 'year'],\n  ['MMMM', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { month: 'long' }, 'month', custom?.monthLong, t.month! - 1);\n  }, 'month'],\n  ['MMM', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { month: 'short' }, 'month', custom?.monthShort, t.month! - 1);\n  }, 'month'],\n  ['MM', (t) => pad(t.month!, 2), 'month'],\n  ['M', (t) => String(t.month!), 'month'],\n  ['dd', (t) => pad(t.day!, 2), 'day'],\n  ['d', (t) => String(t.day!), 'day'],\n  ['EEEE', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { weekday: 'long' }, 'weekday', custom?.weekdayLong, t.dayOfWeek! - 1);\n  }, 'dayOfWeek'],\n  ['EEE', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { weekday: 'short' }, 'weekday', custom?.weekdayShort, t.dayOfWeek! - 1);\n  }, 'dayOfWeek'],\n  ['HH', (t) => pad(t.hour!, 2), 'hour'],\n  ['H', (t) => String(t.hour!), 'hour'],\n  ['hh', (t) => pad(t.hour! % 12 || 12, 2), 'hour'],\n  ['h', (t) => String(t.hour! % 12 || 12), 'hour'],\n  ['mm', (t) => pad(t.minute!, 2), 'minute'],\n  ['m', (t) => String(t.minute!), 'minute'],\n  ['ss', (t) => pad(t.second!, 2), 'second'],\n  ['s', (t) => String(t.second!), 'second'],\n  // Fractional-second tokens, S through SSSSSSSSS (1-9 digits). Each token\n  // formats a slice of the same underlying nanosecond-of-second value —\n  // combining millisecond/microsecond/nanosecond into one 9-digit number\n  // and truncating to the token's width — so \"SSS\" keeps meaning exactly\n  // what it always meant (3-digit milliseconds) while wider tokens expose\n  // the precision Temporal actually carries. formatFraction below is the\n  // shared implementation; see its comment for the truncate-not-round\n  // rule and why.\n  ['SSSSSSSSS', (t) => pad.fraction(t, 9), 'millisecond'],\n  ['SSSSSSSS', (t) => pad.fraction(t, 8), 'millisecond'],\n  ['SSSSSSS', (t) => pad.fraction(t, 7), 'millisecond'],\n  ['SSSSSS', (t) => pad.fraction(t, 6), 'millisecond'],\n  ['SSSSS', (t) => pad.fraction(t, 5), 'millisecond'],\n  ['SSSS', (t) => pad.fraction(t, 4), 'millisecond'],\n  ['SSS', (t) => pad.fraction(t, 3), 'millisecond'],\n  ['SS', (t) => pad.fraction(t, 2), 'millisecond'],\n  ['S', (t) => pad.fraction(t, 1), 'millisecond'],\n  // dayPeriod text is locale-specific (AM/PM in en-US, م/ص in ar-EG) but\n  // still needs .hour on the input to compute which period it is\n  ['a', (t, locale) => dayPeriodPart(t.hour!, locale), 'hour'],\n  ['zzz', (t) => t.timeZoneId!, 'timeZoneId'],\n  // Numeric UTC offset tokens (date-fns/Unicode-LDML family). Only\n  // ZonedDateTime carries an offset, so the field check in format() throws\n  // the same \"requires offset, which this Temporal object doesn't have\"\n  // error zzz throws on PlainDate/PlainTime/PlainDateTime — same\n  // validation path, just a different field name. See formatOffset above\n  // for the per-variant width and Z/numeric distinction.\n  ['xxx', (t) => formatOffset(t.offset!, 'xxx'), 'offset'],\n  ['xx', (t) => formatOffset(t.offset!, 'xx'), 'offset'],\n  ['X', (t) => formatOffset(t.offset!, 'X'), 'offset'],\n  ['XX', (t) => formatOffset(t.offset!, 'XX'), 'offset'],\n  ['XXX', (t) => formatOffset(t.offset!, 'XXX'), 'offset'],\n  ['x', (t) => formatOffset(t.offset!, 'x'), 'offset'],\n\n  // Ordinal day (1st, 2nd, 3rd, ... 21st). English suffix rules only —\n  // locale-aware ordinals (\"2.\" in de-DE, \"2日\" in ja-JP) are out of scope,\n  // since the rest of this library routes locale-specific names through\n  // Intl.DateTimeFormat, and Intl has no part type for ordinals. Format-only:\n  // the suffix isn't structurally distinguishable from a literal in a parse\n  // context (a \"st\"/\"nd\"/\"rd\"/\"th\" suffix isn't a digit and would collide\n  // with any adjacent literal text), so there's no good way to read it back.\n  ['do', (t) => {\n    const day = t.day!;\n    const lastDigit = day % 10;\n    // 11, 12, 13 are the exception — they'd otherwise match the 1/2/3 rule\n    // and produce \"11st\"/\"12nd\"/\"13rd\", which is wrong. They always take \"th\".\n    const lastTwoDigits = day % 100;\n    if (lastTwoDigits >= 11 && lastTwoDigits <= 13) {\n      return day + 'th';\n    }\n    if (lastDigit === 1) return day + 'st';\n    if (lastDigit === 2) return day + 'nd';\n    if (lastDigit === 3) return day + 'rd';\n    return day + 'th';\n  }, 'day'],\n\n  // Quarter computed from month: 1-3=Q1, 4-6=Q2, 7-9=Q3, 10-12=Q4.\n  // `Q` is plain numeric, `QQQ` renders as \"Q3\" — same convention as\n  // date-fns's `Q` and `QQQ` for parity with the most common prior art.\n  // Both format and parse; parse() cross-checks Q/QQQ against the parsed\n  // month in the same spirit as the EEEE-vs-date cross-check.\n  ['Q', (t) => String(Math.ceil(t.month! / 3)), 'month'],\n  ['QQQ', (t) => 'Q' + Math.ceil(t.month! / 3), 'month'],\n\n  // ISO 8601 week and week-numbering year. Both are format-only — parsing\n  // \"ww\"/\"RRRR\" back into a real date requires resolving an ISO week + a\n  // weekday (or some other disambiguator) to a specific date, which is a\n  // different parsing surface than the token-based parse() here. The\n  // ISO-week year (RRRR) can differ from the calendar year at the boundary:\n  // Dec 29-31 often belong to week 1 of the *next* year; Jan 1-3 often\n  // belong to week 52/53 of the *previous* year. See isoWeekYearAndWeek().\n  ['ww', (t) => {\n    requireFields(t, 'ww', 'year', 'month', 'day');\n    const { week } = isoWeekYearAndWeek(t.year!, t.month!, t.day!, t.dayOfWeek!);\n    return pad(week, 2);\n  }, 'dayOfWeek'],\n  ['RRRR', (t) => {\n    requireFields(t, 'RRRR', 'year', 'month', 'day');\n    const { isoYear } = isoWeekYearAndWeek(t.year!, t.month!, t.day!, t.dayOfWeek!);\n    return pad(isoYear, 4);\n  }, 'dayOfWeek'],\n\n  // Day of year — number of days since Jan 1 (1-366). Three widths:\n  //   D    — unpadded (1, 2, 366)\n  //   DD   — 2-digit minimum (zero-padded if <100)\n  //   DDD  — 3-digit zero-padded (001, 002, 366)\n  // Format-only — parsing day-of-year requires resolving against a year,\n  // which is a different shape from the token-based parse() surface.\n  // The dayOfYearHelper() in calendarUtils.ts covers the same field for\n  // callers who need the numeric value.\n  ['D', (t) => {\n    requireFields(t, 'D', 'year', 'month');\n    return String(dayOfYear(t.year!, t.month!, t.day!));\n  }, 'day'],\n  ['DD', (t) => {\n    requireFields(t, 'DD', 'year', 'month');\n    return pad(dayOfYear(t.year!, t.month!, t.day!), 2);\n  }, 'day'],\n  ['DDD', (t) => {\n    requireFields(t, 'DDD', 'year', 'month');\n    return pad(dayOfYear(t.year!, t.month!, t.day!), 3);\n  }, 'day'],\n\n  // Stand-alone month — uses Intl's stand-alone form. In most locales\n  // (en, fr, de, es) this is identical to MMMM/MMM. In Slavic/Baltic\n  // locales (cs, sk, pl, ru) the stand-alone form differs from the\n  // format form (nominative vs genitive case). LLLL = long, LLL = short.\n  ['LLLL', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { month: 'long' }, 'month', custom?.monthLong, t.month! - 1);\n  }, 'month'],\n  ['LLL', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { month: 'short' }, 'month', custom?.monthShort, t.month! - 1);\n  }, 'month'],\n\n  // Stand-alone weekday — same pattern as stand-alone month but for\n  // weekday names. cccc = long, ccc = short.\n  ['cccc', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { weekday: 'long' }, 'weekday', custom?.weekdayLong, t.dayOfWeek! - 1);\n  }, 'dayOfWeek'],\n  ['ccc', (t, locale) => {\n    const custom = getCustomVocab(locale);\n    return localeAwareName(t, locale, { weekday: 'short' }, 'weekday', custom?.weekdayShort, t.dayOfWeek! - 1);\n  }, 'dayOfWeek'],\n\n  // Era — locale-aware (\"AD\"/\"BC\" in en, \"ap. J.-C.\"/\"av. J.-C.\" in fr).\n  // GGGG = long, G = short. Format-only.\n  ['GGGG', (t, locale) => {\n    return intlPart(t, locale, { era: 'long' }, 'era');\n  }, 'year'],\n  ['G', (t, locale) => {\n    return intlPart(t, locale, { era: 'short' }, 'era');\n  }, 'year'],\n\n  // Localized timezone name — uses Intl's longLocalized/short timezone\n  // name option. Format-only — these names are locale-dependent and\n  // vary by season (EST vs EDT), so parsing them back requires a\n  // lookup table that isn't practical to ship.\n  ['zzzz', (t, locale) => {\n    return intlPart(t, locale, { timeZoneName: 'longGeneric' as Intl.DateTimeFormatOptions['timeZoneName'] }, 'timeZoneName' as Intl.DateTimeFormatPartTypes);\n  }, 'timeZoneId'],\n  ['z', (t, locale) => {\n    return intlPart(t, locale, { timeZoneName: 'short' as Intl.DateTimeFormatOptions['timeZoneName'] }, 'timeZoneName' as Intl.DateTimeFormatPartTypes);\n  }, 'timeZoneId'],\n\n];\n\n// Mod-registered tokens, layered on top of the static TOKENS above.\n// Last-write-wins by name (same rule as registerLocale and\n// createFormatter's own token merging) — a second registerFormatToken()\n// call for a name already claimed, whether that name came from another\n// mod or from TOKENS itself, replaces the earlier entry. See\n// registerFormatToken() in runtime.ts for why this beats a hard error:\n// Mod.priority exists precisely so an author can control who wins a\n// shared key, and that only means something if collisions actually\n// resolve instead of throwing.\nconst registeredTokens = new Map<string, [string, TokenHandler, keyof TemporalLike]>();\n\n// tokenize.ts and format.ts each derive a lookup table from TOKENS at\n// import time (SORTED_TOKEN_STRINGS, HANDLER_BY_TOKEN). Once mods can\n// add tokens after those tables are built, something has to tell both\n// modules to rebuild — this is that hook. Both subscribers rebuild in\n// the same call so the tokenizer's idea of \"is this a token\" and\n// format()'s idea of \"what does this token do\" can never drift apart\n// (the c8-ignored \"impossible\" branches in format.ts assume exactly\n// that they can't).\nconst rebuildListeners: Array<() => void> = [];\n\nexport function onTokenTableChange(listener: () => void): void {\n  rebuildListeners.push(listener);\n}\n\n// All tokens currently in effect: built-ins plus mod-registered,\n// mod-registered winning on a name clash. Recomputed on every call\n// rather than cached here — registration only happens at mod-load\n// time, so there's no hot-path cost to paying for the rebuild each time\n// a listener fires.\nexport function getEffectiveTokens(): Array<[string, TokenHandler, keyof TemporalLike]> {\n  const merged = new Map(TOKENS.map((t) => [t[0], t] as const));\n  for (const [name, entry] of registeredTokens) merged.set(name, entry);\n  return [...merged.values()];\n}\n\nexport function registerToken(token: [string, TokenHandler, keyof TemporalLike]): void {\n  registeredTokens.set(token[0], token);\n  for (const listener of rebuildListeners) listener();\n}\n\n// Test-only: clears mod-registered tokens and notifies subscribers, so\n// one test file's registerFormatToken() call can't leak into the next.\n// Mirrors _resetOverridesForTesting() in runtime.ts.\nexport function _resetRegisteredTokensForTesting(): void {\n  registeredTokens.clear();\n  for (const listener of rebuildListeners) listener();\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TOKENS, getEffectiveTokens, onTokenTableChange } from './tokens.js';\nimport { FormatSyntaxError, UnknownTokenError } from './errors.js';\n\nexport type Piece =\n  | { kind: 'token'; value: string }\n  | { kind: 'literal'; value: string };\n\n// A piece plus its exact source span in the ORIGINAL format string.\n// `start`/`end` are UTF-16 code-unit indices, half-open [start, end).\n// Decoded literals can be shorter than their span ('' is 2 source\n// chars → 1 decoded quote), which is exactly why positions computed\n// from decoded lengths (the old approach in analyze.ts) drifted after\n// any quoted text.\nexport interface SpannedPiece {\n  kind: 'token' | 'literal';\n  value: string;\n  start: number;\n  end: number;\n}\n\n// gotta sort longest-first or the greedy scan grabs \"M\" when \"MMMM\" was actually there.\n// Starts from the static TOKENS (so this module works before any mod has\n// registered anything) and rebuilds from tokens.ts's getEffectiveTokens()\n// whenever a mod calls registerFormatToken — otherwise a token registered\n// after this module loaded would never be recognized here, and format()\n// would tokenize it as literal text even though HANDLER_BY_TOKEN in\n// format.ts knows about it. `let`, not `const`, precisely so the rebuild\n// below can replace the binding rather than mutate a shared array in place.\nlet SORTED_TOKEN_STRINGS = TOKENS.map(([tok]) => tok).sort((a, b) => b.length - a.length);\n\nonTokenTableChange(() => {\n  SORTED_TOKEN_STRINGS = getEffectiveTokens()\n    .map(([tok]) => tok)\n    .sort((a, b) => b.length - a.length);\n});\n\n/**\n * Splits a format string like `\"yyyy-MM-dd 'at' HH:mm\"` into token/literal\n * pieces, each with its exact source span. Text in single quotes is always\n * literal (e.g. write 'rd' in \"3rd\" so it's not read as the day token). A\n * doubled quote ('') means a literal quote character, both inside a quoted\n * span and standalone.\n */\nexport function tokenizeWithSpans(format: string): SpannedPiece[] {\n  const pieces: SpannedPiece[] = [];\n  let i = 0;\n\n  while (i < format.length) {\n    const ch = format[i];\n\n    if (ch === \"'\") {\n      // gotta check the doubled-quote case first, otherwise \"''best''\" parses wrong\n      if (format[i + 1] === \"'\") {\n        appendLiteral(pieces, \"'\", i, i + 2);\n        i += 2;\n        continue;\n      }\n\n      let j = i + 1;\n      let literal = '';\n      let closed = false;\n      while (j < format.length) {\n        if (format[j] === \"'\") {\n          if (format[j + 1] === \"'\") {\n            literal += \"'\";\n            j += 2;\n            continue;\n          }\n          closed = true;\n          j += 1;\n          break;\n        }\n        literal += format[j];\n        j += 1;\n      }\n\n      if (!closed) {\n        throw new FormatSyntaxError({\n          format,\n          message: `temporal-fmt: unterminated quote in format string \"${format}\"`,\n        });\n      }\n\n      appendLiteral(pieces, literal, i, j);\n      i = j;\n      continue;\n    }\n\n    const match = SORTED_TOKEN_STRINGS.find((tok) => format.startsWith(tok, i));\n    if (match) {\n      // this is already the longest token that starts here, so if there's\n      // one more of the same char after it, that's not a real token — it'd\n      // just silently fall through to whatever handles that next char and\n      // get glued onto this one. found this the hard way: \"zzzz\" was\n      // parsing as zzz + literal \"z\", \"MMMMM\" as MMMM + the M token. so now\n      // we just treat the whole overlong run as one bad token instead\n      const runChar = match[match.length - 1];\n      if (format[i + match.length] === runChar) {\n        let end = i + match.length;\n        while (format[end] === runChar) end += 1;\n        // UnknownTokenError, not FormatSyntaxError: wrapUntypedError's\n        // classifier already treats this exact message (\"isn't a\n        // recognized token\") as UNKNOWN_TOKEN (see errors.test.js's\n        // \"overlong token run classifies as UnknownTokenError\"), and a\n        // direct throw here needs to agree with what safeParse's fallback\n        // path would have classified it as.\n        throw new UnknownTokenError({\n          format,\n          token: format.slice(i, end),\n          message:\n            `temporal-fmt: \"${format.slice(i, end)}\" in format string \"${format}\" isn't a recognized token — ` +\n            `did you mean \"${match}\"?`,\n        });\n      }\n      pieces.push({ kind: 'token', value: match, start: i, end: i + match.length });\n      i += match.length;\n      continue;\n    }\n\n    // not a token or quote — pass through as-is\n    appendLiteral(pieces, ch, i, i + 1);\n    i += 1;\n  }\n\n  return pieces;\n}\n\n/**\n * Splits a format string like `\"yyyy-MM-dd 'at' HH:mm\"` into token/literal\n * pieces. Text in single quotes is always literal (e.g. write 'rd' in\n * \"3rd\" so it's not read as the day token). A doubled quote ('') means a\n * literal quote character, both inside a quoted span and standalone.\n */\nexport function tokenize(format: string): Piece[] {\n  return tokenizeWithSpans(format).map(({ kind, value }) => ({ kind, value }));\n}\n\n// merges into the previous piece if it's also a literal, so \"---\" is one\n// piece instead of three (spans track the full merged range)\nfunction appendLiteral(pieces: SpannedPiece[], value: string, start: number, end: number): void {\n  const last = pieces[pieces.length - 1];\n  if (last && last.kind === 'literal' && last.end === start) {\n    last.value += value;\n    last.end = end;\n  } else {\n    pieces.push({ kind: 'literal', value, start, end });\n  }\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// format strings are basically always short hand-written stuff like \"yyyy-MM-dd\"\n// so if something's way longer than that, cap it before tokenize() chokes on it\nexport const MAX_FORMAT_LENGTH = 1000;\nexport const MAX_INPUT_LENGTH = 100_000;","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// numbering systems. latn (ASCII digits) is the default, but arab, deva,\n// beng, etc are all options, configurable per format call.\n//\n// the tokens in this lib always spit out ASCII digits normally (check\n// tokens.ts's pad() — just String(n), which is ASCII). this module bolts\n// on the ability to convert that output to a locale's native digits via\n// Intl.NumberFormat, since that's the standard way JS does digit\n// transliteration anyway.\n//\n// parse side is stricter: parse() only accepts ASCII digits, matches how\n// NUMERIC_FRAGMENTS is already built. parseNumberingSystem converts\n// input digits to ASCII first — an explicit opt-in per call, never\n// silently accepting any numeral system that shows up.\n//\n// both directions also accept 'auto': instead of requiring the caller to\n// know the ICU numbering-system code for their locale, ask\n// Intl.NumberFormat(locale).resolvedOptions().numberingSystem what the\n// locale itself uses and transliterate with that.\n\nimport { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { InvalidLocaleError } from './errors.js';\nimport { canonicalCacheKey, normalizeLocaleTag } from './localeVocab.js';\n\nexport type NumberingSystem = 'latn' | 'arab' | 'deva' | 'beng' | 'guru' | 'gujr' | 'orya' | 'tamldec' | 'telu' | 'knda' | 'mlym' | 'fullwide' | 'hanidec';\n\n// What a caller may pass as numberingSystem / parseNumberingSystem: an\n// explicit system name, or 'auto' to derive the system from the call's\n// locale. The `(string & {})` keeps arbitrary strings compiling (the\n// runtime still validates them against SUPPORTED_NUMBERING_SYSTEMS and\n// throws on unknown names, unchanged) while editors still offer the\n// known literals — 'latn', 'arab', ..., 'auto' — as completions.\nexport type NumberingSystemOption = NumberingSystem | 'auto' | (string & {});\n\n// every NumberingSystem value we support. latn's the default and\n// what the rest of this lib naturally produces\nexport const SUPPORTED_NUMBERING_SYSTEMS: ReadonlySet<string> = new Set([\n  'latn', 'arab', 'deva', 'beng', 'guru', 'gujr', 'orya', 'tamldec',\n  'telu', 'knda', 'mlym', 'fullwide', 'hanidec',\n]);\n\nconst digitMapCache = new Map<string, Record<string, string>>();\n\n// 'auto' resolutions, keyed by canonical locale tag (same key discipline\n// as every other locale-keyed cache in this library — 'ar_EG' and 'ar-EG'\n// fold together instead of costing two entries). Intl.NumberFormat\n// construction isn't free and format() runs in loops (a table of dates, one\n// row per record), so resolve each locale once. Bounded, evicting the\n// oldest insertion, mirroring formatterCache in tokens.ts.\nconst autoNumberingCache = new Map<string, string>();\nconst MAX_AUTO_NUMBERING_CACHE = 500;\n\n// Turns 'auto' into a concrete system by asking Intl what the locale\n// itself defaults to (ar-EG -> arab, bn-BD -> beng, en-US -> latn). When\n// the locale's native system isn't one this library can transliterate\n// (thai, laoo, mymr, ... — anything outside SUPPORTED_NUMBERING_SYSTEMS),\n// fall back to 'latn' rather than throwing: 'auto' means \"use whatever\n// this locale naturally uses, if you can\", not \"throw on locales with\n// numerals this library doesn't cover\". A malformed locale tag DOES\n// throw — typed InvalidLocaleError, matching getFormatter() in tokens.ts —\n// since asking to derive from a locale that doesn't exist is a caller bug,\n// not a data condition to paper over.\nfunction resolveAutoNumberingSystem(locale: string): string {\n  const key = canonicalCacheKey(locale);\n  const cached = autoNumberingCache.get(key);\n  if (cached !== undefined) return cached;\n  let resolved: string;\n  try {\n    resolved = new Intl.NumberFormat(normalizeLocaleTag(locale)).resolvedOptions().numberingSystem;\n  } catch (err) {\n    throw new InvalidLocaleError({ actual: locale, reason: (err as Error).message });\n  }\n  const system = SUPPORTED_NUMBERING_SYSTEMS.has(resolved) ? resolved : 'latn';\n  if (autoNumberingCache.size >= MAX_AUTO_NUMBERING_CACHE) {\n    // not real LRU, just evicts oldest insertion — fine for this key space\n    const oldestKey = autoNumberingCache.keys().next().value;\n    if (oldestKey !== undefined) autoNumberingCache.delete(oldestKey);\n  }\n  autoNumberingCache.set(key, system);\n  return system;\n}\n\n// Shared front door for both option names. undefined stays 'latn' — the\n// default is unchanged; 'auto' is an opt-in, not a new default. Anything\n// else passes through untouched for convertDigits/convertDigitsToAscii\n// to validate against the supported set (they throw on unknown names).\nfunction resolveRequestedSystem(requested: string | undefined, locale: string | undefined): string {\n  if (requested === undefined) return 'latn';\n  if (requested === 'auto') return resolveAutoNumberingSystem(locale ?? DEFAULT_LOCALE);\n  return requested;\n}\n\n// builds a digit-transliteration map per numbering system. renders 0-9\n// through Intl.NumberFormat in the target system, then builds the lookup\n// table from that. caching it since spinning up a formatter isn't free\n// and we reuse the same map for every digit we convert\nfunction getDigitMap(system: string): Record<string, string> {\n  let map = digitMapCache.get(system);\n  if (map) return map;\n  /* c8 ignore start @preserve -- this branch is dead by construction, not\n     just untested: both callers (convertDigits, convertDigitsToAscii)\n     already bail out early on system === 'latn' before ever calling\n     getDigitMap, so it never actually gets invoked with 'latn'. keeping\n     it anyway as a defensive fallback rather than betting that stays\n     true forever */\n  if (system === 'latn') {\n    map = {};\n    for (let i = 0; i < 10; i++) map[String(i)] = String(i);\n  } else {\n    /* c8 ignore stop @preserve */\n    const fmt = new Intl.NumberFormat('en-US-u-nu-' + system, { useGrouping: false });\n    map = {};\n    for (let i = 0; i < 10; i++) {\n      map[String(i)] = fmt.format(i);\n    }\n  }\n  digitMapCache.set(system, map);\n  return map;\n}\n\n// swaps every ASCII digit in `s` for its equivalent in the target\n// numbering system. anything that's not a digit passes through untouched\nexport function convertDigits(s: string, system: string): string {\n  if (system === 'latn') return s;\n  if (!SUPPORTED_NUMBERING_SYSTEMS.has(system)) {\n    throw new InvalidLocaleError({ actual: system, reason: `numbering system \"${system}\" is not supported. Supported: ${[...SUPPORTED_NUMBERING_SYSTEMS].join(', ')}.` });\n  }\n  const map = getDigitMap(system);\n  let result = '';\n  for (const ch of s) {\n    if (ch >= '0' && ch <= '9') {\n      // map[ch] is always populated for 0-9 — getDigitMap builds all ten\n      // keys for every system we support, and ch is already range-checked\n      // above. the ?? ch is really just there to satisfy TS about Record's\n      // implicit undefined, not because this path is actually reachable\n      /* c8 ignore next */\n      result += map[ch] ?? ch;\n    } else {\n      result += ch;\n    }\n  }\n  return result;\n}\n\n// inverse of convertDigits — takes non-ASCII digits back to ASCII. used\n// by parse() when someone passes an explicit numberingSystem option.\n// throws on anything unsupported\nexport function convertDigitsToAscii(s: string, system: string): string {\n  // same dead-by-construction thing as the 'latn' guard above —\n  // applyParseNumbering (the only caller) already returns early on\n  // 'latn' before this ever gets called, so system's never actually\n  // 'latn' here in practice. leaving the guard anyway in case someone\n  // calls this directly someday without going through that guard\n  /* c8 ignore next */\n  if (system === 'latn') return s;\n  if (!SUPPORTED_NUMBERING_SYSTEMS.has(system)) {\n    throw new InvalidLocaleError({ actual: system, reason: `numbering system \"${system}\" is not supported.` });\n  }\n  const map = getDigitMap(system);\n  // just flip the map around\n  const reverse: Record<string, string> = {};\n  for (const k of Object.keys(map)) reverse[map[k]!] = k;\n  let result = '';\n  for (const ch of s) {\n    result += reverse[ch] ?? ch;\n  }\n  return result;\n}\n\n// FormatOptions plus a numberingSystem field. pass { numberingSystem: 'arab' }\n// to format() to get Arabic-Indic digits out, or { numberingSystem: 'auto' }\n// to use whichever numeral system the call's locale itself defaults to\n// (ar-EG -> arab, bn-BD -> beng, en-US -> latn), resolved via\n// Intl.NumberFormat(locale).resolvedOptions().numberingSystem with a\n// 'latn' fallback for locales whose native system isn't supported here.\n// Unset still means 'latn' — 'auto' is an opt-in, not a default change.\nexport interface NumberingFormatOptions extends FormatOptions {\n  numberingSystem?: NumberingSystemOption;\n}\n\n// same idea but for the parse side. called parseNumberingSystem instead of\n// just numberingSystem so someone mixing format() and parse() options in\n// one config object can set both independently — the two directions\n// aren't always symmetric (you might want native digits out without\n// wanting to accept them back in, or vice versa). 'auto' works here too,\n// resolving from the parse call's own locale the same way the format\n// side does.\nexport interface NumberingParseOptions extends FormatOptions {\n  parseNumberingSystem?: NumberingSystemOption;\n}\n\n// format-path helper: takes format()'s ASCII output and converts digits\n// if numberingSystem was asked for. lives here so format.ts doesn't need\n// to know anything about numbering systems\nexport function applyNumbering(s: string, options: NumberingFormatOptions): string {\n  const system = resolveRequestedSystem(options.numberingSystem, options.locale);\n  if (system === 'latn') return s;\n  return convertDigits(s, system);\n}\n\n// parse-path helper: converts input digits to ASCII before matching, if\n// parseNumberingSystem got set. kept as a separate option name from the\n// format side so callers can be explicit about which direction they\n// actually want transliterated\nexport function applyParseNumbering(s: string, options: { parseNumberingSystem?: string; locale?: string }): string {\n  // both call sites for this (both in parse.ts) already guard with\n  // `if (options.parseNumberingSystem)` before calling, so an undefined\n  // parseNumberingSystem never actually reaches here from parse() itself —\n  // the undefined handling inside resolveRequestedSystem is dead by\n  // construction from that direction. leaving it in as a safety net\n  // rather than betting every future caller replicates the same guard\n  // (this is a public export; direct calls don't come pre-guarded).\n  const system = resolveRequestedSystem(options.parseNumberingSystem, options.locale);\n  if (system === 'latn') return s;\n  return convertDigitsToAscii(s, system);\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TOKENS, DEFAULT_LOCALE, getEffectiveTokens, onTokenTableChange, type TemporalLike, type FormatOptions } from './tokens.js';\nimport { tokenize, type Piece } from './tokenize.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\nimport { applyNumbering, type NumberingFormatOptions } from './numbering.js';\nimport { FormatSyntaxError, UnknownTokenError } from './errors.js';\n\n// `let`, not `const` — rebuilt below whenever a mod registers a format\n// token, same reasoning as tokenize.ts's SORTED_TOKEN_STRINGS. Every\n// read site in this file reads the live binding at call time (none of\n// them capture it into a closure at import time), so reassigning here\n// is enough; nothing needs to hold a reference to the Map itself.\nlet HANDLER_BY_TOKEN = new Map(TOKENS.map(([tok, fn, field]) => [tok, { fn, field }]));\n\n// Pre-tokenized format strings, keyed by (formatStr) — locale doesn't\n// change the tokenization step, only the per-token rendering, so the\n// piece list is shared across locales. Same eviction shape as the\n// other caches in this library.\nconst tokenizeCache = new Map<string, Piece[]>();\nconst MAX_TOKENIZE_CACHE_SIZE = 500;\n\n// A mod's registerFormatToken() rebuilds both HANDLER_BY_TOKEN here and\n// tokenize.ts's own token-string list in the same synchronous listener\n// pass (tokens.ts's registerToken() calls every subscriber in turn) —\n// see the comment on tokens.ts's rebuildListeners for why the two can\n// never be allowed to drift apart. The tokenizeCache also has to be\n// cleared here: if some format string was already tokenized (and\n// cached) before this registration, the newly-registered token's\n// characters would be stuck as cached literal text forever otherwise —\n// this is the fix for exactly that staleness.\nonTokenTableChange(() => {\n  HANDLER_BY_TOKEN = new Map(getEffectiveTokens().map(([tok, fn, field]) => [tok, { fn, field }]));\n  tokenizeCache.clear();\n});\n\nfunction getPieces(formatStr: string): Piece[] {\n  let pieces = tokenizeCache.get(formatStr);\n  if (pieces) return pieces;\n  if (tokenizeCache.size >= MAX_TOKENIZE_CACHE_SIZE) {\n    const oldestKey = tokenizeCache.keys().next().value;\n    if (oldestKey !== undefined) tokenizeCache.delete(oldestKey);\n  }\n  pieces = tokenize(formatStr);\n  // Deep-freeze before caching: the SAME array instance is handed out\n  // by compileFormat().pieces and _getPieces() (documented as readonly\n  // inspection surface). Read-only at the type level alone didn't stop\n  // runtime mutation — a caller writing pieces[0].value used to poison\n  // the shared cache and corrupt every subsequent format() for that\n  // string process-wide. Frozen objects make the mutation attempt\n  // throw (ESM is strict mode) instead of silently corrupting state.\n  for (const piece of pieces) Object.freeze(piece);\n  Object.freeze(pieces);\n  tokenizeCache.set(formatStr, pieces);\n  return pieces;\n}\n\n/**\n * Format a Temporal.PlainDate, PlainTime, PlainDateTime, or ZonedDateTime\n * using a date-fns-style token string.\n *\n * @example\n * format(Temporal.Now.plainDateISO(), 'yyyy-MM-dd') // \"2026-08-04\"\n * format(zdt, \"MMM d, yyyy 'at' h:mm a\") // \"Aug 4, 2026 at 3:45 PM\"\n * format(zdt, 'MMMM d, yyyy', { locale: 'fr-FR' }) // \"août 4, 2026\"\n *\n * Throws on a token the input type doesn't support (e.g. 'HH' on a PlainDate).\n */\nexport function format(temporal: TemporalLike, formatStr: string, options: NumberingFormatOptions = {}): string {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n        `(got ${formatStr.length}).`,\n    });\n  }\n  // Null/undefined input used to leak a raw V8 TypeError from the\n  // first field read (\"Cannot read properties of null (reading 'year')\")\n  // — every other entry point validates its input with a typed error,\n  // and null/undefined is by far the most common wrong input. A null\n  // `options` object hits the same class (the default parameter only\n  // covers undefined).\n  if (temporal === null || temporal === undefined) {\n    throw new FormatSyntaxError({\n      input: String(temporal),\n      reason: `format() expected a Temporal.PlainDate / PlainTime / PlainDateTime / ZonedDateTime (or a TemporalLike field bag), got ${String(temporal)}`,\n    });\n  }\n  const opts = options ?? {};\n\n  const locale = opts.locale ?? DEFAULT_LOCALE;\n  const pieces = getPieces(formatStr);\n  let result = '';\n\n  for (const piece of pieces) {\n    if (piece.kind === 'literal') {\n      result += piece.value;\n      continue;\n    }\n\n    const handler = HANDLER_BY_TOKEN.get(piece.value);\n    /* c8 ignore start @preserve -- unreachable: tokenize() only ever emits\n       tokens present in TOKENS, and HANDLER_BY_TOKEN is built from that\n       same list, so every token piece.value can hold already has an entry\n       here. Same defensive-guard category as the twin checks in\n       analyze.ts/formatDuration.ts. */\n    if (!handler) {\n      throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token \"${piece.value}\"` });\n    }\n    /* c8 ignore stop @preserve */\n\n    if (temporal[handler.field] === undefined) {\n      throw new FormatSyntaxError({\n        format: formatStr,\n        token: piece.value,\n        message:\n          `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n          `which this Temporal object doesn't have. ` +\n          `(e.g. PlainDate has no time fields, PlainTime has no date fields)`,\n      });\n    }\n\n    result += handler.fn(temporal, locale);\n  }\n\n  // Numeral transliteration happens last and only on request — every\n  // upstream token handler still emits plain ASCII digits, so this is\n  // the single place output digits can diverge from that default.\n  return applyNumbering(result, opts);\n}\n\n// Shape mirrors Intl.DateTimeFormat.formatToParts: each entry is either\n// a literal (carrying no token info) or a token piece (carrying the\n// token string and the formatted value). Letting callers iterate parts\n// means they can build custom output — strip a token, swap a separator,\n// render each token to its own DOM node — without re-implementing the\n// tokenizer or the field-check logic.\nexport interface FormattedPart {\n  type: 'literal' | 'token';\n  value: string;\n  // Present when `type === 'token'`. Carries the token string (e.g. \"yyyy\")\n  // so a caller can look up its metadata via tokenInfo() from analyze.ts.\n  token?: string;\n}\n\nexport function formatToParts(temporal: TemporalLike, formatStr: string, options: NumberingFormatOptions = {}): FormattedPart[] {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n        `(got ${formatStr.length}).`,\n    });\n  }\n  const locale = options.locale ?? DEFAULT_LOCALE;\n  const pieces = getPieces(formatStr);\n  const result: FormattedPart[] = [];\n  for (const piece of pieces) {\n    if (piece.kind === 'literal') {\n      // Collapse adjacent literals so formatToParts stays consistent with\n      // how format() walks pieces — a multi-char literal \"at \" is one\n      // entry, not one per character. Same merge logic as appendLiteral\n      // in tokenize.ts.\n      const last = result[result.length - 1];\n      /* c8 ignore start @preserve -- unreachable through tokenize()'s own\n         output: appendLiteral() in tokenize.ts already merges every\n         adjacent literal character before pieces ever reaches here, so\n         two 'literal' pieces never sit back-to-back in the array this\n         loop walks. Kept as defense-in-depth in case that invariant ever\n         changes upstream. */\n      if (last && last.type === 'literal') {\n        last.value += piece.value;\n      } else {\n        /* c8 ignore stop @preserve */\n        result.push({ type: 'literal', value: piece.value });\n      }\n      continue;\n    }\n    const handler = HANDLER_BY_TOKEN.get(piece.value);\n    /* c8 ignore start @preserve -- unreachable, see the note in format() above */\n    if (!handler) {\n      throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token \"${piece.value}\"` });\n    }\n    /* c8 ignore stop @preserve */\n    if (temporal[handler.field] === undefined) {\n      throw new FormatSyntaxError({\n        format: formatStr,\n        token: piece.value,\n        message:\n          `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n          `which this Temporal object doesn't have. ` +\n          `(e.g. PlainDate has no time fields, PlainTime has no date fields)`,\n      });\n    }\n    // Numeral transliteration applies per-token-part here, rather than\n    // once at the end like format() does, so a caller styling individual\n    // parts (e.g. one <span> per token) still gets correctly-transliterated\n    // digits in each part instead of plain ASCII.\n    result.push({ type: 'token', value: applyNumbering(handler.fn(temporal, locale), options), token: piece.value });\n  }\n  return result;\n}\n\n// Pre-compiles a format string into an object whose format()/formatToParts()\n// methods skip the tokenization step on every call. The tokenizeCache in\n// this module means a plain format(temporal, fmt) call already pays only\n// a Map lookup for tokenization after the first call, so compileFormat()\n// is mostly a typing/ergonomics affordance — useful for callers who want\n// to hold onto a compiled form explicitly (e.g. to inspect the pieces\n// via the .pieces property, or to pass the compiled object around\n// instead of the string).\nexport interface CompiledFormat {\n  format(temporal: TemporalLike, options?: NumberingFormatOptions): string;\n  formatToParts(temporal: TemporalLike, options?: NumberingFormatOptions): FormattedPart[];\n  readonly pieces: ReadonlyArray<Piece>;\n  readonly formatStr: string;\n}\n\nexport function compileFormat(formatStr: string): CompiledFormat {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n        `(got ${formatStr.length}).`,\n    });\n  }\n  // Pre-tokenize once. Validation (unknown tokens, unterminated quotes)\n  // happens here, not lazily on first format() call — surfaces a bad\n  // format string at compile time rather than at first use, which is\n  // the point of compiling up front.\n  const pieces = getPieces(formatStr);\n  return {\n    formatStr,\n    pieces,\n    format(temporal: TemporalLike, options: NumberingFormatOptions = {}) {\n      const locale = options.locale ?? DEFAULT_LOCALE;\n      let result = '';\n      for (const piece of pieces) {\n        if (piece.kind === 'literal') {\n          result += piece.value;\n          continue;\n        }\n        const handler = HANDLER_BY_TOKEN.get(piece.value);\n        /* c8 ignore next -- unreachable, see the note in format() above */\n        if (!handler) throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token \"${piece.value}\"` });\n        if (temporal[handler.field] === undefined) {\n          throw new FormatSyntaxError({\n            format: formatStr,\n            token: piece.value,\n            message:\n              `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n              `which this Temporal object doesn't have. ` +\n              `(e.g. PlainDate has no time fields, PlainTime has no date fields)`,\n          });\n        }\n        result += handler.fn(temporal, locale);\n      }\n      return applyNumbering(result, options);\n    },\n    formatToParts(temporal: TemporalLike, options: NumberingFormatOptions = {}) {\n      const locale = options.locale ?? DEFAULT_LOCALE;\n      const out: FormattedPart[] = [];\n      for (const piece of pieces) {\n        if (piece.kind === 'literal') {\n          const last = out[out.length - 1];\n          /* c8 ignore next -- unreachable, see the note in formatToParts() above */\n          if (last && last.type === 'literal') last.value += piece.value;\n          else out.push({ type: 'literal', value: piece.value });\n          continue;\n        }\n        const handler = HANDLER_BY_TOKEN.get(piece.value);\n        /* c8 ignore next -- unreachable, see the note in format() above */\n        if (!handler) throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token \"${piece.value}\"` });\n        if (temporal[handler.field] === undefined) {\n          throw new FormatSyntaxError({\n            format: formatStr,\n            token: piece.value,\n            message:\n              `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n              `which this Temporal object doesn't have. ` +\n              `(e.g. PlainDate has no time fields, PlainTime has no date fields)`,\n          });\n        }\n        out.push({ type: 'token', value: applyNumbering(handler.fn(temporal, locale), options), token: piece.value });\n      }\n      return out;\n    },\n  };\n}\n\n// Exported so analyze.ts can reuse the same tokenization cache rather\n// than re-tokenizing when a caller asks for both a format() and an\n// analyzeFormat() on the same string.\nexport function _getPieces(formatStr: string): Piece[] {\n  return getPieces(formatStr);\n}\n\n// Exported for analyze.ts — same reason as above. The handler map is\n// the source of truth for \"what field does this token need\" — analyze\n// consumes it to compute requiredFields and compatibleTypes.\nexport function _handlerFor(token: string): { fn: (t: TemporalLike, locale: string) => string; field: keyof TemporalLike } | undefined {\n  return HANDLER_BY_TOKEN.get(token);\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getLocaleVocab } from './localeVocab.js';\nimport { UnknownTokenError } from './errors.js';\nimport { getTemporal } from './temporalProvider.js';\n\nfunction escapeRegExp(literal: string): string {\n  return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction alternation(values: string[], caseInsensitive = false): string {\n  const escaped = values.map(escapeRegExp);\n  if (!caseInsensitive) return `(?:${escaped.join('|')})`;\n  // JS regex has no per-group inline case-insensitive flag, and this\n  // fragment gets embedded in one larger pattern built with a single flag\n  // set — so case-folding here means listing both cases explicitly rather\n  // than relying on a flag.\n  return `(?:${escaped.map(foldCase).join('|')})`;\n}\n\n// Expands \"PM\" into a character-class-per-letter pattern matching any\n// casing of it (\"[Pp][Mm]\"), so \"pm\", \"Pm\", \"PM\" all match the same\n// alternative. Only used for the day-period token (see the 'a' case\n// below) — not applied to month/weekday names, where case-folding across\n// scripts is a different and riskier problem this doesn't need to solve.\nfunction foldCase(value: string): string {\n  return value.replace(/[a-zA-Z]/g, (ch) => `[${ch.toLowerCase()}${ch.toUpperCase()}]`);\n}\n\n// Every real IANA zone id is letters/digits/'_'/'+'/'-' segments joined by\n// '/' (e.g. \"America/Argentina/Buenos_Aires\", \"Etc/GMT+12\"); UTC and\n// fixed-offset strings are the only other shapes zzz accepts. Matching that\n// *shape* here — instead of alternating all ~400 zone names inline — keeps\n// the compiled regex small regardless of how many zzz tokens appear in a\n// format string. The captured text still gets checked against the real\n// zone set in isValidTimeZone() after the overall pattern matches, so this\n// is strictly a matching-cost change, not a validation-strictness change:\n// a bogus zone id fails \"no valid pattern matches\" exactly like it did when\n// the zone list was inlined (see isValidTimeZone's caller in parse.ts).\nconst TIME_ZONE_SHAPE = '(?:UTC|[+-]\\\\d{2}:\\\\d{2}(?::\\\\d{2}(?:\\\\.\\\\d{1,9})?)?|[A-Za-z_]+(?:[+-]\\\\d{1,2})?(?:\\\\/[A-Za-z0-9_+-]+)*)';\n\n// Per-variant regex shapes for the six offset tokens. Each matches the\n// shape its own format counterpart produces, so a round-trip\n// format->parse succeeds for any input the library itself emitted.\n//\n// Kept loose (no hour/minute range bounds inline) on purpose, mirroring\n// how TIME_ZONE_SHAPE is loose: a permissive shape here lets parse()\n// surface a descriptive out-of-range error post-match (see\n// parseOffsetString in parse.ts) instead of the generic \"no valid pattern\n// matches\" the regex throws when the shape itself fails. \"+99:99\" should\n// tell the user it's out of range, not look like the input never matched\n// the format at all.\n//\n// X / x accept an optional minutes group so whole-hour offsets can be\n// written short (\"+05\") while non-whole-hour offsets still parse\n// (\"+0530\"). The optional group is greedy, so for input \"+0530\" the\n// engine prefers the 4-digit match; only falls back to 2-digit when\n// there's nothing else to consume — same longer-first preference the\n// unpadded numeric tokens use elsewhere in this file (see the comment on\n// NUMERIC_FRAGMENTS).\nconst OFFSET_SHAPES: Record<string, string> = {\n  X:   '(?:Z|[+-]\\\\d{2}(?:\\\\d{2})?)',\n  XX:  '(?:Z|[+-]\\\\d{4})',\n  XXX: '(?:Z|[+-]\\\\d{2}:\\\\d{2})',\n  x:   '[+-]\\\\d{2}(?:\\\\d{2})?',\n  xx:  '[+-]\\\\d{4}',\n  xxx: '[+-]\\\\d{2}:\\\\d{2}',\n};\n\nfunction getTimeZoneFragment(): string {\n  return TIME_ZONE_SHAPE;\n}\n\nlet validZoneSet: Set<string> | undefined;\n\n// Real zone ids plus the couple of aliases zzz has always accepted even\n// though Intl.supportedValuesOf('timeZone') doesn't list them (UTC isn't\n// itself an IANA zone name, it's the identity offset).\nfunction getValidZoneSet(): Set<string> {\n  if (!validZoneSet) {\n    validZoneSet = new Set(Intl.supportedValuesOf('timeZone'));\n    validZoneSet.add('UTC');\n  }\n  return validZoneSet;\n}\n\nconst FIXED_OFFSET_RE = /^[+-]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?$/;\n\n// Called post-match on whatever the bounded TIME_ZONE_SHAPE captured, since\n// that shape is deliberately looser than \"a real zone id\" (it has to be, to\n// stay a fixed-size regex fragment — see the comment above). A fixed offset\n// is valid by construction; anything else has to be a real IANA name.\n//\n// Intl.supportedValuesOf('timeZone') is checked first as a fast path — it's\n// a plain Set lookup and covers the overwhelming majority of real input.\n// But it lists only canonical zone ids, not every IANA link/alias name:\n// \"Asia/Kolkata\" is a legitimate, commonly-used alias for \"Asia/Calcutta\"\n// that Temporal.ZonedDateTime.from() itself resolves correctly, yet some\n// ICU builds' supportedValuesOf() omits it. Rejecting it here — even\n// though the exact same string would construct a real ZonedDateTime one\n// call later — was a real bug: parse() refused input its own downstream\n// construction step would have accepted. Anything Intl doesn't recognize\n// gets a second check against Temporal itself before being refused.\nexport function isValidTimeZone(raw: string): boolean {\n  if (FIXED_OFFSET_RE.test(raw) || getValidZoneSet().has(raw)) return true;\n  try {\n    getTemporal().ZonedDateTime.from({\n      year: 2026, month: 1, day: 1, hour: 0, minute: 0, second: 0,\n      timeZone: raw,\n    });\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// mirrors the ranges pad() in tokens.ts actually produces — keep in sync\n// if those ever change\n//\n// Unpadded alternatives (M, H, h, m, s) list the longer branch first\n// (e.g. '1[0-2]|[1-9]', not '[1-9]|1[0-2]'). This matters only when two\n// unpadded tokens are glued with no separator: with short-first ordering,\n// a regex engine takes the first successful overall match, and won't\n// backtrack into a token's second alternative unless its first choice\n// makes the *rest* of the pattern fail outright. If the short reading also\n// happens to leave a valid match for the next token, the engine stops\n// there — silently, deterministically, and with no relation to which\n// reading a human intended. E.g. \"Md\" against \"121\": short-first order\n// resolves it as month=1/day=21 (M grabs '1', d gets '21', which is a\n// valid day) instead of month=12/day=1. Longer-first ordering fixes this\n// by making the greedy match try to consume as many digits as possible\n// before ever handing digits to the next token, which is the reading\n// that matches how format() itself produces glued output in the first\n// place (format() always emits the token's natural width, so decoding\n// should prefer the same). Found via the token×token combinatorial glue\n// matrix in combinatorial.test.js — see that file for the full case list.\nconst NUMERIC_FRAGMENTS: Record<string, string> = {\n  yy: '\\\\d{2}',\n  MM: '(?:0[1-9]|1[0-2])',\n  M: '(?:1[0-2]|[1-9])',\n  dd: '(?:0[1-9]|[12]\\\\d|3[01])',\n  d: '(?:[12]\\\\d|3[01]|[1-9])',\n  HH: '(?:[01]\\\\d|2[0-3])',\n  H: '(?:1\\\\d|2[0-3]|[0-9])',\n  hh: '(?:0[1-9]|1[0-2])',\n  h: '(?:1[0-2]|[1-9])',\n  mm: '(?:[0-5]\\\\d)',\n  m: '(?:[1-5]\\\\d|[0-9])',\n  ss: '(?:[0-5]\\\\d)',\n  s: '(?:[1-5]\\\\d|[0-9])',\n  SSSSSSSSS: '\\\\d{9}',\n  SSSSSSSS: '\\\\d{8}',\n  SSSSSSS: '\\\\d{7}',\n  SSSSSS: '\\\\d{6}',\n  SSSSS: '\\\\d{5}',\n  SSSS: '\\\\d{4}',\n  SSS: '\\\\d{3}',\n  SS: '\\\\d{2}',\n  S: '\\\\d',\n  // Q is always a single digit 1-4 (no padding variant, so no width ambiguity\n  // with adjacent digit tokens the way M/d/H/m/s have).\n  Q: '[1-4]',\n};\n\n// QQQ matches its own formatted output: the literal \"Q\" prefix plus a single\n// digit 1-4. Kept as a static fragment rather than routed through vocab,\n// since the \"Q\" prefix is part of the token's own contract, not locale-vocab\n// data that could ever differ.\nconst QQQ_FRAGMENT = 'Q[1-4]';\n\n// Format-only tokens — they have no parse counterpart. The tokenizer still\n// recognizes them (so format() can use them), but parse()'s regex builder\n// rejects them with a clear error rather than silently dropping the token\n// or falling through to the generic \"unknown token\" message.\n// Exported so analyze.ts can include them in the public analyzer surface.\nexport const FORMAT_ONLY_TOKENS = new Set(['do', 'ww', 'RRRR', 'D', 'DD', 'DDD', 'LLLL', 'LLL', 'cccc', 'ccc', 'GGGG', 'G', 'zzzz', 'z']);\n\n// pad()'s year formatter (tokens.ts) never truncates: it preserves the sign\n// for BCE years and doesn't cap width past 9999, so a formatted \"yyyy\" can\n// be longer than 4 digits or start with '-'. YYYY_EXTENDED accepts that;\n// YYYY_EXACT is the plain 4-unsigned-digit case. Which one a given \"yyyy\"\n// occurrence gets depends on what follows it — see buildCapturingPattern in\n// parsePattern.ts. Two separate fragments instead of one `-?\\d{4,}` because\n// an open-ended-width year directly followed by another digit token (e.g.\n// \"yyyyMM\") lets the year's own greediness silently eat digits meant for\n// the next token — same class of bug as UNPADDED_NUMERIC_TOKENS below, but\n// unbounded-width, so it can't reuse enumerateValidSplits' fixed-range\n// splitting. Restricting to exactly 4 digits whenever something could\n// follow closes that off entirely, at the cost of \"yyyyMM\" not being able\n// to represent a 5-digit year — an already-rare case doubly rare in\n// combination with a glued adjacent token.\nconst YYYY_EXACT = '-?\\\\d{4}';\nconst YYYY_EXTENDED = '-?\\\\d{4,}';\n\n// \"y\" is yyyy's unpadded sibling: any width, 1 digit up through Temporal's\n// max supported year (275760), with the same optional leading \"-\" for\n// years before ISO year 0. Unlike yyyy, there's no bounded fallback to\n// reach for when something digit-consuming follows — yyyy can fall back\n// to an exact 4 digits because it's always exactly 4 digits in that case,\n// but \"y\" being unpadded is the entire point of the token, so there's no\n// narrower shape that still means the same thing. buildCapturingPattern\n// (parsePattern.ts) refuses to build a pattern where \"y\" is immediately\n// followed by another digit-consuming element, rather than trying to\n// bound this fragment the way YYYY_EXACT does.\nconst Y_FRAGMENT = '-?\\\\d+';\n\n// True for any token whose matched text can start with a digit — i.e.\n// every token here except the locale-named ones (MMMM/MMM/EEEE/EEE/a) and\n// zzz (which can start with a digit only via a fixed offset like \"+09:00\",\n// already handled by requiring a leading sign there). Used to decide\n// whether a \"yyyy\" immediately before this token needs the exact-4-digit\n// fragment instead of the open-ended one.\n// Exported for parsePattern.ts's ReDoS guard: a token whose regex\n// fragment can begin with a bare digit (see the guard comments there).\nexport const DIGIT_LEADING_TOKENS = new Set([\n  'yyyy', 'yy', 'y', 'MM', 'M', 'dd', 'd', 'HH', 'H', 'hh', 'h', 'mm', 'm', 'ss', 's',\n  'SSSSSSSSS', 'SSSSSSSS', 'SSSSSSS', 'SSSSSS', 'SSSSS', 'SSSS', 'SSS', 'SS', 'S',\n]);\n\n// Tokens whose regex fragment has no upper bound on width — nothing\n// caps how many digits they might consume. yyyy's YYYY_EXTENDED form is\n// also unbounded, but it's only ever selected when the *next* piece\n// already isn't digit-consuming (see tokenFragment below), so by\n// construction it never reaches a position where the ambiguity guard in\n// parsePattern.ts would need to weigh in. \"y\" has no such self-limiting\n// selection rule — it's unbounded unconditionally — so it needs an\n// explicit guard there instead of a bit-cost estimate: there's no\n// meaningful number of \"width choices\" to assign to \"any number of\n// digits,\" so parsePattern.ts refuses outright rather than pretending a\n// finite ambiguity score covers it.\nexport const UNBOUNDED_WIDTH_TOKENS = new Set(['y']);\n\nexport function tokenFragment(token: string, locale: string, nextToken?: string): string {\n  if (token === 'yyyy') {\n    return nextToken !== undefined && DIGIT_LEADING_TOKENS.has(nextToken) ? YYYY_EXACT : YYYY_EXTENDED;\n  }\n  if (token === 'y') {\n    return Y_FRAGMENT;\n  }\n\n  const numeric = NUMERIC_FRAGMENTS[token];\n  if (numeric) {\n    return numeric;\n  }\n\n  if (token === 'QQQ') {\n    return QQQ_FRAGMENT;\n  }\n\n  if (FORMAT_ONLY_TOKENS.has(token)) {\n    throw new UnknownTokenError({\n      token,\n      message:\n        `temporal-fmt: token \"${token}\" is format-only — it can't be parsed back into a value. ` +\n        `Use a different token in the parse format string (e.g. \"d\" for \"do\", \"MM\" for \"ww\").`,\n    });\n  }\n\n  const vocab = getLocaleVocab(locale);\n  switch (token) {\n    case 'MMMM': return alternation(vocab.monthLong);\n    case 'MMM': return alternation(vocab.monthShort);\n    case 'EEEE': return alternation(vocab.weekdayLong);\n    case 'EEE': return alternation(vocab.weekdayShort);\n    // Case-insensitive on purpose: \"pm\"/\"Pm\"/\"PM\" all mean the same thing,\n    // and unlike the Md-glue ambiguity elsewhere in this file, there's no\n    // second valid reading to guess wrong — so rejecting on case buys no\n    // correctness, only friction against real-world data (mixed-case CSV\n    // exports, lowercase log timestamps).\n    case 'a': return alternation(vocab.dayPeriod, true);\n    case 'zzz': return getTimeZoneFragment();\n    case 'X': case 'XX': case 'XXX':\n    case 'x': case 'xx': case 'xxx':\n      return OFFSET_SHAPES[token]!;\n    /* c8 ignore start @preserve -- defensive guard, not reachable through\n       the public API. tokenFragment's only caller (buildCapturingPattern\n       in parsePattern.ts) always passes piece.value straight from\n       tokenize.ts, which only ever emits strings from tokens.ts's TOKENS\n       table. Every token in that table is handled above: the numeric\n       ones via NUMERIC_FRAGMENTS, QQQ via QQQ_FRAGMENT, the format-only\n       ones via the FORMAT_ONLY_TOKENS check earlier in this function, and\n       everything else via one of the switch cases. There's no token\n       string that can reach this default without either tokens.ts\n       registering something new or tokenize.ts being bypassed, neither of\n       which happens on the parse() path. */\n    default:\n      throw new UnknownTokenError({ token, message: `temporal-fmt: unknown token \"${token}\"` });\n    /* c8 ignore stop @preserve */\n  }\n}\n\n// Tokens whose fragment is variable-width (1-2 digits, no leading zero).\n// Two or more of these glued with no literal separator between them can\n// have more than one digit-split that's independently valid against every\n// fragment in the run — see the big comment on NUMERIC_FRAGMENTS above.\n// Reordering alternation branches picks a winner for *some* of these\n// cases, but can't make both directions of a pair (e.g. \"Md\" and \"dM\")\n// agree, because the ambiguity is in the input string itself, not in how\n// any one fragment is written. exported so parsePattern.ts can find runs\n// of these that need split-counting at match time instead of a single\n// fixed regex.\nexport const UNPADDED_NUMERIC_TOKENS = new Set(['M', 'd', 'H', 'h', 'm', 's']);\n\n// Every accept width for a given unpadded numeric token, as plain min/max\n// value + digit-length pairs — used to enumerate candidate splits of a\n// digit run at match time. Mirrors NUMERIC_FRAGMENTS's semantics exactly\n// (same accepted values), just as data instead of regex source, since\n// enumerating splits against a compiled regex per-candidate would be\n// slower and harder to reason about than checking numeric ranges directly.\nexport const UNPADDED_NUMERIC_RANGES: Record<string, Array<{ digits: 1 | 2; min: number; max: number }>> = {\n  M: [{ digits: 1, min: 1, max: 9 }, { digits: 2, min: 10, max: 12 }],\n  d: [{ digits: 1, min: 1, max: 9 }, { digits: 2, min: 10, max: 31 }],\n  H: [{ digits: 1, min: 0, max: 9 }, { digits: 2, min: 10, max: 23 }],\n  h: [{ digits: 1, min: 1, max: 9 }, { digits: 2, min: 10, max: 12 }],\n  m: [{ digits: 1, min: 0, max: 9 }, { digits: 2, min: 10, max: 59 }],\n  s: [{ digits: 1, min: 0, max: 9 }, { digits: 2, min: 10, max: 59 }],\n};\n\n/**\n * Given the literal digit string a run of N adjacent unpadded-numeric\n * tokens matched as a whole (e.g. \"112\" for a 2-token run), enumerates\n * every way to split it into N pieces (one per token, each piece 1-2\n * digits per that token's own width rule) and returns every split where\n * every piece is independently valid for its token. Length 0 means the\n * run's regex match shouldn't have been possible in the first place\n * (shouldn't happen — the caller only invokes this after the whole\n * pattern already matched, meaning at least one split exists: the one the\n * regex actually took). Length 1 means the reading is unambiguous.\n * Length 2+ means true ambiguity — the caller should throw rather than\n * pick one.\n *\n * Recursive over token count rather than hardcoded to 2, so a 3+ token\n * unseparated run (e.g. \"Hms\") is covered by the same logic without a\n * special case — those are rarer in practice but not impossible, and a\n * partial fix that only covered pairs would leave the identical bug for\n * anyone writing a 3-token glued run.\n */\nexport function enumerateValidSplits(digits: string, tokens: string[]): number[][] {\n  const memo = new Map<string, number[][]>();\n\n  function solve(tokenIndex: number, offset: number): number[][] {\n    const key = `${tokenIndex}:${offset}`;\n    const cached = memo.get(key);\n    if (cached) {\n      return cached;\n    }\n\n    if (tokenIndex === tokens.length) {\n      const result = offset === digits.length ? [[]] : [];\n      memo.set(key, result);\n      return result;\n    }\n\n    const token = tokens[tokenIndex];\n    const ranges = UNPADDED_NUMERIC_RANGES[token!];\n    /* c8 ignore start @preserve -- defensive guard, not reachable through\n       the public API. enumerateValidSplits's only caller (parse.ts, both\n       call sites) passes run.tokens straight from\n       pattern.ambiguousRuns, which parsePattern.ts only ever populates\n       with tokens already checked against UNPADDED_NUMERIC_TOKENS — the\n       exact same key set as UNPADDED_NUMERIC_RANGES. There's no path\n       where a token reaches here without having already passed that\n       check. */\n    if (!ranges) {\n      throw new Error(`temporal-fmt: internal error — \"${token}\" is not an unpadded numeric token`);\n    }\n    /* c8 ignore stop @preserve */\n\n    const results: number[][] = [];\n    for (const { digits: width, min, max } of ranges) {\n      if (offset + width > digits.length) continue;\n      const piece = digits.slice(offset, offset + width);\n      if (width === 2 && piece[0] === '0') continue;\n      const value = Number(piece);\n      if (value < min || value > max) continue;\n\n      for (const restSplit of solve(tokenIndex + 1, offset + width)) {\n        results.push([value, ...restSplit]);\n        if (results.length === 2) break;\n      }\n      if (results.length === 2) break;\n    }\n\n    memo.set(key, results);\n    return results;\n  }\n\n  return solve(0, 0);\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Piece } from './tokenize.js';\nimport { tokenFragment, UNPADDED_NUMERIC_TOKENS, DIGIT_LEADING_TOKENS, UNBOUNDED_WIDTH_TOKENS } from './pattern.js';\nimport { FormatSyntaxError } from './errors.js';\n\nfunction escapeRegExp(literal: string): string {\n  return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// this guards against catastrophic backtracking (ReDoS) in the generated regex.\n//\n// every ReDoS we've actually found in this lib has the same shape: two+\n// variable-width digit-consuming regex fragments sitting next to each other\n// with nothing to tell the engine where one ends and the next starts —\n// either glued straight together (\"MdMdMd...\", \"HmsHms...\") or separated\n// only by a literal that itself starts with a digit (\"M1M1M1...\",\n// \"yyyy1yyyy1...\"). each fragment then has multiple ways to split up the\n// digit run, and on a failing match the engine tries every combination —\n// exponential in the number of fragments. measured this against the old\n// code: \"Md\"×13 (26-char format, 40-char input) took about 2.7s; \"yyyy1\"×8\n// (48-char format) took about 26s. both roughly ×3-14 worse per extra\n// fragment, so it gets bad fast.\n//\n// three fixes, all at pattern-build time:\n//\n//  1. a run of 2+ glued unpadded-numeric tokens now becomes ONE bounded\n//     digit group `(?<rN>\\d{R,2R})` instead of R separate variable-width\n//     fragments. the per-token split still gets resolved after the match,\n//     via enumerateValidSplits() in pattern.ts — same machinery parse()\n//     already used for detecting ambiguous glued runs, so behavior's\n//     unchanged (unique split resolves, 2+ valid splits throws in strict\n//     mode / gets heuristic-picked in lenient, 0 splits is a mismatch).\n//     a lone \\d{R,2R} group only backtracks R+1 times max — linear, not\n//     exponential.\n//\n//  2. yyyy now uses the exact -?\\d{4} fragment not just when the next\n//     TOKEN is digit-leading (that rule already existed) but also when\n//     the next LITERAL starts with a digit. an open-ended -?\\d{4,} year\n//     glued right up against a digit literal is basically the cheapest\n//     possible exponential blowup (unbounded width choices per year), and\n//     the exact form still matches everything the open form did in that\n//     spot except 5+ digit years glued directly to an unquoted digit\n//     literal — a genuinely pathological edge case we're fine trading away.\n//\n//  3. for whatever's left: every adjacency between a variable-width digit\n//     consumer (lone unpadded token, or a glued-run group) and a\n//     digit-consuming successor costs log2 of the consumer's width\n//     choices, added to a running \"ambiguity budget\". go over\n//     MAX_AMBIGUITY_BITS (12 — hard ceiling of 4096 backtrack paths) and\n//     we just reject the format string at build time with a\n//     FormatSyntaxError. normal format strings score 0-3. the\n//     \"M1M1M1...\" attack pattern scores one bit per glued pair.\nconst MAX_AMBIGUITY_BITS = 12;\n\nfunction widthChoicesBits(choices: number): number {\n  return Math.ceil(Math.log2(Math.max(choices, 1)));\n}\n\n// does this piece's regex fragment start by eating a bare digit? (tokens\n// that can match starting with 0-9, and literals whose first char is a\n// digit.) used to spot the boundaries where a variable-width digit\n// consumer before it could end up trading digits with whatever follows\nfunction isDigitConsumingStart(piece: Piece | undefined): boolean {\n  if (piece === undefined) return false;\n  if (piece.kind === 'literal') return /^[0-9]/.test(piece.value);\n  return DIGIT_LEADING_TOKENS.has(piece.value);\n}\n\nexport interface CapturingPattern {\n  regex: RegExp;\n  groups: Array<{ name: string; token: string }>; // token pieces, in order\n  // runs of 2+ adjacent unpadded-numeric tokens glued together with no\n  // literal separator (e.g. \"Md\", \"Hms\"). each run gets captured by ONE\n  // regex group named `groupName` spanning the whole digit run (R..2R\n  // digits) — per-token values get pulled out later by\n  // enumerateValidSplits() at match time. `groupNames` is the per-token\n  // group names, which show up in `groups` for structure/position but\n  // don't actually exist in the regex itself, so anyone consuming this\n  // needs to read values from the split enumeration, not match.groups\n  ambiguousRuns: Array<{ groupName: string; groupNames: string[]; tokens: string[] }>;\n}\n\n/**\n * Same walk as buildPatternSource() in pattern.ts, but each token piece\n * gets its own named capture group (positionally named so the same token,\n * e.g. \"yyyy\", could in theory appear twice) so a caller can pull the\n * matched substring for each token back out after a successful match.\n */\nexport function buildCapturingPattern(pieces: Piece[], locale: string): CapturingPattern {\n  const groups: Array<{ name: string; token: string }> = [];\n  const ambiguousRuns: Array<{ groupName: string; groupNames: string[]; tokens: string[] }> = [];\n  let source = '';\n  let i = 0;\n  let ambiguityBits = 0;\n\n  // tracks the current run of adjacent unpadded-numeric pieces (nothing's\n  // broken it yet — no literal, no non-unpadded token). names get recorded\n  // in order so a run of 2+ can collapse into one group while each token\n  // still gets its own entry in `groups`\n  let currentRun: { names: string[]; tokens: string[] } = { names: [], tokens: [] };\n\n  const flushRun = (nextPiece: Piece | undefined) => {\n    if (currentRun.tokens.length === 1) {\n      // a lone unpadded token just gets its normal two-way fragment.\n      // two width choices on their own aren't a problem; only charge an\n      // ambiguity bit if the next thing can also eat a digit\n      const name = currentRun.names[0]!;\n      const token = currentRun.tokens[0]!;\n      source += `(?<${name}>${tokenFragment(token, locale)})`;\n      if (isDigitConsumingStart(nextPiece)) ambiguityBits += 1;\n    } else if (currentRun.tokens.length >= 2) {\n      // emit the whole accumulated run as ONE bounded digit group. R\n      // unpadded tokens together accept somewhere between R and 2R digits\n      // total, and anything outside that range can't match no matter how\n      // you split it — so this single group covers exactly the same\n      // territory the old per-token fragments did, just without the\n      // combinatorial backtracking. worst case here is R+1 width choices,\n      // which is linear\n      const runName = `r${i++}`;\n      const tokenCount = currentRun.tokens.length;\n      source += `(?<${runName}>\\\\d{${tokenCount},${tokenCount * 2}})`;\n      // note: no `groups` entry for the run group itself — `groups` only\n      // lists per-token pieces (already pushed when we visited them), so\n      // consumers like parseToParts still see exactly one entry per token,\n      // same as before this run-group thing existed. the regex group\n      // itself is only reachable through ambiguousRuns[].groupName\n      ambiguousRuns.push({\n        groupName: runName,\n        groupNames: currentRun.names,\n        tokens: currentRun.tokens,\n      });\n      // a run group next to a digit-consuming successor still keeps its\n      // (R+1) width choices at that boundary, so charge the budget for it\n      if (isDigitConsumingStart(nextPiece)) {\n        ambiguityBits += widthChoicesBits(tokenCount + 1);\n      }\n    }\n    currentRun = { names: [], tokens: [] };\n  };\n\n  for (const [idx, piece] of pieces.entries()) {\n    if (piece.kind === 'literal') {\n      flushRun(piece);\n      source += escapeRegExp(piece.value);\n      continue;\n    }\n\n    if (UNPADDED_NUMERIC_TOKENS.has(piece.value)) {\n      // part of a (possible) glued run — hold off emitting the fragment\n      // and let flushRun deal with it, so 2+ in a row collapse into one\n      // bounded group instead of staying separate\n      const name = `g${i++}`;\n      groups.push({ name, token: piece.value });\n      currentRun.names.push(name);\n      currentRun.tokens.push(piece.value);\n      continue;\n    }\n\n    flushRun(piece);\n    const name = `g${i++}`;\n    groups.push({ name, token: piece.value });\n    const nextPiece = pieces[idx + 1];\n    const nextToken = nextPiece?.kind === 'token' ? nextPiece.value : undefined;\n\n    // \"y\" doesn't have a bounded fallback the way yyyy does (check\n    // tokenFragment in pattern.ts) — it's unpadded by definition, so\n    // there's no narrower fixed-width shape underneath it to fall back\n    // to. \"any number of digits\" sitting right next to another digit\n    // consumer has no finite ambiguity score we could charge against\n    // MAX_AMBIGUITY_BITS, so we just refuse it outright at build time\n    // instead of trying to estimate something\n    if (UNBOUNDED_WIDTH_TOKENS.has(piece.value) && isDigitConsumingStart(nextPiece)) {\n      throw new FormatSyntaxError({\n        reason:\n          `token \"${piece.value}\" has no fixed width — it can't be placed directly next to another ` +\n          `digit-reading token or a literal that starts with a digit, since there's no way to tell ` +\n          `where \"${piece.value}\" ends and the next field begins. Add a non-digit separator (e.g. \"-\" or \" \") after it.`,\n      });\n    }\n\n    // yyyy's fragment depends on what comes next: exact 4-digit form\n    // whenever something digit-consuming follows (digit-leading token —\n    // the original rule — OR a literal starting with a digit, added as\n    // part of the ReDoS fix above). the open-ended form is only safe\n    // when nothing digit-consuming can come right after it\n    if (piece.value === 'yyyy' && nextToken === undefined && isDigitConsumingStart(nextPiece)) {\n      source += `(?<${name}>${tokenFragment(piece.value, locale, 'M')})`;\n    } else {\n      source += `(?<${name}>${tokenFragment(piece.value, locale, nextToken)})`;\n    }\n  }\n  flushRun(undefined);\n\n  if (ambiguityBits > MAX_AMBIGUITY_BITS) {\n    throw new FormatSyntaxError({\n      reason:\n        `format string has too many variable-width numeric tokens glued to digit-consuming neighbors ` +\n        `(ambiguity score ${ambiguityBits} > ${MAX_AMBIGUITY_BITS}). ` +\n        `This shape makes the regex engine backtrack exponentially on near-miss input. ` +\n        `Add a non-digit separator between these tokens (e.g. \"-\" or \" \") or use their padded forms (MM/dd/HH/mm/ss).`,\n    });\n  }\n\n  // the 'd' flag turns on match.indices.groups, which parseToParts uses\n  // to report where each token actually landed in the input. without it\n  // we'd need a whole separate walk of the piece list against the input\n  // to compute positions — duplicating logic the regex engine's already\n  // doing for us. safe to add: 'd' only adds an `indices` property to\n  // the result, doesn't change matching behavior at all\n  return { regex: new RegExp(`^(?:${source})$`, 'ud'), groups, ambiguousRuns };\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { buildCapturingPattern, type CapturingPattern } from './parsePattern.js';\nimport { enumerateValidSplits, isValidTimeZone } from './pattern.js';\nimport { getLocaleVocab, canonicalCacheKey, assertValidLocaleTag, subscribeToVocabChanges } from './localeVocab.js';\nimport { getTemporal } from './temporalProvider.js';\nimport { MAX_FORMAT_LENGTH, MAX_INPUT_LENGTH } from './constants.js';\nimport { TemporalFmtError, InvalidTimeZoneError, InvalidOffsetError, FormatSyntaxError, ParseMismatchError, AmbiguousInputError, InvalidDateError, wrapUntypedError } from './errors.js';\nimport { applyParseNumbering, type NumberingParseOptions } from './numbering.js';\n\n// format strings are short hand-written literals reused across many calls —\n// cache the compiled capturing pattern per (formatStr, locale) pair instead\n// of rebuilding it every call.\nconst patternCache = new Map<string, CapturingPattern>();\nconst MAX_CACHE_SIZE = 500;\n\n// A compiled pattern embeds locale-vocabulary alternations (MMMM/MMM/\n// EEEE/EEE/a fragments) at build time. When registerLocaleVocab()\n// swaps a locale's vocabulary, every cached pattern for any locale\n// becomes potentially stale — the cached regex would keep matching the\n// OLD vocabulary while format() renders the new one, breaking the\n// format→parse round-trip for the library's own output. Clear the whole\n// cache on any vocab change: rebuilds are cheap and self-limiting via\n// the cache size cap.\nsubscribeToVocabChanges(() => { patternCache.clear(); });\n\nfunction getPattern(formatStr: string, locale: string): CapturingPattern {\n  const key = JSON.stringify([canonicalCacheKey(locale), formatStr]);\n  let pattern = patternCache.get(key);\n  if (pattern) {\n    return pattern;\n  }\n  if (patternCache.size >= MAX_CACHE_SIZE) {\n    const oldestKey = patternCache.keys().next().value;\n    if (oldestKey !== undefined) patternCache.delete(oldestKey);\n  }\n  pattern = buildCapturingPattern(tokenize(formatStr), locale);\n  patternCache.set(key, pattern);\n  return pattern;\n}\n\n// Requires an explicit `-u-ca-` extension (e.g. 'en-u-ca-hebrew') to apply\n// a non-Gregorian calendar, per parse()'s own docstring. 'gregory' counts\n// as \"no calendar\" so the default locale keeps constructing plain ISO 8601.\n//\n// Used to key off resolvedOptions().calendar instead — a locale's\n// *default* calendar, whether the caller asked for one or not. That broke\n// th-TH silently: its default is 'buddhist', so plain Gregorian-looking\n// digits parsed 543 years off, while format() has no matching calendar\n// step and just prints the object's own ISO fields either way.\nconst calendarCache = new Map<string, string | undefined>();\nconst MAX_CALENDAR_CACHE_SIZE = 500;\n\nfunction resolveCalendar(locale: string): string | undefined {\n  // Typed validation first: a genuinely malformed tag (bare private-use\n  // singleton, control characters, garbage) surfaces as the library's\n  // InvalidLocaleError instead of a raw engine RangeError — same code as\n  // before, different (documented, structured) error class.\n  assertValidLocaleTag(locale);\n  // canonicalCacheKey is memoized (localeVocab.ts), so the common path —\n  // repeated parse() calls with the same locale — no longer constructs a\n  // fresh Intl.Locale per call just to compute the calendar-cache key.\n  const canonicalLocale = canonicalCacheKey(locale);\n  if (calendarCache.has(canonicalLocale)) {\n    return calendarCache.get(canonicalLocale);\n  }\n  if (calendarCache.size >= MAX_CALENDAR_CACHE_SIZE) {\n    const oldestKey = calendarCache.keys().next().value;\n    if (oldestKey !== undefined) calendarCache.delete(oldestKey);\n  }\n  let calendar: string | undefined;\n  const parts = canonicalLocale.split('-');\n  const extensionIndex = parts.indexOf('u');\n  const calendarKeyIndex = extensionIndex === -1 ? -1 : parts.indexOf('ca', extensionIndex + 1);\n  if (calendarKeyIndex !== -1 && calendarKeyIndex + 1 < parts.length) {\n    const resolved = new Intl.DateTimeFormat(canonicalLocale).resolvedOptions().calendar;\n    calendar = resolved === 'gregory' ? undefined : resolved;\n  }\n  calendarCache.set(canonicalLocale, calendar);\n  return calendar;\n}\n\ninterface Fields {\n  year?: number;\n  twoDigitYear?: number;\n  month?: number;\n  day?: number;\n  hour?: number;\n  hour12?: number;\n  dayPeriodRaw?: string;\n  isPM?: boolean;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n  microsecond?: number;\n  nanosecond?: number;\n  timeZoneId?: string;\n  // Canonical `+HH:MM` form of any offset token (X/XX/XXX/x/xx/xxx)\n  // captured in this pattern. Distinct from timeZoneId because the two\n  // can coexist in the same pattern (e.g. \"yyyy-MM-dd HH:mm zzz XXX\") —\n  // see the cross-check after construction for how a mismatch between\n  // them is resolved.\n  offsetString?: string;\n  weekdayExpected?: number;\n  weekdayRaw?: string;\n  quarter?: number;\n}\n\n// Normalizes a captured offset-token string into the canonical `+HH:MM`\n// shape Temporal.ZonedDateTime.from accepts as a `timeZone` value. Throws\n// descriptive errors for out-of-range hours/minutes, since the regex\n// shape (OFFSET_SHAPES in pattern.ts) is deliberately permissive — a\n// post-match range check here gives the user a specific error (\"offset\n// hours 99 out of range, max 14\") instead of \"no valid pattern matches\".\n//\n// Range bounds: -12:00 to +14:00, the standard IANA offset range\n// (Baker/Howland at -12, Kiritimati at +14). +14:01 / -12:01 etc. are\n// rejected explicitly even though the per-piece bounds (hours ≤ 14,\n// minutes ≤ 59) alone wouldn't catch them.\nfunction parseOffsetString(raw: string, token: string): string {\n  if (raw === 'Z') {\n    /* c8 ignore start @preserve -- unreachable: lowercase tokens' regex\n       (OFFSET_SHAPES in pattern.ts) has no \"Z\" alternative at all, so\n       raw === 'Z' can only ever be reached when token is one of the\n       uppercase variants (X/XX/XXX). A lowercase token can't even\n       capture \"Z\" as `raw` in the first place. */\n    if (token === 'x' || token === 'xx' || token === 'xxx') {\n      throw new Error(\n        `temporal-fmt: offset token \"${token}\" doesn't accept \"Z\" — only the uppercase variants (X/XX/XXX) emit \"Z\" for UTC. ` +\n        `Use \"+00:00\", \"+0000\", or \"+00\" depending on the variant's width.`\n      );\n    }\n    /* c8 ignore stop @preserve */\n    return '+00:00';\n  }\n\n  const sign = raw[0];\n  /* c8 ignore start @preserve -- unreachable: raw is a regex-captured\n     group from an offset token, and every OFFSET_SHAPES pattern\n     (pattern.ts) is anchored to either \"Z\" or a leading [+-]. raw's\n     first character can never be anything else by the time it reaches\n     this function. */\n  if (sign !== '+' && sign !== '-') {\n    throw new Error(`temporal-fmt: offset \"${raw}\" for token \"${token}\" doesn't start with \"+\", \"-\", or \"Z\".`);\n  }\n  /* c8 ignore stop @preserve */\n  const body = raw.slice(1);\n  let hoursStr: string;\n  let minutesStr: string;\n  if (body.length === 2) {\n    /* c8 ignore start @preserve -- unreachable: each offset token's own\n       regex shape in OFFSET_SHAPES (pattern.ts) already gates which\n       body shapes it can capture. Only X and x ever match a 2-digit\n       body — XX/xx/XXX/xxx's regexes can't produce one — so this\n       mismatch can never actually fire through parse(). */\n    // +HH — only X/x emit this shape; XX/xx/XXX/xxx always carry minutes.\n    if (token !== 'X' && token !== 'x') {\n      throw new Error(\n        `temporal-fmt: offset token \"${token}\" can't match \"${raw}\" — it requires minutes, but \"${raw}\" has none.`\n      );\n    }\n    /* c8 ignore stop @preserve */\n    hoursStr = body;\n    minutesStr = '00';\n  } else if (body.length === 4) {\n    /* c8 ignore start @preserve -- unreachable, same reason as the\n       2-digit case above: XXX/xxx's regex requires a colon, so it can\n       never capture a 4-digit no-colon body in the first place. */\n    // +HHMM — X/x (when minutes are non-zero) or XX/xx.\n    if (token === 'XXX' || token === 'xxx') {\n      throw new Error(\n        `temporal-fmt: offset token \"${token}\" can't match \"${raw}\" — it requires a colon between hours and minutes (e.g. \"${sign}${body.slice(0, 2)}:${body.slice(2)}\").`\n      );\n    }\n    /* c8 ignore stop @preserve */\n    hoursStr = body.slice(0, 2);\n    minutesStr = body.slice(2, 4);\n  } else if (body.length === 5 && body[2] === ':') {\n    /* c8 ignore start @preserve -- unreachable, same reason again: only\n       XXX/xxx's regex can produce a colon-shaped body; X/x/XX/xx never\n       capture one. */\n    // +HH:MM — XXX/xxx only.\n    if (token !== 'XXX' && token !== 'xxx') {\n      throw new Error(\n        `temporal-fmt: offset token \"${token}\" can't match \"${raw}\" — it doesn't use a colon (use \"${sign}${body.slice(0, 2)}${body.slice(3)}\" instead).`\n      );\n    }\n    /* c8 ignore stop @preserve */\n    hoursStr = body.slice(0, 2);\n    minutesStr = body.slice(3, 5);\n  /* c8 ignore start @preserve -- unreachable: every offset token's\n     regex only ever produces a body of length 2, length 4, or length 5\n     with a colon at index 2 (see OFFSET_SHAPES in pattern.ts) — no\n     shape falls outside those three cases, so this else arm can't be\n     taken through parse(). Kept as an exhaustiveness fallback so\n     hoursStr/minutesStr are assigned on every path TypeScript can see. */\n  } else {\n    throw new Error(`temporal-fmt: offset \"${raw}\" doesn't match the shape token \"${token}\" accepts.`);\n  }\n  /* c8 ignore stop @preserve */\n\n  const hours = Number(hoursStr);\n  const minutes = Number(minutesStr);\n  // Per-piece range checks catch most malformed input.\n  if (hours > 14) {\n    throw new InvalidOffsetError({\n      actual: raw,\n      message: `temporal-fmt: offset hours ${hours} in \"${raw}\" out of range (max 14 — Kiritimati, Line Islands is +14:00).`,\n    });\n  }\n  if (minutes > 59) {\n    throw new InvalidOffsetError({\n      actual: raw,\n      message: `temporal-fmt: offset minutes ${minutes} in \"${raw}\" out of range (max 59).`,\n    });\n  }\n  // Boundary: +14:01..+14:59 and -12:01..-12:59 are out of range even\n  // though each piece alone is in bounds — the overall offset exceeds\n  // the IANA-supported range.\n  if (sign === '+' && hours === 14 && minutes !== 0) {\n    throw new InvalidOffsetError({\n      actual: raw,\n      message: `temporal-fmt: offset \"${raw}\" exceeds the maximum supported UTC offset of +14:00.`,\n    });\n  }\n  if (sign === '-' && hours === 12 && minutes !== 0) {\n    throw new InvalidOffsetError({\n      actual: raw,\n      message: `temporal-fmt: offset \"${raw}\" exceeds the maximum supported negative UTC offset of -12:00.`,\n    });\n  }\n  return `${sign}${hoursStr}:${minutesStr}`;\n}\n\nfunction assignField<T>(fields: Fields, key: keyof Fields, value: T): void {\n  (fields as Record<string, T | undefined>)[key] = value;\n}\n\nfunction applyGroup(fields: Fields, token: string, raw: string, locale: string, formatStr: string): void {\n  const vocab = getLocaleVocab(locale);\n  switch (token) {\n    case 'yyyy': case 'y':\n      assignField(fields, 'year', Number(raw));\n      break;\n    case 'yy':\n      assignField(fields, 'twoDigitYear', Number(raw));\n      break;\n    case 'MM': case 'M':\n      assignField(fields, 'month', Number(raw));\n      break;\n    case 'MMMM':\n      assignField(fields, 'month', vocab.monthLong.indexOf(raw) + 1);\n      break;\n    case 'MMM':\n      assignField(fields, 'month', vocab.monthShort.indexOf(raw) + 1);\n      break;\n    case 'dd': case 'd':\n      assignField(fields, 'day', Number(raw));\n      break;\n    case 'EEEE':\n      assignField(fields, 'weekdayRaw', raw);\n      assignField(fields, 'weekdayExpected', vocab.weekdayLong.indexOf(raw) + 1);\n      break;\n    case 'EEE':\n      assignField(fields, 'weekdayRaw', raw);\n      assignField(fields, 'weekdayExpected', vocab.weekdayShort.indexOf(raw) + 1);\n      break;\n    case 'HH': case 'H':\n      assignField(fields, 'hour', Number(raw));\n      break;\n    case 'hh': case 'h':\n      assignField(fields, 'hour12', Number(raw));\n      break;\n    case 'mm': case 'm':\n      assignField(fields, 'minute', Number(raw));\n      break;\n    case 'ss': case 's':\n      assignField(fields, 'second', Number(raw));\n      break;\n    case 'S': case 'SS': case 'SSS': case 'SSSS': case 'SSSSS':\n    case 'SSSSSS': case 'SSSSSSS': case 'SSSSSSSS': case 'SSSSSSSSS': {\n      // The captured digits are the leading N digits of a nanosecond-of-second\n      // value, not the whole thing — \"5\" under SSSSSSSSS means 500000000ns\n      // (half a second), not 5ns. Right-padding to 9 digits before splitting\n      // is what makes that work; left-padding (or just Number(raw)) would\n      // read \"5\" as 5ns instead.\n      const nanoOfSecond = Number(raw.padEnd(9, '0'));\n      assignField(fields, 'millisecond', Math.floor(nanoOfSecond / 1_000_000));\n      assignField(fields, 'microsecond', Math.floor(nanoOfSecond / 1_000) % 1_000);\n      assignField(fields, 'nanosecond', nanoOfSecond % 1_000);\n      break;\n    }\n    case 'a': {\n      // Matches case-insensitively (see pattern.ts's foldCase), so the\n      // lookup here has to fold too, or \"pm\" would pass the regex and\n      // then fail this indexOf against the exact-case vocab.\n      const periodIndex = vocab.dayPeriod.findIndex((p) => p.toLowerCase() === raw.toLowerCase());\n      /* c8 ignore start @preserve -- unreachable: the 'a' token's regex\n         fragment (pattern.ts's alternation() over vocab.dayPeriod) can\n         only ever capture a case-insensitive match of one of\n         vocab.dayPeriod's own entries. Both the regex and this lookup\n         derive their vocab from the same `locale` via getLocaleVocab(),\n         so periodIndex can't come back negative through parse(). */\n      if (periodIndex < 0) throw new Error(`temporal-fmt: unknown day period \"${raw}\" for locale \"${locale}\".`);\n      /* c8 ignore stop @preserve */\n      assignField(fields, 'dayPeriodRaw', raw);\n      assignField(fields, 'isPM', periodIndex === 1);\n      break;\n    }\n    case 'zzz':\n      assignField(fields, 'timeZoneId', raw);\n      break;\n    case 'X': case 'XX': case 'XXX':\n    case 'x': case 'xx': case 'xxx':\n      assignField(fields, 'offsetString', parseOffsetString(raw, token));\n      break;\n    case 'Q':\n      assignField(fields, 'quarter', Number(raw));\n      break;\n    case 'QQQ':\n      // strips the literal \"Q\" prefix the token itself formats; the suffix\n      // digit is the quarter value 1-4\n      assignField(fields, 'quarter', Number(raw.slice(1)));\n      break;\n  }\n}\n\n// The lenient split-selection heuristic for ambiguous glued numeric runs.\n// See README \"Lenient parse mode\" — the strict default throws on these,\n// lenient mode opts into picking one split instead.\nfunction pickLenientSplit(splits: number[][], tokens: string[]): number[] {\n  // Prefer the split where a \"d\" (day) token, if any, has a value of 12 or\n  // less. Rationale: when a person writes a glued run like \"121\" for an\n  // Md format string, the reading \"Dec 1\" (M=12, d=1) is what they\n  // typically meant — if they meant \"Jan 21\" they would more often have\n  // written it as \"1/21\" or \"01/21\" with a separator or padding, since the\n  // 2-digit day is the more naturally-cohesive unit to keep glued. This\n  // isn't a guarantee, which is exactly why lenient mode is opt-in — but\n  // it's a reasonable default when the caller has asked us to guess.\n  const dayIndex = tokens.indexOf('d');\n  if (dayIndex !== -1) {\n    const smallDaySplits = splits.filter((s) => s[dayIndex]! <= 12);\n    if (smallDaySplits.length > 0) {\n      return smallDaySplits[0]!;\n    }\n  }\n  // Fallback to the first valid split when the day heuristic doesn't\n  // narrow it down — deterministic, and \"first\" here means \"whichever\n  // enumerateValidSplits returned first\", which is a depth-first\n  // leftmost-shortest walk over the candidate splits.\n  return splits[0]!;\n}\n\n// emulates strptime (POSIX) for 2-digit years so the result doesn't depend\n// on the current clock: 00-68 -> 2000-2068, 69-99 -> 1900-1999\n// https://www.man7.org/linux//man-pages/man3/strptime.3p.html\nfunction resolveYear(fields: Fields): number | undefined {\n  if (fields.year !== undefined && fields.twoDigitYear !== undefined) {\n    // FormatSyntaxError, not ParseMismatchError: this is a contradiction\n    // in the format string itself (both a full-year token and \"yy\" are\n    // present), not a mismatch between the format and a specific input.\n    // \"y\" and \"yyyy\" both land in fields.year, so this also covers a\n    // \"y\"+\"yy\" mix, not just \"yyyy\"+\"yy\" — kept generic rather than\n    // naming a specific pair.\n    throw new FormatSyntaxError({\n      message: 'temporal-fmt: format string mixes a full-year token (\"yyyy\"/\"y\") with the two-digit \"yy\" token.',\n    });\n  }\n  if (fields.year !== undefined) return fields.year;\n  if (fields.twoDigitYear !== undefined) {\n    return fields.twoDigitYear <= 68 ? 2000 + fields.twoDigitYear : 1900 + fields.twoDigitYear;\n  }\n  return undefined;\n}\n\nfunction resolveHour(fields: Fields, formatStr: string, locale: string): number | undefined {\n  if (fields.hour !== undefined && fields.hour12 !== undefined) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string \"${formatStr}\" mixes a 24-hour token (\"HH\"/\"H\") with a ` +\n        `12-hour token (\"hh\"/\"h\").`,\n    });\n  }\n  if (fields.hour !== undefined) {\n    if (fields.dayPeriodRaw !== undefined) {\n      throw new FormatSyntaxError({\n        format: formatStr,\n        message:\n          `temporal-fmt: format string \"${formatStr}\" mixes a 24-hour token (\"HH\"/\"H\") with a ` +\n          `day-period token (\"a\"). Both describe the same field; use one or the other, not both.`,\n      });\n    }\n    return fields.hour;\n  }\n  if (fields.hour12 !== undefined) {\n    if (fields.isPM === undefined) {\n      throw new FormatSyntaxError({\n        format: formatStr,\n        message:\n          `temporal-fmt: format string \"${formatStr}\" uses a 12-hour token (\"hh\"/\"h\") without an \"a\" token, ` +\n          `so parse() can't tell AM from PM.`,\n      });\n    }\n    return (fields.hour12 % 12) + (fields.isPM ? 12 : 0);\n  }\n  return undefined;\n}\n\n/**\n * Parses `input` against `formatStr` and builds the real Temporal value it\n * describes: a `Temporal.PlainDate`, `PlainTime`, `PlainDateTime`, or\n * `ZonedDateTime` depending on which tokens are present.\n *\n * Returns `unknown` — this package has no ambient `Temporal` types to return\n * a real one against.\n *\n * `options.locale` picks the calendar the result is built in. Pass a locale\n * tag with a `-u-ca-` extension (e.g. `'en-u-ca-hebrew'`) to parse into a\n * non-Gregorian calendar.\n *\n * @throws if `input` doesn't match `formatStr`'s shape at all\n * @throws if it matches the shape but describes an impossible date (e.g. Feb\n * 30) or self-contradictory data (e.g. a weekday name that doesn't match the\n * actual date)\n *\n * @example\n * parse('yyyy-MM-dd HH:mm', '2026-08-04 15:45') // Temporal.PlainDateTime\n * parse('yyyy-MM', '2026-08-04T15:45:30') // throws — shape doesn't match\n * parse('yyyy-MM-dd', '2026-02-30') // throws — not a real date\n */\nexport function parse(formatStr: string, input: string, options: NumberingParseOptions = {}): unknown | undefined {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n        `(got ${formatStr.length}).`,\n    });\n  }\n\n  if (input.length > MAX_INPUT_LENGTH) {\n    throw new FormatSyntaxError({\n      input,\n      message: `temporal-fmt: input exceeds maximum length of ${MAX_INPUT_LENGTH} characters (got ${input.length}).`,\n    });\n  }\n\n  // Transliterate non-ASCII numerals to ASCII before any matching happens,\n  // when the caller opts in via parseNumberingSystem. Every regex this\n  // module builds expects 0-9; this is the one place that assumption\n  // could otherwise be violated by locale-native input digits.\n  if (options.parseNumberingSystem) {\n    input = applyParseNumbering(input, options);\n  }\n\n  const locale = options.locale ?? DEFAULT_LOCALE;\n  const calendar = resolveCalendar(locale);\n  const pattern = getPattern(formatStr, locale);\n  const match = pattern.regex.exec(input);\n  if (!match) {\n    throw new ParseMismatchError({\n      input, format: formatStr,\n      // reason set explicitly (not just message): parse.test.js's\n      // \"safeParse: failure returns { ok: false, error } with a\n      // TemporalFmtError\" asserts result.error.reason carries the\n      // underlying detail text, matching what wrapUntypedError used to\n      // populate when this message reached it as a caught plain Error.\n      reason: 'no valid pattern matches the format string and input shape',\n      message: `temporal-fmt: no valid pattern matches the format string and input shape`,\n    });\n  }\n\n  if (pattern.groups.length === 0) {\n    // ParseMismatchError, not FormatSyntaxError: pinned by\n    // errors.test.js's \"format string with no tokens at all falls\n    // through to ParseMismatchError\" — wrapUntypedError's classifier\n    // has no branch for this message, so it lands on the\n    // PARSE_MISMATCH fallback, and a direct throw here needs to\n    // agree with that.\n    throw new ParseMismatchError({\n      format: formatStr,\n      // reason set explicitly: errors.test.js's \"format string with no\n      // tokens at all falls through to ParseMismatchError\" asserts\n      // error.reason matches /has no tokens/.\n      reason: `format string \"${formatStr}\" has no tokens — nothing to parse into a value.`,\n      message: `temporal-fmt: format string \"${formatStr}\" has no tokens — nothing to parse into a value.`,\n    });\n  }\n\n  // The regex's zzz fragment only matches a bounded zone-id *shape* (see\n  // TIME_ZONE_SHAPE in pattern.ts) rather than alternating every real IANA\n  // name inline, so a shape match isn't proof of a real zone yet — check\n  // Zone ids can't be enumerated in the regex itself (there are ~400 of\n  // them and they change over time as IANA updates the tz database), so\n  // the regex only captures the zzz group's shape and this loop checks\n  // each captured zzz group against the actual zone list here. Unlike a\n  // regex-shape mismatch, this failure has a specific cause worth\n  // naming: the shape matched but the zone id itself isn't recognized.\n  for (const { name, token } of pattern.groups) {\n    if (token === 'zzz' && !isValidTimeZone(match.groups![name]!)) {\n      throw new InvalidTimeZoneError({\n        input, format: formatStr, actual: match.groups![name],\n        reason: 'not a recognized IANA time zone identifier',\n      });\n    }\n  }\n\n  // A run of 2+ adjacent unpadded-numeric tokens with no literal separator\n  // (e.g. \"Md\", \"dM\", \"Hms\") is captured by a single bounded digit group in\n  // the regex (see buildCapturingPattern — per-token variable-width\n  // fragments made near-miss matching exponential in the number of glued\n  // tokens). Resolve each run's per-token split here instead: unique valid\n  // split resolves (identical to what the old regex's own greedy match\n  // produced, since the old match was always one of the valid splits);\n  // 2+ valid splits is genuinely ambiguous input — strict mode throws,\n  // lenient opts into the documented heuristic. A span with 0 valid\n  // splits matched the run's width window but names no valid per-token\n  // assignment, which the old per-token fragments rejected at match\n  // time — surface the same \"no valid pattern matches\" error.\n  const runValues = new Map<string, string>();\n  for (const run of pattern.ambiguousRuns) {\n    const runDigits = match.groups![run.groupName]!;\n    const splits = enumerateValidSplits(runDigits, run.tokens);\n    if (splits.length === 0) {\n      throw new ParseMismatchError({\n        input, format: formatStr,\n        reason: 'no valid pattern matches the format string and input shape',\n        message: `temporal-fmt: no valid pattern matches the format string and input shape`,\n      });\n    }\n    if (splits.length > 1) {\n      // Strict default — throw on ambiguity. The whole point of the\n      // library's parse() is to refuse to guess when the same input has\n      // more than one valid reading. Lenient mode (opt-in via\n      // options.lenient) instead picks one split via a documented\n      // heuristic — see pickLenientSplit() above and the README section\n      // \"Lenient parse mode\" for why this is strictly additive and never\n      // the default.\n      if (!options.lenient) {\n        throw new AmbiguousInputError({\n          input, format: formatStr,\n          message:\n            `temporal-fmt: \"${runDigits}\" in format string \"${formatStr}\" is ambiguous — ` +\n            `${splits.length} different ways to read tokens \"${run.tokens.join('')}\" (with no separator ` +\n            `between them) are all individually valid (e.g. ${JSON.stringify(splits[0])} vs ${JSON.stringify(splits[1])}). ` +\n            `parse() won't guess; add a separator between these tokens, or use their padded form ` +\n            `(e.g. \"MM\" instead of \"M\") so each one has a fixed width. ` +\n            `Pass { lenient: true } to opt into a documented heuristic that picks one.`,\n        });\n      }\n      const picked = pickLenientSplit(splits, run.tokens);\n      run.groupNames.forEach((name, idx) => runValues.set(name, String(picked[idx])));\n    } else {\n      run.groupNames.forEach((name, idx) => runValues.set(name, String(splits[0]![idx])));\n    }\n  }\n  const fields: Fields = {};\n  // Per-token values for glued-run members come from the split\n  // enumeration above (runValues); every other token reads its own\n  // regex group directly.\n  for (const { name, token } of pattern.groups) {\n    const raw = runValues.get(name) ?? match.groups![name]!;\n    applyGroup(fields, token, raw, locale, formatStr);\n  }\n\n  const year = resolveYear(fields);\n  const hour = resolveHour(fields, formatStr, locale);\n  const { month, day, minute, second, millisecond, microsecond, nanosecond, timeZoneId, offsetString, weekdayExpected, weekdayRaw, quarter } = fields;\n\n  const hasAnyDatePart = year !== undefined || month !== undefined || day !== undefined;\n  const hasFullDate = year !== undefined && month !== undefined && day !== undefined;\n  if (hasAnyDatePart && !hasFullDate) {\n    throw new InvalidDateError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string \"${formatStr}\" has an incomplete date — ` +\n        `year, month, and day tokens must all be present together.`,\n    });\n  }\n\n  const hasTime = hour !== undefined || minute !== undefined || second !== undefined || millisecond !== undefined;\n\n  if (timeZoneId !== undefined && !(hasFullDate && hasTime)) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string \"${formatStr}\" has a \"zzz\" token but needs a full date and time ` +\n        `to build a ZonedDateTime.`,\n    });\n  }\n\n  // Mirror zzz's full-date-and-time requirement: an offset alone is\n  // meaningless without a wall-clock instant to anchor it to. Throws the\n  // same kind of \"needs full date and time\" error zzz throws — separate\n  // message so a caller reading it can tell which token type they\n  // forgot to pair with a full date+time.\n  if (offsetString !== undefined && !(hasFullDate && hasTime)) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string \"${formatStr}\" has an offset token (X/XX/XXX/x/xx/xxx) but needs a full date and time ` +\n        `to build a ZonedDateTime.`,\n    });\n  }\n\n  if (weekdayExpected !== undefined && !hasFullDate) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string \"${formatStr}\" has a weekday token (\"EEEE\"/\"EEE\") but needs ` +\n        `a full date to validate it against.`,\n    });\n  }\n\n  if (!hasFullDate && !hasTime) {\n    // shouldn't happen — every token maps to a date, time, zone, or\n    // weekday field, and weekday-without-date already threw above\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message: `temporal-fmt: format string \"${formatStr}\" has no date or time tokens to parse.`,\n    });\n  }\n\n  const temporal = getTemporal();\n  const timeFields = {\n    hour: hour ?? 0,\n    minute: minute ?? 0,\n    second: second ?? 0,\n    millisecond: millisecond ?? 0,\n    microsecond: microsecond ?? 0,\n    nanosecond: nanosecond ?? 0,\n  };\n  // omitted entirely for the default calendar (see resolveCalendar) so\n  // construction stays plain ISO 8601 unless a caller's locale asks for\n  // something else — Temporal calendars don't apply to time-only values.\n  const calendarField = calendar ? { calendar } : {};\n\n  // overflow: 'reject' — without it Temporal *clamps* out-of-range fields\n  // (Feb 30 silently becomes Feb 28) instead of throwing, which would\n  // contradict the \"throws on genuinely invalid data\" behavior parse() promises.\n  const reject = { overflow: 'reject' as const };\n\n  let result: unknown;\n  try {\n    if (timeZoneId !== undefined) {\n      // offset: 'prefer' never throws on a mismatch — it just falls back to\n      // the zone's real offset at this instant, silently overriding\n      // whatever the offset token said. That's also what resolves a\n      // repeated wall-clock time (DST fall-back): without an explicit\n      // offset, Temporal defaults to the first occurrence, so passing the\n      // token's offset here is what lets a second-occurrence input resolve\n      // to the second occurrence instead of always falling back to the\n      // first. Either way, \"prefer\" can't be used to detect disagreement —\n      // that's checked explicitly below, once we have a real ZonedDateTime\n      // to compare against, instead of relying on the wording of whatever\n      // error Temporal's active implementation happens to throw (that\n      // wording isn't part of the spec and differs between the native\n      // Temporal global and userland polyfills).\n      const zoneOptions: Temporal.ZonedDateTimeFromOptions = { overflow: 'reject', offset: 'prefer' };\n      result = temporal.ZonedDateTime.from(\n        {\n          year: year!, month: month!, day: day!, ...timeFields, ...calendarField,\n          timeZone: timeZoneId,\n          ...(offsetString !== undefined ? { offset: offsetString } : {}),\n        },\n        zoneOptions\n      );\n      if (offsetString !== undefined) {\n        // 'prefer' silently rewrites the wall-clock time itself when the\n        // input falls in a DST gap (the time never occurred, so there's\n        // no instant to prefer toward) — it doesn't just pick a\n        // different offset for the same clock time, the way it does for\n        // an overlap. Checking offsetString alone can't tell \"gap,\n        // silently moved\" apart from \"overlap, correctly resolved,\"\n        // since both can produce an actualOffset that differs from what\n        // was parsed. Comparing the wall-clock fields catches the gap\n        // case: they can only drift from the parsed input if Temporal\n        // moved the clock time to escape the gap.\n        //\n        // Only checked when an offset token was given: with no offset\n        // token to disagree with, a gap shifting forward is the\n        // documented, wanted behavior (there's nothing to reject against).\n        const zdt = result as Temporal.ZonedDateTime;\n        const wallClockShifted =\n          zdt.hour !== timeFields.hour ||\n          zdt.minute !== timeFields.minute ||\n          zdt.second !== timeFields.second;\n        if (wallClockShifted) {\n          // InvalidDateError, not AmbiguousInputError: the message\n          // *mentions* \"not an ambiguous... instant\" as a negation, which\n          // is a false-positive match against wrapUntypedError's\n          // /ambiguous/i classifier regex — the actual failure here is a\n          // wall-clock time that doesn't exist (DST gap), which is an\n          // invalid-value problem, not an ambiguous-reading-of-input\n          // problem the way the numeric-token-glue ambiguity above is.\n          throw new InvalidDateError({\n            input, format: formatStr,\n            message:\n              `\"${timeZoneId}\" has no such wall-clock time on this date — it falls in a DST gap, ` +\n              `not an ambiguous or valid instant.`,\n          });\n        }\n        const actualOffset = zdt.offset;\n        if (actualOffset !== offsetString) {\n          throw new ParseMismatchError({\n            input, format: formatStr,\n            message:\n              `has both a \"zzz\" zone (${timeZoneId}) and an offset token (${offsetString}), ` +\n              `but the zone's actual offset at this date/time is ${actualOffset}, not ${offsetString}.`,\n          });\n        }\n      }\n    } else if (offsetString !== undefined) {\n      // An offset token with no \"zzz\" zone token present. Previously this\n      // built a fixed-offset ZonedDateTime directly from the offset\n      // string; now it's refused outright — an offset identifies a\n      // moment's distance from UTC, not a zone, and building a\n      // ZonedDateTime without a real zone identity papers over that\n      // difference instead of surfacing it.\n      throw new ParseMismatchError({\n        input, format: formatStr,\n        message:\n          `format string \"${formatStr}\" has an offset token but no \"zzz\" zone token. ` +\n          `An offset does not identify a time zone by itself — add \"zzz\" to the pattern, ` +\n          `or parse into a PlainDateTime/PlainDate/PlainTime if a zone isn't needed.`,\n      });\n    } else if (hasFullDate && hasTime) {\n      result = temporal.PlainDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField }, reject);\n    } else if (hasFullDate) {\n      result = temporal.PlainDate.from({ year: year!, month: month!, day: day!, ...calendarField }, reject);\n    } else {\n      result = temporal.PlainTime.from(timeFields, reject);\n    }\n  } catch (err) {\n    throw new InvalidDateError({\n      input, format: formatStr,\n      message:\n        `temporal-fmt: \"${input}\" doesn't describe a valid date/time for format \"${formatStr}\": ` +\n        `${(err as Error).message}`,\n    });\n  }\n\n  if (weekdayExpected !== undefined) {\n    const actual = (result as { dayOfWeek: number }).dayOfWeek;\n    if (actual !== weekdayExpected) {\n      const vocab = getLocaleVocab(locale);\n      throw new InvalidDateError({\n        input, format: formatStr,\n        message:\n          `temporal-fmt: \"${weekdayRaw}\" doesn't match the actual weekday (${vocab.weekdayLong[actual - 1]}) ` +\n          `for the parsed date.`,\n      });\n    }\n  }\n\n  // Q/QQQ is a derived field of the month: 1-3 -> Q1, 4-6 -> Q2, 7-9 -> Q3,\n  // 10-12 -> Q4. If a format string carries a quarter token alongside\n  // month/date tokens, parse() cross-checks the parsed quarter against the\n  // month the same way EEEE cross-checks weekday against date — silently\n  // accepting a mismatch would defeat the point of having a quarter token\n  // at all, since you'd be telling parse() one thing and the date another.\n  if (quarter !== undefined && month !== undefined) {\n    const expectedQuarter = Math.ceil(month / 3);\n    if (quarter !== expectedQuarter) {\n      throw new InvalidDateError({\n        format: formatStr,\n        message:\n          `temporal-fmt: format string \"${formatStr}\" contains a quarter token (Q/QQQ) whose value ` +\n          `(Q${quarter}) disagrees with the parsed month's actual quarter — month ${month} is in ` +\n          `Q${expectedQuarter}.`,\n      });\n    }\n  }\n\n  return result;\n}\n\n// safeParse: returns a discriminated union instead of throwing. The\n// happy path returns `{ ok: true, value }` with the Temporal instance\n// (typed as `unknown` since this package has no ambient Temporal types).\n// The error path returns `{ ok: false, error }` where `error` is a\n// `TemporalFmtError` subclass when the failure is one the typed-error\n// surface in errors.ts knows how to classify (most of them), or a\n// wrapped plain `Error` (still inside a TemporalFmtError shell) when\n// the throw site hasn't been migrated yet. Callers needing the original\n// thrown object for backward compatibility should use parse() directly.\nexport type SafeParseResult =\n  | { ok: true; value: unknown }\n  | { ok: false; error: TemporalFmtError };\n\nexport function safeParse(formatStr: string, input: string, options: NumberingParseOptions = {}): SafeParseResult {\n  try {\n    return { ok: true, value: parse(formatStr, input, options) };\n  } catch (err) {\n    // Pass through typed errors unchanged — preserves the structured\n    // fields (code/token/position/etc.) the existing typed-error\n    // surface already populated.\n    //\n    // Every reachable throw site in parse()'s call graph now throws a\n    // TemporalFmtError directly, so this condition is always true in the\n    // current test suite; the false path (falling through to\n    // wrapUntypedError below) is kept as a safety net for any throw site\n    // added later without being migrated to a typed class immediately —\n    // removing it would silently break the \"safeParse always returns a\n    // TemporalFmtError\" contract documented above. Ignoring the whole\n    // if/else as one unit is harmless for the true branch (real tests\n    // still execute and count it — c8 just excludes it from the\n    // denominator), and it's the only shape that actually suppresses the\n    // false-branch marker, since c8 has no standalone \"ignore else\".\n    /* c8 ignore start @preserve */\n    if (err instanceof TemporalFmtError) {\n      return { ok: false, error: err };\n    }\n    return { ok: false, error: wrapUntypedError(err as Error, { input, format: formatStr }) };\n  }\n  /* c8 ignore stop @preserve */\n}\n\n// tryParse: best-effort variant. Returns the parsed value or undefined.\n// Suppresses diagnostics entirely — when callers need the reason for\n// a failure, they should use safeParse(). Intentionally loose on the\n// return type (unknown) since this package has no ambient Temporal\n// types to return a real one against.\nexport function tryParse(formatStr: string, input: string, options: NumberingParseOptions = {}): unknown | undefined {\n  try {\n    return parse(formatStr, input, options);\n  } catch {\n    return undefined;\n  }\n}\n\n// parseToParts: returns the matched groups with token labels, before\n// any Temporal construction. Useful for callers that want to inspect\n// what each token captured (e.g. to build a non-Temporal result, or to\n// cross-check fields themselves) without committing to the inferred\n// Temporal type parse() would build.\n//\n// Throws the same errors parse() throws for early validation (unknown\n// token, unterminated quote, no-match, ambiguity in strict mode) since\n// those failures happen before any group assignment. Construction-time\n// errors (Feb 30, weekday mismatch, etc.) do not happen here —\n// parseToParts doesn't construct anything, so it can't fail at that step.\nexport interface ParsedPart {\n  token: string;\n  raw: string;\n  // Field name (year/month/day/...) this token would assign if handed\n  // to parse()'s applyGroup loop. undefined for tokens that don't map\n  // to a single field (none today, but kept here so future additions\n  // don't have to widen the type).\n  field?: string;\n  // Position of `raw` in `input`, 0-indexed. Lets a caller highlight\n  // the matched span in an editor/CLI.\n  position: number;\n}\n\nexport function parseToParts(formatStr: string, input: string, options: NumberingParseOptions = {}): ParsedPart[] {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n        `(got ${formatStr.length}).`,\n    });\n  }\n  if (input.length > MAX_INPUT_LENGTH) {\n    throw new FormatSyntaxError({\n      input,\n      message: `temporal-fmt: input exceeds maximum length of ${MAX_INPUT_LENGTH} characters (got ${input.length}).`,\n    });\n  }\n\n  // Same numeral transliteration parse() does — see the comment there.\n  if (options.parseNumberingSystem) {\n    input = applyParseNumbering(input, options);\n  }\n\n  const locale = options.locale ?? DEFAULT_LOCALE;\n  const pattern = getPattern(formatStr, locale);\n  const match = pattern.regex.exec(input);\n  if (!match) {\n    throw new ParseMismatchError({\n      input, format: formatStr,\n      // reason set explicitly (not just message): parse.test.js's\n      // \"safeParse: failure returns { ok: false, error } with a\n      // TemporalFmtError\" asserts result.error.reason carries the\n      // underlying detail text, matching what wrapUntypedError used to\n      // populate when this message reached it as a caught plain Error.\n      reason: 'no valid pattern matches the format string and input shape',\n      message: `temporal-fmt: no valid pattern matches the format string and input shape`,\n    });\n  }\n  if (pattern.groups.length === 0) {\n    // ParseMismatchError, not FormatSyntaxError: pinned by\n    // errors.test.js's \"format string with no tokens at all falls\n    // through to ParseMismatchError\" — wrapUntypedError's classifier\n    // has no branch for this message, so it lands on the\n    // PARSE_MISMATCH fallback, and a direct throw here needs to\n    // agree with that.\n    throw new ParseMismatchError({\n      format: formatStr,\n      // reason set explicitly: errors.test.js's \"format string with no\n      // tokens at all falls through to ParseMismatchError\" asserts\n      // error.reason matches /has no tokens/.\n      reason: `format string \"${formatStr}\" has no tokens — nothing to parse into a value.`,\n      message: `temporal-fmt: format string \"${formatStr}\" has no tokens — nothing to parse into a value.`,\n    });\n  }\n  // Same zzz shape-validation parse() does — kept here for parity, so\n  // a caller using parseToParts sees the same InvalidTimeZoneError for\n  // a bogus zone id, not a silently-accepted bogus zone.\n  for (const { name, token } of pattern.groups) {\n    if (token === 'zzz' && !isValidTimeZone(match.groups![name]!)) {\n      throw new InvalidTimeZoneError({\n        input, format: formatStr, actual: match.groups![name],\n        reason: 'not a recognized IANA time zone identifier',\n      });\n    }\n  }\n\n  // Glued-run split handling: same as parse() — each run's single regex\n  // group is split into per-token values by enumerateValidSplits();\n  // unique split resolves, 2+ splits throws in strict mode / heuristic-\n  // picks in lenient, 0 splits is a shape mismatch. parseToParts mirrors\n  // parse() so callers switching between the two on the same input get\n  // consistent results.\n  const runValues = new Map<string, string>();\n  for (const run of pattern.ambiguousRuns) {\n    const runDigits = match.groups![run.groupName]!;\n    const splits = enumerateValidSplits(runDigits, run.tokens);\n    if (splits.length === 0) {\n      throw new ParseMismatchError({\n        input, format: formatStr,\n        reason: 'no valid pattern matches the format string and input shape',\n        message: `temporal-fmt: no valid pattern matches the format string and input shape`,\n      });\n    }\n    if (splits.length > 1) {\n      if (!options.lenient) {\n        throw new AmbiguousInputError({\n          input, format: formatStr,\n          message:\n            `temporal-fmt: \"${runDigits}\" in format string \"${formatStr}\" is ambiguous — ` +\n            `${splits.length} different ways to read tokens \"${run.tokens.join('')}\" (with no separator ` +\n            `between them) are all individually valid (e.g. ${JSON.stringify(splits[0])} vs ${JSON.stringify(splits[1])}). ` +\n            `parse() won't guess; add a separator between these tokens, or use their padded form ` +\n            `(e.g. \"MM\" instead of \"M\") so each one has a fixed width. ` +\n            `Pass { lenient: true } to opt into a documented heuristic that picks one.`,\n        });\n      }\n      const picked = pickLenientSplit(splits, run.tokens);\n      run.groupNames.forEach((name, idx) => runValues.set(name, String(picked[idx])));\n    } else {\n      run.groupNames.forEach((name, idx) => runValues.set(name, String(splits[0]![idx])));\n    }\n  }\n\n  const parts: ParsedPart[] = [];\n  // match.indices.groups (provided by the regex 'd' flag) gives the\n  // [start, end] of each named group in the input. Used here so positions\n  // are accurate even when literals separate tokens — summing raw\n  // lengths alone wouldn't account for the literal characters between\n  // groups. Falls back to the cumulative-raw-length heuristic on engines\n  // without 'd' support (none we target, but the fallback keeps the\n  // code robust if the flag is ever removed).\n  const indices = (match as RegExpMatchArray & { indices?: { groups?: Record<string, [number, number]> } }).indices;\n  const groupIndices = indices?.groups;\n  let consumed = 0;\n  for (const { name, token } of pattern.groups) {\n    const raw = runValues.get(name) ?? match.groups![name]!;\n    // Glued-run members have no regex group of their own — the regex's\n    // recorded indices point at the run's overall span, not the\n    // individual token's slice within it — so fall back to cumulative-\n    // raw-length for them. Positions stay monotonic but may not be\n    // exact for tokens inside a resolved run. Documented as a known\n    // limitation; the alternative (re-running the regex with the chosen\n    // split baked in) would mean a second match pass for a corner case\n    // the caller opted into by gluing unpadded tokens.\n    const fromIndices = !runValues.has(name) && groupIndices?.[name];\n    /* c8 ignore next */\n    const position = fromIndices ? fromIndices[0] : (match.index ?? 0) + consumed;\n    parts.push({ token, raw, position });\n    consumed += raw.length;\n  }\n  return parts;\n}\n\n// compileParser: pre-compiles a format string into an object whose\n// parse()/safeParse()/parseToParts() methods skip the per-call\n// pattern-cache lookup. The patternCache in this module means a plain\n// parse(fmt, input) call already pays only a Map lookup after the first\n// call, so compileParser is mostly an ergonomics affordance — useful\n// for callers who want to hold the compiled parser explicitly (e.g. to\n// inspect the pattern via the .pattern property).\nexport interface CompiledParser {\n  parse(input: string, options?: NumberingParseOptions): unknown;\n  safeParse(input: string, options?: NumberingParseOptions): SafeParseResult;\n  tryParse(input: string, options?: NumberingParseOptions): unknown | undefined;\n  parseToParts(input: string, options?: NumberingParseOptions): ParsedPart[];\n  readonly formatStr: string;\n  readonly pattern: CapturingPattern;\n}\n\nexport function compileParser(formatStr: string, options: NumberingParseOptions = {}): CompiledParser {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new FormatSyntaxError({\n      format: formatStr,\n      message:\n        `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n        `(got ${formatStr.length}).`,\n    });\n  }\n  // Pre-compile against the default locale; per-call locales will\n  // re-resolve via getPattern() if they differ. Most callers use one\n  // locale consistently, so pre-compiling against the default keeps\n  // the fast path fast.\n  const locale = options.locale ?? DEFAULT_LOCALE;\n  const pattern = getPattern(formatStr, locale);\n  return {\n    formatStr,\n    pattern,\n    parse(input: string, opts: NumberingParseOptions = {}) {\n      return parse(formatStr, input, { locale, ...opts });\n    },\n    safeParse(input: string, opts: NumberingParseOptions = {}) {\n      return safeParse(formatStr, input, { locale, ...opts });\n    },\n    tryParse(input: string, opts: NumberingParseOptions = {}) {\n      return tryParse(formatStr, input, { locale, ...opts });\n    },\n    parseToParts(input: string, opts: NumberingParseOptions = {}) {\n      return parseToParts(formatStr, input, { locale, ...opts });\n    },\n  };\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// lets people register their own relative-date grammars on top of\n// parseRelative.ts, which only ships with English/Spanish/French/German\n// baked in.\n//\n// parseRelative() looks at the locale option, figures out the language,\n// and dispatches. registerRelativeGrammar() means someone can bolt on\n// a new language without touching parseRelative.ts itself.\n//\n// a grammar is just a list of matchers, each one either resolves to a\n// Temporal field bag or returns null. tries them in order, first match\n// wins — same shape as the ENGLISH/SPANISH/FRENCH/GERMAN_GRAMMAR objects\n// parseRelative already has internally, just made pluggable\n\nimport { getTemporal, type TemporalNamespace } from './temporalProvider.js';\n\nexport interface RelativeGrammarMatch {\n  // whatever fields the matcher figured out, gets fed to Temporal.PlainDate.from()\n  year?: number;\n  month?: number;\n  day?: number;\n  // for cases like \"next Tuesday\" where you can't compute the fields\n  // without knowing the reference date's weekday first — pass a function\n  // instead of raw fields\n  resolve?: (reference: { year: number; month: number; day: number; dayOfWeek: number }) => { year: number; month: number; day: number };\n}\n\nexport interface RelativeGrammar {\n  // language subtag ('en', 'es', etc), matched against the locale option\n  language: string;\n  // tried top to bottom, first one that matches wins\n  matchers: Array<(input: string) => RelativeGrammarMatch | null>;\n}\n\n// cap so nobody can loop registerRelativeGrammar() and blow up the array\n// (and the scan in tryRegisteredGrammar with it) forever. re-registering\n// an existing language doesn't count against this, only actually new ones.\n// same idea as what registerLocaleVocab does for custom vocabs\nconst MAX_REGISTERED_GRAMMARS = 100;\n\nconst registeredGrammars: RelativeGrammar[] = [];\n\nexport function registerRelativeGrammar(grammar: RelativeGrammar): void {\n  if (typeof grammar.language !== 'string' || grammar.language.length === 0) {\n    throw new Error('temporal-fmt: registerRelativeGrammar requires a non-empty language string.');\n  }\n  if (grammar.language.length > 35) {\n    throw new RangeError(`temporal-fmt: registerRelativeGrammar language tags must be at most 35 characters (got ${grammar.language.length}).`);\n  }\n  if (!Array.isArray(grammar.matchers) || grammar.matchers.length === 0) {\n    throw new Error('temporal-fmt: registerRelativeGrammar requires at least one matcher.');\n  }\n  // Every matcher runs on untrusted parseRelative input — a non-function\n  // entry used to register fine and then blow up every subsequent\n  // parseRelative() call for that locale with a raw V8 TypeError\n  // (\"matcher is not a function\"). Cap the count for the same reason the\n  // grammar count is capped: every registered matcher is scanned per\n  // parseRelative call.\n  if (grammar.matchers.length > 1000) {\n    throw new RangeError(`temporal-fmt: registerRelativeGrammar accepts at most 1000 matchers (got ${grammar.matchers.length}).`);\n  }\n  if (!grammar.matchers.every((m) => typeof m === 'function')) {\n    throw new Error('temporal-fmt: registerRelativeGrammar matchers must all be functions.');\n  }\n  // if this language's already registered, just swap it out\n  const existingIdx = registeredGrammars.findIndex((g) => g.language === grammar.language);\n  if (existingIdx >= 0) {\n    registeredGrammars[existingIdx] = grammar;\n  } else {\n    if (registeredGrammars.length >= MAX_REGISTERED_GRAMMARS) {\n      throw new RangeError(`temporal-fmt: registerRelativeGrammar reached the ${MAX_REGISTERED_GRAMMARS}-grammar limit.`);\n    }\n    registeredGrammars.push(grammar);\n  }\n}\n\n// parseRelative() calls this first, before falling back to the built-ins.\n// null means nothing registered matched\nexport function tryRegisteredGrammar(\n  language: string,\n  input: string,\n  reference: { year: number; month: number; day: number; dayOfWeek: number },\n): unknown | null {\n  for (const grammar of registeredGrammars) {\n    if (grammar.language !== language) continue;\n    for (const matcher of grammar.matchers) {\n      // One throwing matcher shouldn't take parseRelative() down with a\n      // raw error — treat it as \"no match\" and let the next matcher (or\n      // the built-in grammars) try. Registered matchers are third-party\n      // code; isolating their failures is the registration boundary's\n      // job.\n      let match: RelativeGrammarMatch | null;\n      try {\n        match = matcher(input);\n      } catch {\n        continue;\n      }\n      if (match === null) continue;\n      const temporal = getTemporal();\n      if (match.resolve) {\n        const fields = match.resolve(reference);\n        return temporal.PlainDate.from(fields, { overflow: 'reject' });\n      }\n      return temporal.PlainDate.from(\n        { year: match.year ?? reference.year, month: match.month ?? reference.month, day: match.day ?? reference.day },\n        { overflow: 'reject' },\n      );\n    }\n  }\n  return null;\n}\n\n// just for introspection, lists what's registered\nexport function listRegisteredGrammars(): string[] {\n  return registeredGrammars.map((g) => g.language);\n}\n\n// this is just here so TS doesn't complain about the unused import —\n// TemporalNamespace shows up in the type signature above but not as a\n// real runtime reference\nvoid (undefined as unknown as TemporalNamespace);\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getTemporal } from './temporalProvider.js';\nimport { type TemporalNamespace } from './temporalProvider.js';\nimport { tryRegisteredGrammar } from './relativeGrammar.js';\nimport { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\n\n// parseRelative resolves common relative-date phrases (\"next Tuesday\",\n// \"in 3 days\", \"March 5th\") against a reference date, returning a\n// Temporal.PlainDate. It's a different subsystem from the token-based\n// parse(): the input is free natural-language text, not a structurally-\n// typed format string, so this module owns its own grammar rather than\n// bolting a natural-language layer onto the existing tokenizer.\n//\n// Per-language grammars: each locale's grammar lives in its own\n// clearly-labeled section below (ENGLISH_GRAMMAR, SPANISH_GRAMMAR,\n// FRENCH_GRAMMAR, GERMAN_GRAMMAR). The vocabulary and phrase patterns\n// are NOT shared across languages — Spanish \"hace 2 semanas\" and\n// French \"il y a 2 semaines\" are different idioms and get their own\n// regexes. What IS shared is the matching engine (iterate matchers in\n// order, first match wins, throw on no match) and the resolution\n// helpers (addDays, addUnits, weekdayOffset, resolveToNextOccurrence).\n// Same approach the humanizing skill calls \"solve each recurring\n// problem once\": the matching strategy is shared, the per-language\n// vocabulary is not.\n//\n// Default locale (no `locale` option) uses English — matches the\n// pre-change behavior byte-for-byte. Passing `locale: 'es'`,\n// `locale: 'fr'`, or `locale: 'de'` (or any locale tag with that\n// language subtag) routes to the corresponding grammar. Unrecognized\n// languages fall back to English rather than throwing — a caller\n// passing `locale: 'it-IT'` still gets *some* result, just from the\n// English grammar. (We could throw instead; the current contract is\n// \"best effort.\" If the caller wanted Italian specifically, they'd\n// pass an Italian grammar via registerLocaleVocab-style extension —\n// not implemented here.)\n\n// Lowercase + expand German umlauts (ä→ae, ö→oe, ü→ue, ß→ss) + strip\n// remaining diacritics. Three things going on at once:\n//\n//  1. Lowercase — case-insensitive matching without forcing the\n//     regex flag to do it (also keeps the captured groups lowercase\n//     for the resolver's comparisons).\n//  2. Expand German umlaut transliterations. Germans without an\n//     umlaut key write \"ä\" as \"ae\" — the standard transliteration.\n//     Expanding \"ä\" → \"ae\" (before NFD stripping) means both \"März\"\n//     and \"Maerz\" normalize to \"maerz\" and match the same pattern.\n//     The reverse (ae → ä) would be wrong: \"Tage\" has \"ae\" as a\n//     coincidence, not as an umlaut transliteration. Forward expansion\n//     is unambiguous because the source string already has the\n//     umlaut — the expansion only affects the matched form.\n//  3. Strip combining marks via NFD. \"Miércoles\" → \"Miercoles\",\n//     \"février\" → \"fevrier\", \"août\" → \"aout\". Pairs with the umlaut\n//     expansion above so all four languages' accented forms collapse\n//     to one canonical unaccented form for matching.\n//\n// Both sides of the match — input string AND the weekday/month name\n// lists — get the same normalization applied, so this is symmetric.\nfunction normalizeForMatch(s: string): string {\n  return s.toLowerCase()\n    .replace(/ä/g, 'ae')\n    .replace(/ö/g, 'oe')\n    .replace(/ü/g, 'ue')\n    .replace(/ß/g, 'ss')\n    .normalize('NFD')\n    .replace(/[\\u0300-\\u036f]/g, '');\n}\n\n// Standard Levenshtein edit distance (insert/delete/substitute, cost 1\n// each). Used only by the opt-in fuzzy layer below — the exact matcher\n// pass never calls this. Iterative DP over two rows, not the full\n// matrix, since only the previous row is ever needed.\nfunction levenshtein(a: string, b: string): number {\n  /* c8 ignore start @preserve -- unreachable through the only call\n   * site (fuzzyCorrectEnglish): `a` is always a word that already\n   * failed the `vocabulary.includes(word)` exact-match check, so\n   * a === b never holds against any `b` drawn from that same\n   * vocabulary; and neither `a` (split from a non-empty normalized\n   * string) nor `b` (a vocabulary entry) is ever empty. Kept as\n   * general-purpose guards in case levenshtein() gets a second caller\n   * later. */\n  if (a === b) return 0;\n  if (a.length === 0) return b.length;\n  if (b.length === 0) return a.length;\n  /* c8 ignore stop @preserve */\n  let prev = new Array(b.length + 1);\n  let curr = new Array(b.length + 1);\n  for (let j = 0; j <= b.length; j++) prev[j] = j;\n  for (let i = 1; i <= a.length; i++) {\n    curr[0] = i;\n    for (let j = 1; j <= b.length; j++) {\n      const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n      curr[j] = Math.min(\n        prev[j] + 1,      // deletion\n        curr[j - 1] + 1,  // insertion\n        prev[j - 1] + cost, // substitution\n      );\n    }\n    [prev, curr] = [curr, prev];\n  }\n  return prev[b.length];\n}\n\n// Max edit distance a fuzzy correction is allowed to bridge. 2 covers\n// the common single-finger-slip and single-transposed-letter typo cases\n// (\"tommorow\" is distance 1 from \"tomorrow\"; \"tuesady\" is distance 2\n// from \"tuesday\" — a transposition costs 2 under simple Levenshtein,\n// which doesn't special-case adjacent-swap as a single edit) without\n// opening the door to correcting a word into something only vaguely\n// similar. Deliberately conservative — this is a typo-tolerance layer,\n// not a \"guess what they meant\" layer; the library's whole design\n// philosophy elsewhere (parse()'s strict-by-default ambiguity handling,\n// the lenient opt-in) is to bound how much guessing is allowed and make\n// the caller ask for it explicitly.\nconst FUZZY_MAX_DISTANCE = 2;\nconst MAX_RELATIVE_INPUT_LENGTH = 4096;\nconst MAX_RELATIVE_WORDS = 32;\n\n// English-only fuzzy vocabulary. Anything a matcher's regex treats as a\n// fixed keyword (not a captured number) belongs here — weekday names,\n// month names (long and short), and the marker words the matchers\n// switch on (today/tomorrow/yesterday/next/last/this/in/ago and the\n// unit words day/week/month/year). Numbers and ordinal suffixes are\n// deliberately excluded: \"5th\" vs \"5tj\" isn't a word-shaped typo this\n// layer is trying to solve, and correcting digits is a much easier way\n// to silently produce a wrong date than correcting a weekday name is.\n//\n// Scoped to English only for this pass — the other three grammars have\n// enough positional/multi-word-marker variation (French's \"il y a\",\n// Spanish's dual pre/post weekday-modifier shapes) that a single\n// word-substitution corrector isn't a good fit for all of them without\n// per-language tuning this change doesn't attempt. parseRelative()\n// throws a clear scope-limited error if { fuzzy: true } is combined\n// with a non-English locale, rather than silently no-op-ing.\nfunction buildEnglishFuzzyVocabulary(): string[] {\n  return [\n    ...ENGLISH_WEEKDAYS,\n    ...ENGLISH_MONTHS,\n    ...ENGLISH_MONTH_SHORT,\n    'today', 'tomorrow', 'yesterday',\n    'next', 'last', 'this',\n    'in', 'ago',\n    'day', 'days', 'week', 'weeks', 'month', 'months', 'year', 'years',\n  ].map(normalizeForMatch);\n}\n\n// Lazily built and cached — the vocabulary is static per process, no\n// need to rebuild the normalized list on every fuzzy call.\nlet englishFuzzyVocabulary: readonly string[] | undefined;\nfunction getEnglishFuzzyVocabulary(): readonly string[] {\n  if (!englishFuzzyVocabulary) englishFuzzyVocabulary = Object.freeze(buildEnglishFuzzyVocabulary());\n  return englishFuzzyVocabulary;\n}\n\n// Attempts a word-level fuzzy correction of `normalized` against the\n// English vocabulary, returning a corrected string or undefined if no\n// correction was needed/possible. Tokenizes on whitespace; each token\n// that isn't already an exact vocabulary word (or a pure number/ordinal,\n// which passes through untouched) gets replaced with its closest\n// vocabulary match, if one exists within FUZZY_MAX_DISTANCE. If a token\n// has no sufficiently-close vocabulary match, it's left as-is — the\n// re-attempted exact match will then fail on that token same as before,\n// which is the correct outcome for \"this word isn't a typo of anything\n// we know, it's just not a phrase we support.\"\nfunction fuzzyCorrectEnglish(normalized: string): string | undefined {\n  const vocabulary = getEnglishFuzzyVocabulary();\n  const words = normalized.split(' ');\n  if (normalized.length > MAX_RELATIVE_INPUT_LENGTH || words.length > MAX_RELATIVE_WORDS) {\n    throw new RangeError(\n      `temporal-fmt: parseRelative fuzzy input is too large (maximum ${MAX_RELATIVE_INPUT_LENGTH} characters and ${MAX_RELATIVE_WORDS} words).`,\n    );\n  }\n  let changed = false;\n  const corrected = words.map((word) => {\n    // Pure digits, or digits with an ordinal suffix (st/nd/rd/th) —\n    // never touched by fuzzy correction. See the vocabulary comment\n    // above for why.\n    if (/^\\d+(?:st|nd|rd|th)?$/.test(word)) return word;\n    // Already an exact vocabulary word — nothing to correct.\n    if (vocabulary.includes(word)) return word;\n\n    let best: string | undefined;\n    let bestDist = FUZZY_MAX_DISTANCE + 1;\n    for (const candidate of vocabulary) {\n      const dist = levenshtein(word, candidate);\n      if (dist < bestDist) {\n        bestDist = dist;\n        best = candidate;\n      }\n    }\n    if (best !== undefined && bestDist <= FUZZY_MAX_DISTANCE) {\n      changed = true;\n      return best;\n    }\n    return word;\n  });\n\n  return changed ? corrected.join(' ') : undefined;\n}\n\ninterface TemporalFieldBag {\n  year?: number;\n  month?: number;\n  day?: number;\n  dayOfWeek?: number;\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n}\n\nfunction readYear(reference: TemporalFieldBag): number {\n  if (typeof reference.year !== 'number') {\n    throw new Error('temporal-fmt: parseRelative reference date is missing year.');\n  }\n  return reference.year;\n}\nfunction readMonth(reference: TemporalFieldBag): number {\n  if (typeof reference.month !== 'number') {\n    throw new Error('temporal-fmt: parseRelative reference date is missing month.');\n  }\n  return reference.month;\n}\nfunction readDay(reference: TemporalFieldBag): number {\n  if (typeof reference.day !== 'number') {\n    throw new Error('temporal-fmt: parseRelative reference date is missing day.');\n  }\n  return reference.day;\n}\n\nfunction extractDayOfWeek(reference: TemporalFieldBag): number {\n  const dow = reference.dayOfWeek;\n  if (typeof dow !== 'number') {\n    throw new Error(\n      'temporal-fmt: parseRelative needs a reference date exposing dayOfWeek (a Temporal.PlainDate / PlainDateTime / ZonedDateTime).'\n    );\n  }\n  return dow;\n}\n\n// Build an alternation regex fragment from a name list, normalized for\n// matching. Longest-first so \"September\" wins over \"Sep\" in the same\n// match position. The caller is responsible for any wrapping groups\n// or anchors — this just produces the inner alternation.\nfunction nameAlternation(names: string[]): string {\n  const normalized = names.map(normalizeForMatch);\n  // Dedupe — some locales render the long and short form identically\n  // (English \"May\" is the same in both MMMM and MMM lists). Keep both\n  // in the alternation rather than deduping, since duplicates in a\n  // regex alternation don't change behavior and the dedupe would just\n  // be a micro-optimization.\n  // Sort longest-first so a longer name wins over its own prefix.\n  const sorted = [...normalized].sort((a, b) => b.length - a.length);\n  // Escape regex metacharacters — names shouldn't contain any, but\n  // belt-and-braces avoids a future \"M+1\" month name from breaking\n  // the alternation silently.\n  return sorted.map((n) => n.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|');\n}\n\n// Resolves to a PlainDate by adding `days` to the reference. Used for\n// weekday refs and the today/tomorrow/yesterday family.\nfunction buildPlainDate(temporal: { PlainDate: { from: (fields: Record<string, number>, options?: { overflow?: 'constrain' | 'reject' }) => unknown } }, year: number, month: number, day: number): unknown {\n  return temporal.PlainDate.from({ year, month, day }, { overflow: 'reject' });\n}\n\nfunction addDays(\n  temporal: { PlainDate: { from: (fields: Record<string, number>) => unknown } },\n  reference: TemporalFieldBag,\n  days: number,\n): unknown {\n  // Build the reference as a real PlainDate so we can use Temporal's\n  // own add() for date arithmetic — calendar-correct (handles month\n  // boundaries, leap years, etc.) so we don't have to reimplement it.\n  const refDate = temporal.PlainDate.from({\n    year: readYear(reference),\n    month: readMonth(reference),\n    day: readDay(reference),\n  }) as { add: (duration: Record<string, number>) => unknown };\n  return refDate.add({ days });\n}\n\nfunction addUnits(\n  temporal: { PlainDate: { from: (fields: Record<string, number>) => unknown } },\n  reference: TemporalFieldBag,\n  count: number,\n  unit: 'day' | 'week' | 'month' | 'year',\n): unknown {\n  const refDate = temporal.PlainDate.from({\n    year: readYear(reference),\n    month: readMonth(reference),\n    day: readDay(reference),\n  }) as { add: (duration: Record<string, number>) => unknown };\n  const duration: Record<string, number> = {};\n  if (unit === 'day') duration.days = count;\n  if (unit === 'week') duration.weeks = count;\n  if (unit === 'month') duration.months = count;\n  if (unit === 'year') duration.years = count;\n  return refDate.add(duration);\n}\n\n// \"next X\" — strictly future next occurrence. Said on a Tuesday:\n// \"next Tuesday\" = 7 days from now, not today. Rationale: \"this\n// Tuesday\" handles the same-week case, so \"next Tuesday\" staying\n// strictly-future gives the two phrases distinct, non-overlapping\n// meanings. Documented in README \"parseRelative\".\n//\n// \"last X\" — strictly past most recent occurrence. Symmetric to \"next\".\n//\n// \"this X\" — the X of the current ISO week (Mon..Sun). Can land on\n// today, past, or future depending on where in the week today falls.\n//\n// All three resolve the same way across the four supported languages\n// (en/es/fr/de): the equivalent idiom in each language maps to one of\n// these three rel words. The natural-language reading is consistent\n// — \"next Tuesday\" said on a Tuesday means next week's Tuesday in\n// every language we support.\nfunction weekdayOffset(rel: 'next' | 'last' | 'this', refDow: number, targetDow: number): number {\n  // refDow and targetDow are both 1..7 (ISO Mon=1..Sun=7).\n  if (rel === 'next') {\n    let diff = targetDow - refDow;\n    if (diff <= 0) diff += 7; // 0 (today) → 7, negative → wrap forward\n    return diff; // 1..7\n  }\n  if (rel === 'last') {\n    let diff = targetDow - refDow;\n    if (diff >= 0) diff -= 7; // 0 (today) → -7, positive → wrap backward\n    return diff; // -7..-1\n  }\n  // rel === 'this' — X of the current week. Can be today, past, or future.\n  return targetDow - refDow; // -6..+6\n}\n\n// \"March 5th\" without a year → resolve to the next occurrence of that\n// month/day. If today is that date, return today. Otherwise, if it's\n// already past this year, return next year's occurrence.\n//\n// \"Next occurrence\" semantics: future-leaning. Documented in README\n// as the chosen behavior. The alternative (\"nearest in time, past or\n// future\") would mean \"March 5th\" said on March 6 returns yesterday —\n// counterintuitive for the typical \"next birthday\"/\"next deadline\"\n// use case this kind of phrase tends to drive.\nfunction resolveToNextOccurrence(\n  temporal: {\n    PlainDate: {\n      from: (fields: Record<string, number>, options?: { overflow?: 'constrain' | 'reject' }) => unknown;\n      compare?: (one: unknown, two: unknown) => number;\n    };\n  },\n  reference: TemporalFieldBag,\n  month: number,\n  day: number,\n): unknown {\n  const refYear = readYear(reference);\n  const refDate = temporal.PlainDate.from({\n    year: refYear,\n    month: readMonth(reference),\n    day: readDay(reference),\n  });\n  // PlainDate.compare is a static method on the namespace, not an\n  // instance method — that's why it's called off temporal.PlainDate\n  // rather than off an instance below. Checked outside the try/catch\n  // below on purpose: that block's catch is scoped to Feb-29-style\n  // overflow errors from from(), and silently retries with next year's\n  // date. A missing-compare error thrown from inside that try would get\n  // caught by the same handler and swallowed by that retry (next year's\n  // from() usually succeeds), masking the real problem instead of\n  // surfacing it.\n  if (!temporal.PlainDate.compare) {\n    throw new Error('temporal-fmt: parseRelative needs Temporal.PlainDate.compare to resolve month-day phrases; the active implementation does not expose it.');\n  }\n  // try this year first; if Feb 29 in a non-leap year, Temporal will\n  // throw via overflow: 'reject' — fall through to next year.\n  try {\n    const thisYear = temporal.PlainDate.from({ year: refYear, month, day }, { overflow: 'reject' });\n    // Returns -1 / 0 / 1.\n    if (temporal.PlainDate.compare(thisYear, refDate) >= 0) {\n      // today or in the future → use this year's occurrence\n      return thisYear;\n    }\n    // already past this year → next year's occurrence\n    return temporal.PlainDate.from({ year: refYear + 1, month, day }, { overflow: 'reject' });\n  } catch (err) {\n    // Feb 29 in a non-leap year, or similar. Try next year — if the\n    // caller asked for \"Feb 29\" said in a non-leap year, next year may\n    // also not be leap, in which case the inner from() will throw and\n    // surface a clear error rather than silently landing on Feb 28.\n    try {\n      return temporal.PlainDate.from({ year: refYear + 1, month, day }, { overflow: 'reject' });\n    } catch {\n      throw new Error(\n        `temporal-fmt: parseRelative can't resolve month ${month} day ${day} — ` +\n        `it isn't a valid date in either ${refYear} or ${refYear + 1}. ` +\n        `Original error: ${(err as Error).message}`\n      );\n    }\n  }\n}\n\n// Each language provides a list of matchers. The shared engine\n// iterates them in order and returns the first match. A matcher is a\n// (regex, resolver) pair — the regex captures the structural pieces\n// (count, unit name, weekday name, etc.), the resolver turns them\n// into a Temporal.PlainDate using the shared helpers above.\ninterface ResolveContext {\n  temporal: TemporalNamespace;\n  reference: TemporalFieldBag;\n}\n\ninterface Matcher {\n  pattern: RegExp;\n  resolve: (match: RegExpMatchArray, ctx: ResolveContext) => unknown;\n}\n\ninterface RelativeDateGrammar {\n  // Single-line description of supported phrase classes, included in\n  // the \"doesn't recognize\" error so the caller knows what to try.\n  supportedHint: string;\n  // Ordered matchers; first match wins.\n  matchers: Matcher[];\n}\n\nfunction weekdayIndexFromName(name: string, names: string[]): number {\n  const normalized = normalizeForMatch(name);\n  const idx = names.findIndex((n) => normalizeForMatch(n) === normalized);\n  /* c8 ignore start @preserve -- unreachable: every caller passes a\n   * name captured by nameAlternation(names), which builds its regex\n   * alternation from this same list under the same normalizeForMatch\n   * transform. The regex can't match anything findIndex() wouldn't\n   * also find here. Defensive throw kept for the type checker and as\n   * a tripwire if that invariant ever breaks. Ignore comment sits on\n   * the `if` itself, not just the throw inside it — c8 tracks the\n   * branch outcome (was the true side ever taken) separately from the\n   * statements inside, so excluding only the inner throw still leaves\n   * the branch itself flagged as uncovered. */\n  /* c8 ignore next */\n  if (idx < 0) {\n    throw new Error(`temporal-fmt: parseRelative internal error — weekday \"${name}\" not in names list.`);\n  }\n  /* c8 ignore stop @preserve */\n  return idx + 1;\n}\n\nfunction monthIndexFromName(name: string, longNames: string[], shortNames: string[] = []): number {\n  const normalized = normalizeForMatch(name);\n  const longIdx = longNames.findIndex((n) => normalizeForMatch(n) === normalized);\n  if (longIdx >= 0) return longIdx + 1;\n  const shortIdx = shortNames.findIndex((n) => normalizeForMatch(n) === normalized);\n  /* c8 ignore next */\n  if (shortIdx >= 0) return shortIdx + 1;\n  /* c8 ignore start @preserve -- unreachable: every caller passes a name\n   * captured by nameAlternation([...longNames, ...shortNames]), so the\n   * regex alternation and these two findIndex() scans are built from\n   * the same lists under the same normalizeForMatch transform. Kept as\n   * a tripwire for the type checker in case that invariant ever breaks. */\n  throw new Error(`temporal-fmt: parseRelative internal error — month \"${name}\" not in names list.`);\n  /* c8 ignore stop @preserve */\n  /* c8 ignore next -- defensive block is unreachable by construction. */\n}\n\n// English grammar — also the default when no locale is supplied. The\n// regexes here are the same ones the pre-change parseRelative() used\n// inline; they've just been pulled into a matcher list so the matching\n// engine can iterate them the same way it does for es/fr/de.\nconst ENGLISH_WEEKDAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];\nconst ENGLISH_MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\nconst ENGLISH_MONTH_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\nconst ENGLISH_GRAMMAR: RelativeDateGrammar = {\n  supportedHint: 'Supported: weekday refs (\"next Tuesday\"), day offsets (\"today\"/\"tomorrow\"/\"yesterday\"), unit offsets (\"in 3 days\", \"2 weeks ago\"), and month-day (\"March 5th\").',\n  matchers: [\n    // today / tomorrow / yesterday — exact match, most rigid shape.\n    // Checked first because they're the most common phrase class.\n    {\n      pattern: /^today$/i,\n      resolve: (_m, ctx) => buildPlainDate(ctx.temporal, readYear(ctx.reference), readMonth(ctx.reference), readDay(ctx.reference)),\n    },\n    {\n      pattern: /^tomorrow$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, 1),\n    },\n    {\n      pattern: /^yesterday$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, -1),\n    },\n    // weekday references: \"next/last/this Tuesday\". Capture the relative\n    // word and the weekday name separately, then resolve via +7 / -7.\n    {\n      pattern: new RegExp(`^(next|last|this)\\\\s+(${nameAlternation(ENGLISH_WEEKDAYS)})$`, 'i'),\n      resolve: (m, ctx) => {\n        const rel = m[1]!.toLowerCase() as 'next' | 'last' | 'this';\n        const targetDow = weekdayIndexFromName(m[2]!, ENGLISH_WEEKDAYS);\n        const refDow = extractDayOfWeek(ctx.reference);\n        return addDays(ctx.temporal, ctx.reference, weekdayOffset(rel, refDow, targetDow));\n      },\n    },\n    // unit offsets: \"in 3 days\", \"2 weeks ago\", \"in 1 month\", \"1 year ago\".\n    // Two shapes share this matcher — leading \"in\" (future) or trailing\n    // \"ago\" (past). Both lead with <number> <unit>.\n    {\n      pattern: /^(in\\s+)?(\\d+)\\s+(day|week|month|year)s?(?:\\s+ago)?$/i,\n      resolve: (m, ctx) => {\n        const inPrefix = m[1];\n        const count = m[2]!;\n        const unitName = m[3]!.toLowerCase() as 'day' | 'week' | 'month' | 'year';\n        // Disambiguate future vs past: \"in N units\" is always future; \"N\n        // units ago\" is always past. A bare \"N units\" without either is\n        // a sign error — throw, since neither direction is implied and\n        // guessing is exactly what this library refuses to do.\n        const hasIn = !!inPrefix;\n        const hasAgo = /\\bago\\b/i.test(m[0]!);\n        if (!hasIn && !hasAgo) {\n          throw new Error(\n            `temporal-fmt: parseRelative can't tell whether \"${m[0]}\" is past or future — ` +\n            `use \"in ${count} ${unitName}s\" or \"${count} ${unitName}s ago\".`\n          );\n        }\n        // Contradictory markers: the regex tolerates \"in 3 days ago\"\n        // (both a leading \"in\" and a trailing \"ago\"), which used to\n        // silently resolve as FUTURE. The library's whole posture is\n        // throw-rather-than-guess — a contradiction is worse than a\n        // missing marker, not something to quietly pick a side on.\n        if (hasIn && hasAgo) {\n          throw new Error(\n            `temporal-fmt: parseRelative got contradictory direction markers in \"${m[0]}\" — ` +\n            `\"in N ${unitName}s\" is future and \"N ${unitName}s ago\" is past; use one or the other.`\n          );\n        }\n        const sign = hasIn ? 1 : -1;\n        return addUnits(ctx.temporal, ctx.reference, sign * Number(count), unitName);\n      },\n    },\n    // month-day without year, e.g. \"March 5th\", \"March 5\", \"March 5, 2026\"\n    // (year is ignored if present). The ordinal suffix is decorative —\n    // strip it. The day-of-month is a 1- or 2-digit number.\n    {\n      pattern: new RegExp(`^(${nameAlternation([...ENGLISH_MONTHS, ...ENGLISH_MONTH_SHORT])})\\\\s+(\\\\d{1,2})(?:st|nd|rd|th)?(?:,?\\\\s*(\\\\d{4}))?$`, 'i'),\n      resolve: (m, ctx) => {\n        const month = monthIndexFromName(m[1]!, ENGLISH_MONTHS, ENGLISH_MONTH_SHORT);\n        const day = Number(m[2]!);\n        return resolveToNextOccurrence(ctx.temporal, ctx.reference, month, day);\n      },\n    },\n  ],\n};\n\n// Spanish grammar. Distinct phrase shapes from English:\n// - \"hace 2 semanas\" (past unit offset) — distinct word \"hace\", not\n//   the English \"X units ago\" suffix shape.\n// - \"5 de marzo\" — day-first, with required \"de\" between day and\n//   month, opposite of English \"March 5\".\n// - \"el próximo lunes\" / \"lunes pasado\" — weekday ref has the relative\n//   word sometimes as a prefix with article, sometimes as a suffix.\n//\n// All four phrase classes the English grammar supports have Spanish\n// equivalents here.\nconst SPANISH_WEEKDAYS = ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo'];\nconst SPANISH_MONTHS = ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'];\n// Spanish month abbreviations vary by region (\"set\" vs \"sept\" for\n// September). Sticking with the most common ICU form per locale.\nconst SPANISH_MONTH_SHORT = ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sept', 'oct', 'nov', 'dic'];\n\nconst SPANISH_GRAMMAR: RelativeDateGrammar = {\n  supportedHint: 'Frases soportadas: referencias de día de la semana (\"el próximo lunes\", \"el lunes pasado\", \"este martes\"), offsets de día (\"hoy\"/\"mañana\"/\"ayer\"), offsets de unidad (\"en 3 días\", \"hace 2 semanas\"), y mes-día (\"5 de marzo\").',\n  matchers: [\n    {\n      pattern: /^hoy$/i,\n      resolve: (_m, ctx) => buildPlainDate(ctx.temporal, readYear(ctx.reference), readMonth(ctx.reference), readDay(ctx.reference)),\n    },\n    {\n      pattern: /^ma[ñn]ana$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, 1),\n    },\n    {\n      pattern: /^ayer$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, -1),\n    },\n    // weekday references. Spanish has three common shapes, all meaning\n    // the same thing per rel word:\n    //   \"el próximo lunes\" / \"próximo lunes\"  → next\n    //   \"el lunes próximo\"                    → next (suffix variant)\n    //   \"el lunes pasado\" / \"lunes pasado\"    → last\n    //   \"este lunes\"                          → this\n    // Capture the rel word from whichever shape matched, then resolve\n    // the same way English does.\n    {\n      pattern: new RegExp(\n        `^(?:el\\\\s+)?(?:(pr[oó]ximo|pasado)\\\\s+(${nameAlternation(SPANISH_WEEKDAYS)})|(${nameAlternation(SPANISH_WEEKDAYS)})\\\\s+(pr[oó]ximo|pasado)|este\\\\s+(${nameAlternation(SPANISH_WEEKDAYS)}))$`,\n        'i',\n      ),\n      resolve: (m, ctx) => {\n        let relWord: string;\n        let weekdayName: string;\n        if (m[1] && m[2]) {\n          // prefix variant: \"próximo lunes\" / \"pasado lunes\"\n          relWord = m[1]!;\n          weekdayName = m[2]!;\n        } else if (m[3] && m[4]) {\n          // suffix variant: \"lunes próximo\" / \"lunes pasado\"\n          weekdayName = m[3]!;\n          relWord = m[4]!;\n        } else {\n          // \"este lunes\"\n          relWord = 'este';\n          weekdayName = m[5]!;\n        }\n        const rel = normalizeForMatch(relWord) === 'proximo' ? 'next' : relWord.toLowerCase() === 'este' ? 'this' : 'last';\n        const targetDow = weekdayIndexFromName(weekdayName, SPANISH_WEEKDAYS);\n        const refDow = extractDayOfWeek(ctx.reference);\n        return addDays(ctx.temporal, ctx.reference, weekdayOffset(rel, refDow, targetDow));\n      },\n    },\n    // unit offsets. Spanish uses distinct markers:\n    //   \"en 3 días\" / \"dentro de 3 días\" → future\n    //   \"hace 2 semanas\"                → past\n    // Both shapes lead with the marker, unlike English where one\n    // shape leads and the other trails.\n    {\n      pattern: new RegExp(\n        `^(?:(en|dentro\\\\s+de)\\\\s+(\\\\d+)\\\\s+(d[ií]a|semana|mes|a[ñn]o)s?|(\\\\d+)\\\\s+(d[ií]a|semana|mes|a[ñn]o)s?\\\\s+(hace))$`,\n        'i',\n      ),\n      resolve: (m, ctx) => {\n        let count: string;\n        let unitWord: string;\n        let sign: number;\n        if (m[1] && m[2] && m[3]) {\n          // future: \"en 3 días\" / \"dentro de 3 días\"\n          count = m[2]!;\n          unitWord = m[3]!;\n          sign = 1;\n        } else {\n          // past: \"2 semanas hace\" — but the more natural Spanish is\n          // \"hace 2 semanas\" (marker first). The regex above only\n          // matches \"N units hace\"; that's a less common but\n          // grammatical alternative. The primary past form \"hace N\n          // unidades\" is matched by the next matcher.\n          count = m[4]!;\n          unitWord = m[5]!;\n          sign = -1;\n        }\n        const unit = unitWordToEnglish(unitWord);\n        return addUnits(ctx.temporal, ctx.reference, sign * Number(count), unit);\n      },\n    },\n    // \"hace 2 semanas\" — the primary past-offset shape. Matcher kept\n    // separate from the future \"en/dentro de\" matcher above because\n    // Spanish word order differs between the two (marker-first for\n    // past, marker-first for future too, but with different markers).\n    {\n      pattern: new RegExp(`^hace\\\\s+(\\\\d+)\\\\s+(d[ií]a|semana|mes|a[ñn]o)s?$`, 'i'),\n      resolve: (m, ctx) => {\n        const count = Number(m[1]!);\n        const unit = unitWordToEnglish(m[2]!);\n        return addUnits(ctx.temporal, ctx.reference, -count, unit);\n      },\n    },\n    // bare \"N <unit>\" without \"en\" / \"hace\" — throw, since direction\n    // is ambiguous. Matched AFTER the directional shapes so the\n    // directional ones win when their marker is present.\n    {\n      pattern: new RegExp(`^(\\\\d+)\\\\s+(d[ií]a|semana|mes|a[ñn]o)s?$`, 'i'),\n      resolve: (m, _ctx) => {\n        throw new Error(\n          `temporal-fmt: parseRelative no puede decidir si \"${m[0]}\" es pasado o futuro — ` +\n          `usa \"en ${m[1]} ${m[2]}s\" o \"hace ${m[1]} ${m[2]}s\".`\n        );\n      },\n    },\n    // month-day: \"5 de marzo\" (day first), \"5 de marzo de 2026\" (year\n    // ignored if present). Day is 1-2 digits, with optional trailing\n    // \".\" (rare in Spanish but tolerated).\n    {\n      pattern: new RegExp(\n        `^(\\\\d{1,2})\\\\.?\\\\s+de\\\\s+(${nameAlternation([...SPANISH_MONTHS, ...SPANISH_MONTH_SHORT])})(?:\\\\s+de\\\\s+(\\\\d{4}))?$`,\n        'i',\n      ),\n      resolve: (m, ctx) => {\n        const day = Number(m[1]!);\n        const month = monthIndexFromName(m[2]!, SPANISH_MONTHS, SPANISH_MONTH_SHORT);\n        return resolveToNextOccurrence(ctx.temporal, ctx.reference, month, day);\n      },\n    },\n  ],\n};\n\n// French grammar. Distinct from English/Spanish:\n// - \"il y a 2 semaines\" (past marker is a 3-word phrase, not a single word).\n// - \"mardi prochain\" — relative word is a SUFFIX on the weekday,\n//   opposite of English \"next Tuesday\".\n// - \"5 mars\" — day-first, no \"de\" between day and month (unlike\n//   Spanish's \"5 de marzo\").\nconst FRENCH_WEEKDAYS = ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'];\nconst FRENCH_MONTHS = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'];\nconst FRENCH_MONTH_SHORT = ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'];\n\nconst FRENCH_GRAMMAR: RelativeDateGrammar = {\n  supportedHint: 'Phrases prises en charge : références de jour de la semaine (\"lundi prochain\", \"mardi dernier\", \"ce mercredi\"), décalages de jour (\"aujourd\\'hui\"/\"demain\"/\"hier\"), décalages d\\'unité (\"dans 3 jours\", \"il y a 2 semaines\"), et mois-jour (\"5 mars\").',\n  matchers: [\n    {\n      pattern: /^aujourd'hui$/i,\n      resolve: (_m, ctx) => buildPlainDate(ctx.temporal, readYear(ctx.reference), readMonth(ctx.reference), readDay(ctx.reference)),\n    },\n    {\n      pattern: /^demain$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, 1),\n    },\n    {\n      pattern: /^hier$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, -1),\n    },\n    // weekday references: \"lundi prochain\" (next), \"lundi dernier\"\n    // (last), \"ce lundi\" (this). The relative word follows the\n    // weekday for next/last, precedes it for this.\n    {\n      pattern: new RegExp(\n        `^(?:(${nameAlternation(FRENCH_WEEKDAYS)})\\\\s+(prochain|dernier)|ce\\\\s+(${nameAlternation(FRENCH_WEEKDAYS)}))$`,\n        'i',\n      ),\n      resolve: (m, ctx) => {\n        let rel: 'next' | 'last' | 'this';\n        let weekdayName: string;\n        if (m[1] && m[2]) {\n          weekdayName = m[1]!;\n          rel = m[2]!.toLowerCase() === 'prochain' ? 'next' : 'last';\n        } else {\n          rel = 'this';\n          weekdayName = m[3]!;\n        }\n        const targetDow = weekdayIndexFromName(weekdayName, FRENCH_WEEKDAYS);\n        const refDow = extractDayOfWeek(ctx.reference);\n        return addDays(ctx.temporal, ctx.reference, weekdayOffset(rel, refDow, targetDow));\n      },\n    },\n    // past: \"il y a 2 semaines\" — multi-word marker.\n    {\n      pattern: new RegExp(`^il\\\\s+y\\\\s+a\\\\s+(\\\\d+)\\\\s+(jour|semaine|mois|an|ann[eée]e)s?$`, 'i'),\n      resolve: (m, ctx) => {\n        const count = Number(m[1]!);\n        const unit = unitWordToEnglish(m[2]!);\n        return addUnits(ctx.temporal, ctx.reference, -count, unit);\n      },\n    },\n    // future: \"dans 3 jours\"\n    {\n      pattern: new RegExp(`^dans\\\\s+(\\\\d+)\\\\s+(jour|semaine|mois|an|ann[eée]e)s?$`, 'i'),\n      resolve: (m, ctx) => {\n        const count = Number(m[1]!);\n        const unit = unitWordToEnglish(m[2]!);\n        return addUnits(ctx.temporal, ctx.reference, count, unit);\n      },\n    },\n    // bare \"N <unit>\" without marker — throw.\n    {\n      pattern: new RegExp(`^(\\\\d+)\\\\s+(jour|semaine|mois|an|ann[eée]e)s?$`, 'i'),\n      resolve: (m, _ctx) => {\n        throw new Error(\n          `temporal-fmt: parseRelative ne peut pas déterminer si \"${m[0]}\" est passé ou futur — ` +\n          `utilisez \"dans ${m[1]} ${m[2]}s\" ou \"il y a ${m[1]} ${m[2]}s\".`\n        );\n      },\n    },\n    // month-day: \"5 mars\" (day first, no separator word). Year ignored.\n    {\n      pattern: new RegExp(\n        `^(\\\\d{1,2})\\\\s+(${nameAlternation([...FRENCH_MONTHS, ...FRENCH_MONTH_SHORT])})(?:\\\\s+(\\\\d{4}))?$`,\n        'i',\n      ),\n      resolve: (m, ctx) => {\n        const day = Number(m[1]!);\n        const month = monthIndexFromName(m[2]!, FRENCH_MONTHS, FRENCH_MONTH_SHORT);\n        return resolveToNextOccurrence(ctx.temporal, ctx.reference, month, day);\n      },\n    },\n  ],\n};\n\n// German grammar. Distinct from the others:\n// - Unit words pluralize with -n in the dative after \"in\"/\"vor\":\n//   \"in 3 Tagen\" (vs nominative \"3 Tage\"). The regex accepts both\n//   since callers may not always get the case right, and accepting\n//   both doesn't introduce ambiguity.\n// - \"nächsten Dienstag\" — relative word precedes weekday as a\n//   declined adjective, with the weekday capitalized as a noun.\n// - \"5. März\" — day-first with a period after the day number,\n//   matching German date convention.\nconst GERMAN_WEEKDAYS = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'];\nconst GERMAN_MONTHS = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];\nconst GERMAN_MONTH_SHORT = ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'];\n\nconst GERMAN_GRAMMAR: RelativeDateGrammar = {\n  supportedHint: 'Unterstützte Phrasen: Wochentag-Bezüge (\"nächsten Dienstag\", \"letzten Freitag\", \"diesen Montag\"), Tages-Offsets (\"heute\"/\"morgen\"/\"gestern\"), Einheiten-Offsets (\"in 3 Tagen\", \"vor 2 Wochen\"), und Monat-Tag (\"5. März\").',\n  matchers: [\n    {\n      pattern: /^heute$/i,\n      resolve: (_m, ctx) => buildPlainDate(ctx.temporal, readYear(ctx.reference), readMonth(ctx.reference), readDay(ctx.reference)),\n    },\n    {\n      pattern: /^morgen$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, 1),\n    },\n    {\n      pattern: /^gestern$/i,\n      resolve: (_m, ctx) => addDays(ctx.temporal, ctx.reference, -1),\n    },\n    // weekday references: \"nächsten Dienstag\" (next), \"letzten\n    // Dienstag\" (last), \"diesen Dienstag\" (this). Adjective precedes\n    // the weekday; case varies (nächsten/letzten/diesen all take the\n    // weak-declension -en/-en/-en ending when no article, which is\n    // convenient — one regex alternation covers all three.\n    {\n      pattern: new RegExp(`^(n(?:ae|a|ä)chsten|letzten|diesen)\\\\s+(${nameAlternation(GERMAN_WEEKDAYS)})$`, 'i'),\n      resolve: (m, ctx) => {\n        const adj = normalizeForMatch(m[1]!);\n        const rel: 'next' | 'last' | 'this' = (adj === 'nachsten' || adj === 'naechsten') ? 'next' : adj === 'diesen' ? 'this' : 'last';\n        const targetDow = weekdayIndexFromName(m[2]!, GERMAN_WEEKDAYS);\n        const refDow = extractDayOfWeek(ctx.reference);\n        return addDays(ctx.temporal, ctx.reference, weekdayOffset(rel, refDow, targetDow));\n      },\n    },\n    // past: \"vor 2 Wochen\"\n    {\n      pattern: new RegExp(`^vor\\\\s+(\\\\d+)\\\\s+(Tag(?:e|n|en)?|Woche(?:n)?|Monat(?:e|n|en)?|Jahr(?:e|n|en)?)$`, 'i'),\n      resolve: (m, ctx) => {\n        const count = Number(m[1]!);\n        const unit = unitWordToEnglish(m[2]!);\n        return addUnits(ctx.temporal, ctx.reference, -count, unit);\n      },\n    },\n    // future: \"in 3 Tagen\"\n    {\n      pattern: new RegExp(`^in\\\\s+(\\\\d+)\\\\s+(Tag(?:e|n|en)?|Woche(?:n)?|Monat(?:e|n|en)?|Jahr(?:e|n|en)?)$`, 'i'),\n      resolve: (m, ctx) => {\n        const count = Number(m[1]!);\n        const unit = unitWordToEnglish(m[2]!);\n        return addUnits(ctx.temporal, ctx.reference, count, unit);\n      },\n    },\n    // bare \"N <unit>\" without \"in\" or \"vor\" — throw.\n    {\n      pattern: new RegExp(`^(\\\\d+)\\\\s+(Tag(?:e|n|en)?|Woche(?:n)?|Monat(?:e|n|en)?|Jahr(?:e|n|en)?)$`, 'i'),\n      resolve: (m, _ctx) => {\n        throw new Error(\n          `temporal-fmt: parseRelative kann nicht erkennen, ob \"${m[0]}\" Vergangenheit oder Zukunft ist — ` +\n          `verwende \"in ${m[1]} ${m[2]}\" oder \"vor ${m[1]} ${m[2]}\".`\n        );\n      },\n    },\n    // month-day: \"5. März\" (day-first with period). Year ignored.\n    {\n      pattern: new RegExp(\n        `^(\\\\d{1,2})\\\\.?\\\\s+(${nameAlternation([...GERMAN_MONTHS, ...GERMAN_MONTH_SHORT, 'Maerz', 'Maer'])})(?:\\\\s+(\\\\d{4}))?$`,\n        'i',\n      ),\n      resolve: (m, ctx) => {\n        const day = Number(m[1]!);\n        const month = monthIndexFromName(m[2]!, GERMAN_MONTHS, GERMAN_MONTH_SHORT);\n        return resolveToNextOccurrence(ctx.temporal, ctx.reference, month, day);\n      },\n    },\n  ],\n};\n\nconst GRAMMARS: Record<string, RelativeDateGrammar> = {\n  en: ENGLISH_GRAMMAR,\n  es: SPANISH_GRAMMAR,\n  fr: FRENCH_GRAMMAR,\n  de: GERMAN_GRAMMAR,\n};\n\n// Pick a grammar for a locale. Falls back to English for languages we\n// don't have a grammar for (Italian, Portuguese, etc.) rather than\n// throwing — best-effort, matches how formatDistance treats unknown\n// locales (Intl.RelativeTimeFormat accepts them; here we fall back to\n// English so the call still succeeds with reasonable output).\nfunction grammarForLocale(locale: string | undefined): RelativeDateGrammar {\n  if (!locale) return ENGLISH_GRAMMAR;\n  try {\n    // Intl.Locale requires BCP-47 hyphens — same normalization as the\n    // other locale-handling code in this library.\n    const tag = new Intl.Locale(locale.replace(/_/g, '-'));\n    const lang = tag.language.toLowerCase();\n    return GRAMMARS[lang] ?? ENGLISH_GRAMMAR;\n  } catch {\n    // Malformed locale tag — fall back to English. The actual Intl\n    // call downstream will throw if the tag is genuinely unusable,\n    // which is a better surface for that error than here.\n    return ENGLISH_GRAMMAR;\n  }\n}\n\n// Language subtag of a locale option, for dispatching to grammars\n// registered via registerRelativeGrammar(). Mirrors grammarForLocale's\n// normalization and fallback.\nfunction languageOf(locale: string | undefined): string {\n  if (!locale) return 'en';\n  try {\n    return new Intl.Locale(locale.replace(/_/g, '-')).language.toLowerCase();\n  } catch {\n    return 'en';\n  }\n}\n\n// Map a per-language unit word back to the English unit name the\n// shared addUnits() helper expects. Each language contributes its own\n// regex alternation of unit words; this function normalizes the\n// captured word back to a unit enum value.\nfunction unitWordToEnglish(word: string): 'day' | 'week' | 'month' | 'year' {\n  const w = normalizeForMatch(word);\n  // English\n  /* c8 ignore next */\n  if (w === 'day' || w === 'week' || w === 'month' || w === 'year') return w;\n  // Spanish (accent-stripped)\n  if (w === 'dia') return 'day';\n  if (w === 'semana') return 'week';\n  if (w === 'mes') return 'month';\n  if (w === 'ano' || w === 'año') return 'year';\n  // French\n  if (w === 'jour') return 'day';\n  if (w === 'semaine') return 'week';\n  if (w === 'mois') return 'month';\n  if (w === 'an' || w === 'annee') return 'year';\n  // German\n  if (w === 'tag' || w === 'tagen') return 'day';\n  if (w === 'woche' || w === 'wochen') return 'week';\n  if (w === 'monat' || w === 'monaten') return 'month';\n  /* c8 ignore next */\n  if (w === 'jahr' || w === 'jahren') return 'year';\n  /* c8 ignore start @preserve -- unreachable: every caller passes a word\n   * captured by a regex alternation built from exactly these unit-word\n   * forms (day/week/month/year across en/es/fr/de), so the branches\n   * above already cover every string that can reach this function.\n   * Kept as a tripwire for the type checker in case a grammar adds a\n   * unit word here without a matching regex update. */\n  throw new Error(`temporal-fmt: parseRelative internal error — unrecognized unit word \"${word}\".`);\n  /* c8 ignore stop @preserve */\n  /* c8 ignore next -- defensive block is unreachable by construction. */\n}\n\n// Reference: kept exported for the unit tests that need it. The other\n// helpers above are not exported since tests only need to drive\n// parseRelative() through the public API + this one constant for the\n// Tuesday-on-Tuesday fixture.\nexport const WEEKDAY_NAMES = ENGLISH_WEEKDAYS;\nexport const MONTH_NAMES = ENGLISH_MONTHS;\n// Exported for the localeVocab-style stub-test pattern in case a future\n// test wants to verify a grammar's name list against Intl's actual\n// output for that locale — same pattern localeVocab.test.js uses to\n// catch a mismatch between what format() produces and what parse()\n// expects.\nexport const SPANISH_MONTH_NAMES = SPANISH_MONTHS;\nexport const FRENCH_MONTH_NAMES = FRENCH_MONTHS;\nexport const GERMAN_MONTH_NAMES = GERMAN_MONTHS;\nexport const SPANISH_WEEKDAY_NAMES = SPANISH_WEEKDAYS;\nexport const FRENCH_WEEKDAY_NAMES = FRENCH_WEEKDAYS;\nexport const GERMAN_WEEKDAY_NAMES = GERMAN_WEEKDAYS;\nvoid WEEKDAY_NAMES;\nvoid MONTH_NAMES;\n\nexport interface ParseRelativeOptions extends FormatOptions {\n  /**\n   * Opt-in typo tolerance. When the input doesn't match any phrase\n   * exactly, retry after correcting individual words (weekday names,\n   * month names, and marker words like \"next\"/\"ago\"/\"tomorrow\") that\n   * are within a small edit distance of a known word — e.g.\n   * \"tommorow\" → \"tomorrow\", \"next tuesady\" → \"next tuesday\". Numbers\n   * are never touched.\n   *\n   * Off by default, matching this library's throw-rather-than-guess\n   * philosophy elsewhere (parse()'s `lenient` option is the same shape\n   * of opt-in). English only for this option currently — combining\n   * `fuzzy: true` with a non-English `locale` throws rather than\n   * silently skipping the fuzzy pass.\n   *\n   * If no correction produces a recognized phrase, throws the same\n   * \"doesn't recognize\" error the exact pass would have thrown.\n   */\n  fuzzy?: boolean;\n}\n\n/**\n * Resolve common relative-date phrases against a reference date,\n * returning a Temporal.PlainDate. Supports English by default, plus\n * Spanish (es), French (fr), and German (de) via the `locale` option.\n *\n * Supported phrase classes (with examples per language):\n *\n * - weekday refs: \"next Tuesday\" / \"el próximo martes\" / \"mardi prochain\" / \"nächsten Dienstag\"\n * - day offsets: \"today\" / \"hoy\" / \"aujourd'hui\" / \"heute\" (and tomorrow/yesterday equivalents)\n * - unit offsets: \"in 3 days\" / \"en 3 días\" / \"dans 3 jours\" / \"in 3 Tagen\"\n * - month-day without year: \"March 5th\" / \"5 de marzo\" / \"5 mars\" / \"5. März\"\n *\n * Ambiguous-case handling is consistent across all four languages:\n * \"next X\" said on X (today is the named weekday) means 7 days from\n * now, not today. \"last X\" said on X means 7 days ago. See README\n * \"parseRelative\" for the documented behavior of each ambiguous case.\n *\n * Throws a descriptive error for any phrase it doesn't recognize in\n * the target language, rather than guessing. A bare \"5 days\" without\n * \"in\" or \"ago\" (or the per-language equivalent) throws with a message\n * pointing at the disambiguation options.\n *\n * Returns a Temporal.PlainDate for every supported phrase. Time-of-day\n * extensions like \"next Tuesday at 3pm\" aren't supported in this pass.\n */\nexport function parseRelative(\n  input: string,\n  referenceDate: unknown,\n  options: ParseRelativeOptions = {},\n): unknown {\n  const reference = referenceDate as TemporalFieldBag;\n  const temporal = getTemporal();\n\n  // Trim, collapse internal whitespace, strip diacritics, and lowercase.\n  // Whitespace normalization is shared with the pre-change behavior;\n  // diacritic stripping pairs with nameAlternation()'s normalization so\n  // \"mi[eé]rcoles\" and \"miercoles\" both match the same pattern.\n  // Lowercasing matches the case-insensitive regex flag explicitly so\n  // the user's input never gets case-swapped on its way through the\n  // matcher (the regexes are 'i'-flagged, but normalizing here keeps\n  // the original-trimmed-string echo in error messages predictable).\n  const trimmed = (input ?? '').trim().replace(/\\s+/g, ' ');\n  if (trimmed.length === 0) {\n    throw new Error('temporal-fmt: parseRelative got an empty input string.');\n  }\n  if (trimmed.length > MAX_RELATIVE_INPUT_LENGTH) {\n    throw new RangeError(\n      `temporal-fmt: parseRelative input is too large (maximum ${MAX_RELATIVE_INPUT_LENGTH} characters).`,\n    );\n  }\n  // For error messages, keep the user's original spelling (with accents)\n  // so the echo in the \"doesn't recognize\" error matches what they\n  // typed. The matching itself uses the diacritic-stripped form so\n  // \"mi[eé]rcoles\" / \"miercoles\" / \"MI[ÉE]RCOLES\" all match the same\n  // pattern without forcing the user to remember the accent.\n  const normalized = normalizeForMatch(trimmed);\n\n  const grammar = grammarForLocale(options.locale);\n  const ctx: ResolveContext = { temporal, reference };\n\n  // Registered grammars (registerRelativeGrammar) take precedence over\n  // the built-in ones for their language — that's the documented\n  // contract in relativeGrammar.ts (\"try registered grammars before\n  // falling back to the built-in ones\"). This wiring was missing\n  // entirely before: registered grammars were stored and listed but\n  // never consulted, so the extension point silently did nothing.\n  // Returns null quickly when nothing is registered for the language.\n  const registered = tryRegisteredGrammar(languageOf(options.locale), trimmed, {\n    year: reference.year as number,\n    month: reference.month as number,\n    day: reference.day as number,\n    dayOfWeek: reference.dayOfWeek as number,\n  });\n  if (registered !== null) {\n    return registered;\n  }\n\n  const tryMatch = (text: string): unknown | typeof NO_MATCH => {\n    for (const matcher of grammar.matchers) {\n      const match = text.match(matcher.pattern);\n      if (match) {\n        return matcher.resolve(match, ctx);\n      }\n    }\n    return NO_MATCH;\n  };\n\n  const exactResult = tryMatch(normalized);\n  if (exactResult !== NO_MATCH) {\n    return exactResult;\n  }\n\n  if (options.fuzzy) {\n    // Fuzzy mode is English-only for this pass — see the vocabulary\n    // comment above fuzzyCorrectEnglish for why the other three\n    // grammars aren't covered. Fail loudly rather than silently\n    // skipping the fuzzy attempt, so a caller relying on fuzzy mode\n    // for, say, French input doesn't get a confusing \"doesn't\n    // recognize\" error with no indication fuzzy matching never ran.\n    if (grammar !== ENGLISH_GRAMMAR) {\n      throw new Error(\n        `temporal-fmt: parseRelative's { fuzzy: true } option currently only supports English. ` +\n        `Pass no locale (or locale: 'en'), or omit { fuzzy: true } for this locale.`\n      );\n    }\n    const corrected = fuzzyCorrectEnglish(normalized);\n    if (corrected !== undefined) {\n      const fuzzyResult = tryMatch(corrected);\n      if (fuzzyResult !== NO_MATCH) {\n        return fuzzyResult;\n      }\n    }\n  }\n\n  throw new Error(\n    `temporal-fmt: parseRelative doesn't recognize \"${trimmed}\". ` +\n    grammar.supportedHint\n  );\n}\n\n// Sentinel distinguishing \"no matcher matched\" from a legitimate\n// resolve() return value of `undefined`/`null` (matchers can throw\n// their own errors, e.g. the ambiguous-direction case, but none\n// currently return a nullish PlainDate — this sentinel just makes the\n// \"no match\" case unambiguous regardless).\nconst NO_MATCH = Symbol('temporal-fmt: parseRelative no match');\n\n// DEFAULT_LOCALE is imported for the option's default-value documentation\n// above (no locale → English). The symbol itself isn't read at runtime\n// here, but the import keeps the dependency edge explicit so future\n// changes to the default-locale constant propagate here too.\nvoid DEFAULT_LOCALE;","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Per-token metadata: the structured descriptor this module\n// asks for (meaning, format-capable?, parse-capable?, locale-sensitive?,\n// calendar-sensitive?, timezone-sensitive?, supported Temporal types,\n// round-trip-safe?). One table, kept in sync with TOKENS in tokens.ts\n// by tests (see test/tokenMetadata.test.js — every entry in TOKENS has\n// a metadata entry, and vice versa).\n//\n// This is the single source of truth that analyzeFormat() (section E)\n// and the ESLint plugin / codemod consume — never read the\n// TOKENS array directly for metadata; use TOKEN_METADATA here, or the\n// tokenInfo() / listTokens() wrappers in analyze.ts.\n\nimport type { TemporalLike } from './tokens.js';\n\nexport type TemporalType =\n  | 'Instant'\n  | 'PlainDate'\n  | 'PlainTime'\n  | 'PlainDateTime'\n  | 'ZonedDateTime'\n  | 'PlainYearMonth'\n  | 'PlainMonthDay';\n\nexport interface TokenMetadata {\n  // Short human-readable description of what the token represents.\n  meaning: string;\n  // True if format() accepts this token. Every token in TOKENS is\n  // format-capable by construction; this flag exists so the table is\n  // self-describing for callers (the codemod) that work with token\n  // families including format-only tokens from other libraries.\n  formatCapable: boolean;\n  // True if parse() accepts this token. False for `do`, `ww`, `RRRR`\n  // — see FORMAT_ONLY_TOKENS in pattern.ts.\n  parseCapable: boolean;\n  // True if the output depends on locale (resolves via Intl or\n  // custom vocab). MMMM/MMM/EEEE/EEE/a are true; everything else is\n  // numeric ASCII and locale-independent.\n  localeSensitive: boolean;\n  // True if the output depends on the calendar (gregory, hebrew,\n  // etc.). Locale-aware tokens inherit calendar sensitivity from\n  // the Intl path (a hebrew PlainDate's month name depends on the\n  // hebrew calendar). Year/month/day numeric tokens are calendar-\n  // sensitive in principle (a Hebrew year/month renders differently\n  // than a Gregorian one) but stay ISO-numeric on the format side\n  // because tokens.ts reads straight off TemporalLike fields, which\n  // are already calendar-specific by the time format() sees them.\n  calendarSensitive: boolean;\n  // True if the token requires a timeZoneId or offset field — i.e.\n  // only ZonedDateTime supports it. zzz and the six offset tokens\n  // (X/XX/XXX/x/xx/xxx) are timezone-sensitive.\n  timezoneSensitive: boolean;\n  // Which Temporal types can supply the field this token needs.\n  // PlainTime can't supply year; PlainDate can't supply hour; only\n  // ZonedDateTime carries timeZoneId/offset.\n  supportedTypes: TemporalType[];\n  // True if format(x, fmt) → parse(fmt, output) round-trips back to\n  // a value equal to x. False when the format is fundamentally lossy:\n  // `do` (ordinal suffix isn't structurally parseable), `ww`/`RRRR`\n  // (week + weekday alone can't reconstruct a date without an extra\n  // disambiguator), `yy` (two-digit year loses century — strptime\n  // heuristic resolves it, but the heuristic isn't symmetric with\n  // how `yy` formats BCE years, so round-trip only works for years\n  // where 00-68/69-99 lands back on the same century).\n  roundTripSafe: boolean;\n}\n\n// Helper: which Temporal types carry each field. Centralized here so\n// the supportedTypes arrays below stay short and the table is easy to\n// audit. Mirrors the field checks in tokens.ts (handler third tuple\n// element).\nconst TYPES_WITH: Record<string, TemporalType[]> = {\n  year: ['PlainDate', 'PlainDateTime', 'ZonedDateTime', 'PlainYearMonth'],\n  month: ['PlainDate', 'PlainDateTime', 'ZonedDateTime', 'PlainYearMonth', 'PlainMonthDay'],\n  day: ['PlainDate', 'PlainDateTime', 'ZonedDateTime', 'PlainMonthDay'],\n  // Instant deliberately NOT listed: Temporal.Instant exposes no\n  // hour/minute/second/millisecond wall-clock fields (they're\n  // zone-dependent), so format(instant, 'HH') throws at the field\n  // check — the metadata used to claim Instant was supported, telling\n  // analyzer/IDE consumers the opposite of what runtime does.\n  hour: ['PlainTime', 'PlainDateTime', 'ZonedDateTime'],\n  minute: ['PlainTime', 'PlainDateTime', 'ZonedDateTime'],\n  second: ['PlainTime', 'PlainDateTime', 'ZonedDateTime'],\n  millisecond: ['PlainTime', 'PlainDateTime', 'ZonedDateTime'],\n  dayOfWeek: ['PlainDate', 'PlainDateTime', 'ZonedDateTime'],\n  timeZoneId: ['ZonedDateTime'],\n  offset: ['ZonedDateTime'],\n};\n\n// Every token in TOKENS gets an entry here. Adding a token to TOKENS\n// without adding one here makes test/tokenMetadata.test.js fail.\nexport const TOKEN_METADATA: Record<string, TokenMetadata> = {\n  yyyy: {\n    meaning: 'Four-digit year (preserves sign for BCE; no truncation).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.year, roundTripSafe: true,\n  },\n  yy: {\n    meaning: 'Two-digit year (year % 100). Throws on negative years.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.year, roundTripSafe: false,\n  },\n  y: {\n    meaning: 'Unpadded year, any width (preserves sign for BCE; no truncation, no minimum digits). Cannot sit directly next to another digit-reading token or a literal starting with a digit — there would be no way to tell where it ends.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.year, roundTripSafe: true,\n  },\n  MMMM: {\n    meaning: 'Long month name (locale-aware, e.g. \"January\", \"janvier\").',\n    formatCapable: true, parseCapable: true, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  MMM: {\n    meaning: 'Short month name (locale-aware, e.g. \"Jan\", \"janv.\").',\n    formatCapable: true, parseCapable: true, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  MM: {\n    meaning: 'Two-digit month (01-12, zero-padded).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  M: {\n    meaning: 'One- or two-digit month (1-12, no padding).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  dd: {\n    meaning: 'Two-digit day-of-month (01-31, zero-padded).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.day, roundTripSafe: true,\n  },\n  d: {\n    meaning: 'One- or two-digit day-of-month (1-31, no padding).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.day, roundTripSafe: true,\n  },\n  EEEE: {\n    meaning: 'Long weekday name (locale-aware, e.g. \"Monday\", \"lundi\"). Parse cross-checks against the parsed date.',\n    formatCapable: true, parseCapable: true, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.dayOfWeek, roundTripSafe: true,\n  },\n  EEE: {\n    meaning: 'Short weekday name (locale-aware, e.g. \"Mon\", \"lun.\"). Parse cross-checks against the parsed date.',\n    formatCapable: true, parseCapable: true, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.dayOfWeek, roundTripSafe: true,\n  },\n  HH: {\n    meaning: 'Two-digit hour, 24-hour clock (00-23, zero-padded).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.hour, roundTripSafe: true,\n  },\n  H: {\n    meaning: 'One- or two-digit hour, 24-hour clock (0-23, no padding).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.hour, roundTripSafe: true,\n  },\n  hh: {\n    meaning: 'Two-digit hour, 12-hour clock (01-12, zero-padded). Requires `a` token on parse.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.hour, roundTripSafe: true,\n  },\n  h: {\n    meaning: 'One- or two-digit hour, 12-hour clock (1-12, no padding). Requires `a` token on parse.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.hour, roundTripSafe: true,\n  },\n  mm: {\n    meaning: 'Two-digit minute (00-59, zero-padded).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.minute, roundTripSafe: true,\n  },\n  m: {\n    meaning: 'One- or two-digit minute (0-59, no padding).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.minute, roundTripSafe: true,\n  },\n  ss: {\n    meaning: 'Two-digit second (00-59, zero-padded).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.second, roundTripSafe: true,\n  },\n  s: {\n    meaning: 'One- or two-digit second (0-59, no padding).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.second, roundTripSafe: true,\n  },\n  S: {\n    meaning: 'Fractional second, 1 digit (tenths of a second).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SS: {\n    meaning: 'Fractional second, 2 digits (hundredths of a second).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSS: {\n    meaning: 'Fractional second, 3 digits (milliseconds).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSSS: {\n    meaning: 'Fractional second, 4 digits (tens of microseconds).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSSSS: {\n    meaning: 'Fractional second, 5 digits (hundred-thousandths of a second).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSSSSS: {\n    meaning: 'Fractional second, 6 digits (microseconds).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSSSSSS: {\n    meaning: 'Fractional second, 7 digits (tens of nanoseconds).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSSSSSSS: {\n    meaning: 'Fractional second, 8 digits (hundred-millionths of a second).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  SSSSSSSSS: {\n    meaning: 'Fractional second, 9 digits (nanoseconds).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.millisecond, roundTripSafe: true,\n  },\n  a: {\n    meaning: 'Day period (locale-aware: \"AM\"/\"PM\", \"午前\"/\"午後\", etc.). Required alongside 12-hour tokens on parse.',\n    formatCapable: true, parseCapable: true, localeSensitive: true, calendarSensitive: false, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.hour, roundTripSafe: true,\n  },\n  zzz: {\n    meaning: 'IANA time zone id (e.g. \"America/New_York\") or fixed offset (\"+05:30\"). Requires full date+time on parse.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.timeZoneId, roundTripSafe: true,\n  },\n  X: {\n    meaning: 'Numeric UTC offset, short (Z for UTC, ±HH[MM] otherwise). Minutes omitted when zero.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.offset, roundTripSafe: true,\n  },\n  XX: {\n    meaning: 'Numeric UTC offset, no colon (Z for UTC, ±HHMM otherwise).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.offset, roundTripSafe: true,\n  },\n  XXX: {\n    meaning: 'Numeric UTC offset, with colon (Z for UTC, ±HH:MM otherwise).',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.offset, roundTripSafe: true,\n  },\n  x: {\n    meaning: 'Numeric UTC offset, short, never Z (always ±HH[MM]). Lowercase variant of X.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.offset, roundTripSafe: true,\n  },\n  xx: {\n    meaning: 'Numeric UTC offset, no colon, never Z (always ±HHMM). Lowercase variant of XX.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.offset, roundTripSafe: true,\n  },\n  xxx: {\n    meaning: 'Numeric UTC offset, with colon, never Z (always ±HH:MM). Lowercase variant of XXX.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.offset, roundTripSafe: true,\n  },\n  do: {\n    meaning: 'Ordinal day-of-month with English suffix (\"1st\", \"2nd\", \"3rd\", \"4th\", ... 21st, 22nd, ...). Format-only — not parseable.',\n    formatCapable: true, parseCapable: false, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.day, roundTripSafe: false,\n  },\n  Q: {\n    meaning: 'Quarter as a digit (1-4). Derived from month.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  QQQ: {\n    meaning: 'Quarter with \"Q\" prefix (\"Q1\"..\"Q4\"). Derived from month.',\n    formatCapable: true, parseCapable: true, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  ww: {\n    meaning: 'ISO 8601 week number (01-53). Format-only — week alone can\\'t reconstruct a date.',\n    formatCapable: true, parseCapable: false, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.dayOfWeek, roundTripSafe: false,\n  },\n  RRRR: {\n    meaning: 'ISO 8601 week-numbering year (4-digit, may differ from calendar year at year boundaries). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.dayOfWeek, roundTripSafe: false,\n  },\n  // Day-of-year is leap-adjusted, so it needs a YEAR — PlainMonthDay\n  // (month+day with no year) used to be listed as supported here while\n  // format() computed a non-leap day-of-year for it.\n  D: {\n    meaning: 'Day of year, unpadded (1-366). Format-only — parsing requires resolving against a year.',\n    formatCapable: true, parseCapable: false, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.day.filter((t) => t !== 'PlainMonthDay'), roundTripSafe: false,\n  },\n  DD: {\n    meaning: 'Day of year, 2-digit minimum (01-366). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.day.filter((t) => t !== 'PlainMonthDay'), roundTripSafe: false,\n  },\n  DDD: {\n    meaning: 'Day of year, 3-digit zero-padded (001-366). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: false, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.day.filter((t) => t !== 'PlainMonthDay'), roundTripSafe: false,\n  },\n  LLLL: {\n    meaning: 'Stand-alone long month name (nominative case in Slavic locales). Identical to MMMM in most locales.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  LLL: {\n    meaning: 'Stand-alone short month name. Identical to MMM in most locales.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.month, roundTripSafe: true,\n  },\n  cccc: {\n    meaning: 'Stand-alone long weekday name. Identical to EEEE in most locales.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.dayOfWeek, roundTripSafe: true,\n  },\n  ccc: {\n    meaning: 'Stand-alone short weekday name. Identical to EEE in most locales.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.dayOfWeek, roundTripSafe: true,\n  },\n  GGGG: {\n    meaning: 'Long era name (locale-aware, e.g. \"Anno Domini\"/\"Before Christ\"). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.year, roundTripSafe: false,\n  },\n  G: {\n    meaning: 'Short era name (locale-aware, e.g. \"AD\"/\"BC\"). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: true, timezoneSensitive: false,\n    supportedTypes: TYPES_WITH.year, roundTripSafe: false,\n  },\n  zzzz: {\n    meaning: 'Localized long timezone name (e.g. \"Eastern Standard Time\"). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.timeZoneId, roundTripSafe: false,\n  },\n  z: {\n    meaning: 'Localized short timezone name (e.g. \"EST\"). Format-only.',\n    formatCapable: true, parseCapable: false, localeSensitive: true, calendarSensitive: false, timezoneSensitive: true,\n    supportedTypes: TYPES_WITH.timeZoneId, roundTripSafe: false,\n  },\n\n};\n\nexport const ALL_TOKEN_NAMES: string[] = Object.keys(TOKEN_METADATA);","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Format-string analysis and introspection. Single source of truth for\n// \"what does this format string need / accept / produce\" — consumed by\n// the ESLint plugin and the codemod\n// so they don't each carry their own token table that drifts out of\n// sync with the runtime. Everything here reads from TOKENS in\n// tokens.ts and TOKEN_METADATA in tokenMetadata.ts, so adding a token\n// to those two tables automatically makes it visible to analyze()\n// without touching this file.\n\nimport { TOKENS, type TemporalLike } from './tokens.js';\nimport { TOKEN_METADATA, type TokenMetadata, type TemporalType } from './tokenMetadata.js';\nimport { tokenize, tokenizeWithSpans, type Piece } from './tokenize.js';\nimport { _handlerFor } from './format.js';\nimport { UNPADDED_NUMERIC_TOKENS, FORMAT_ONLY_TOKENS } from './pattern.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\n// Re-exported so callers can import everything analyzer-related from a\n// single entry point — analyze.ts is the introspection surface.\nexport type { TokenMetadata, TemporalType } from './tokenMetadata.js';\nexport type { Piece } from './tokenize.js';\n\n// tokenizeFormat is the same tokenize() the runtime uses, exposed\n// under a name that signals \"this is the introspection entry point.\"\n// Same implementation, different name — callers reading analyze.ts\n// see a coherent API surface rather than having to know that the\n// runtime tokenizer is the right thing to call.\nexport function tokenizeFormat(formatStr: string): Piece[] {\n  return tokenize(formatStr);\n}\n\n// listTokens: every token the runtime recognizes, with metadata. Used\n// by IDE autocomplete data (section AC) and the codemod's \"can this\n// source-library token be translated?\" lookup (section Z).\nexport function listTokens(): Array<{ name: string; metadata: TokenMetadata }> {\n  return TOKENS.map(([name]) => ({ name, metadata: TOKEN_METADATA[name]! }));\n}\n\n// tokenInfo: one token's metadata. Returns undefined for unknown\n// tokens rather than throwing — callers (autocomplete, hover docs)\n// want a sentinel, not an exception, when a user types a partial token.\nexport function tokenInfo(name: string): TokenMetadata | undefined {\n  return TOKEN_METADATA[name];\n}\n\nexport interface AnalyzedToken {\n  name: string;\n  // Position in the format string, 0-indexed. Useful for IDE diagnostics\n  // that highlight a specific token.\n  position: number;\n  metadata: TokenMetadata;\n}\n\nexport interface FormatAnalysis {\n  // Every token in the format string, in order, with metadata.\n  tokens: AnalyzedToken[];\n  // Fields (year/month/day/hour/...) any token in this format string\n  // reads off the input. Lets a caller statically check \"does this\n  // format string need a field PlainDate doesn't have?\"\n  requiredFields: string[];\n  // Temporal types that can supply every required field. The intersection\n  // across all tokens — a format string with both `yyyy` (needs year)\n  // and `HH` (needs hour) is compatible only with types carrying both,\n  // i.e. PlainDateTime/ZonedDateTime.\n  compatibleTypes: TemporalType[];\n  // Can parse() accept this format string? False when any token is\n  // format-only (do/ww/RRRR per FORMAT_ONLY_TOKENS in pattern.ts).\n  parseable: boolean;\n  // Does the format string contain any locale-aware token (MMMM/MMM/\n  // EEEE/EEE/a)? True means the output depends on the locale option\n  // and a registered custom vocab can override the result.\n  localeSensitive: boolean;\n  // Does the format string contain any calendar-sensitive token?\n  // Almost every date/weekday token is, since its output depends on\n  // the object's calendar (a hebrew PlainDate's \"MMMM\" is a hebrew\n  // month name). Pure-time tokens (HH/mm/ss) are not.\n  calendarSensitive: boolean;\n  // Does the format string contain zzz or any offset token? If yes,\n  // only ZonedDateTime can supply the field.\n  timezoneSensitive: boolean;\n  // Does the format string contain a run of 2+ adjacent unpadded\n  // numeric tokens with no literal between them (Md, dM, Hms, ...)?\n  // Such runs can be ambiguous at parse time — strict mode throws,\n  // lenient mode picks one split via the documented heuristic.\n  ambiguous: boolean;\n  // Does format(x, fmt) → parse(fmt, output) round-trip? False when\n  // any token is format-only OR when yy is used (century loss).\n  roundTripSafe: boolean;\n  // Non-fatal issues found during analysis. Each carries a `code`\n  // the IDE plugin / CLI can switch on. Empty for clean format strings.\n  warnings: Array<{ code: string; message: string }>;\n}\n\nexport function analyzeFormat(formatStr: string): FormatAnalysis {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new Error(\n      `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n      `(got ${formatStr.length}).`\n    );\n  }\n  const pieces = tokenizeWithSpans(formatStr);\n  const tokens: AnalyzedToken[] = [];\n  const requiredFields = new Set<string>();\n  const compatibleTypesSet = new Set<TemporalType>();\n  let parseable = true;\n  let localeSensitive = false;\n  let calendarSensitive = false;\n  let timezoneSensitive = false;\n  let roundTripSafe = true;\n  const warnings: Array<{ code: string; message: string }> = [];\n\n  // Walk pieces, building up the analysis. Each token's `position` is\n  // its exact source index in the ORIGINAL format string (from\n  // tokenizeWithSpans) — decoded literal lengths used to be accumulated\n  // instead, which under-counted every quoted span ('a b' is 5 source\n  // chars, 3 decoded; '' is 2 source chars, 1 decoded), so every token\n  // after any quote escape reported a position that was too small.\n  const unpaddedRun: string[] = [];\n  const flushRun = () => {\n    if (unpaddedRun.length >= 2) {\n      warnings.push({\n        code: 'AMBIGUOUS_NUMERIC_RUN',\n        message: `Adjacent unpadded numeric tokens \"${unpaddedRun.join('')}\" with no separator can be ambiguous to parse. Add a separator or use the padded form (e.g. \"MM\" instead of \"M\").`,\n      });\n    }\n    unpaddedRun.length = 0;\n  };\n\n  for (const piece of pieces) {\n    if (piece.kind === 'literal') {\n      flushRun();\n      continue;\n    }\n    const metadata = TOKEN_METADATA[piece.value];\n    // Dead by construction, confirmed via listTokens(): every token in\n    // TOKENS has a matching TOKEN_METADATA entry (51/51), and tokenize()\n    // already throws on any string that isn't in TOKENS before this loop\n    // ever runs. Kept as a guard against the two tables drifting apart.\n    /* c8 ignore start */\n    if (!metadata) {\n      warnings.push({\n        code: 'UNKNOWN_TOKEN_NO_METADATA',\n        message: `Token \"${piece.value}\" is recognized by the tokenizer but has no metadata entry in tokenMetadata.ts — this is a bug in temporal-fmt.`,\n      });\n      continue;\n    }\n    /* c8 ignore stop */\n    tokens.push({ name: piece.value, position: piece.start, metadata });\n\n    // Required fields: read off the handler map (the source of truth\n    // for \"what field does this token need\"). Falls back to the\n    // metadata's supportedTypes-derived field set if the handler isn't\n    // found, which also shouldn't happen.\n    const handler = _handlerFor(piece.value);\n    if (handler) {\n      requiredFields.add(handler.field as string);\n    }\n\n    // compatibleTypes: intersect every token's supportedTypes. The\n    // first token seeds the set; subsequent tokens narrow it.\n    if (tokens.length === 1) {\n      for (const t of metadata.supportedTypes) compatibleTypesSet.add(t);\n    } else {\n      const stillCompatible = new Set<TemporalType>();\n      for (const t of compatibleTypesSet) {\n        if (metadata.supportedTypes.includes(t)) stillCompatible.add(t);\n      }\n      compatibleTypesSet.clear();\n      for (const t of stillCompatible) compatibleTypesSet.add(t);\n    }\n\n    if (!metadata.parseCapable) {\n      parseable = false;\n      warnings.push({\n        code: 'FORMAT_ONLY_TOKEN',\n        message: `Token \"${piece.value}\" is format-only — it can't be parsed back into a value. Use a parse-capable variant (e.g. \"d\" instead of \"do\") if you need round-trip.`,\n      });\n    }\n    if (metadata.localeSensitive) localeSensitive = true;\n    if (metadata.calendarSensitive) calendarSensitive = true;\n    if (metadata.timezoneSensitive) timezoneSensitive = true;\n    if (!metadata.roundTripSafe) roundTripSafe = false;\n\n    // Track runs of adjacent unpadded numeric tokens — same definition\n    // as parsePattern.ts uses (UNPADDED_NUMERIC_TOKENS). A literal\n    // between tokens breaks the run; this is checked by the flushRun\n    // call above.\n    if (UNPADDED_NUMERIC_TOKENS.has(piece.value)) {\n      unpaddedRun.push(piece.value);\n    } else {\n      flushRun();\n    }\n  }\n  flushRun();\n\n  // Cross-token checks the runtime parse() performs. Mirroring them\n  // here lets the ESLint plugin flag them statically without having\n  // to re-derive the logic.\n  const tokenNames = tokens.map((t) => t.name);\n  const has12Hour = tokenNames.some((t) => t === 'hh' || t === 'h');\n  const has24Hour = tokenNames.some((t) => t === 'HH' || t === 'H');\n  const hasAPeriod = tokenNames.some((t) => t === 'a');\n  if (has12Hour && !hasAPeriod) {\n    warnings.push({\n      code: 'TWELVE_HOUR_WITHOUT_A',\n      message: '12-hour token (\"hh\"/\"h\") used without an \"a\" (AM/PM) token — parse() can\\'t tell AM from PM and throws at runtime.',\n    });\n  }\n  if (has12Hour && has24Hour) {\n    warnings.push({\n      code: 'MIXED_12_AND_24_HOUR',\n      message: 'Mixing 24-hour and 12-hour tokens — parse() refuses to guess which is authoritative and throws at runtime.',\n    });\n  }\n\n  const hasOffset = tokenNames.some((t) => t === 'X' || t === 'XX' || t === 'XXX' || t === 'x' || t === 'xx' || t === 'xxx');\n  const hasZzz = tokenNames.some((t) => t === 'zzz');\n  if (hasOffset && hasZzz) {\n    warnings.push({\n      code: 'ZZZ_WITH_OFFSET_TOKEN',\n      message: 'Format string has both \"zzz\" and an offset token — parse() cross-checks them and throws if the parsed offset disagrees with the zone\\'s actual offset.',\n    });\n  }\n  if (hasOffset && !requiredFields.has('year')) {\n    warnings.push({\n      code: 'OFFSET_WITHOUT_FULL_DATE',\n      message: 'Offset token used without a full date — parse() needs a complete date and time to build a ZonedDateTime and throws at runtime otherwise.',\n    });\n  }\n\n  return {\n    tokens,\n    requiredFields: [...requiredFields].sort(),\n    compatibleTypes: [...compatibleTypesSet].sort(),\n    parseable,\n    localeSensitive,\n    calendarSensitive,\n    timezoneSensitive,\n    // Ambiguous iff at least one warning fired about an ambiguous run.\n    ambiguous: warnings.some((w) => w.code === 'AMBIGUOUS_NUMERIC_RUN'),\n    roundTripSafe: roundTripSafe && parseable,\n    warnings,\n  };\n}\n\n// explainFormat: human-readable rendering of analyzeFormat's output.\n// Used by the CLI (section AD) for `temporal-fmt inspect <fmt>` and by\n// the IDE for hover docs on a format string. Plain prose, no JSON —\n// callers wanting machine-readable output should call analyzeFormat()\n// directly.\nexport function explainFormat(formatStr: string): string {\n  const analysis = analyzeFormat(formatStr);\n  const lines: string[] = [];\n  lines.push(`Format string: \"${formatStr}\"`);\n  lines.push(`Tokens (${analysis.tokens.length}):`);\n  for (const t of analysis.tokens) {\n    lines.push(`  ${t.name} @${t.position} — ${t.metadata.meaning}`);\n  }\n  if (analysis.requiredFields.length > 0) {\n    lines.push(`Required fields: ${analysis.requiredFields.join(', ')}`);\n  }\n  if (analysis.compatibleTypes.length > 0) {\n    lines.push(`Compatible Temporal types: ${analysis.compatibleTypes.join(', ')}`);\n  }\n  lines.push(`Parseable: ${analysis.parseable ? 'yes' : 'no'}`);\n  lines.push(`Locale-sensitive: ${analysis.localeSensitive ? 'yes' : 'no'}`);\n  lines.push(`Calendar-sensitive: ${analysis.calendarSensitive ? 'yes' : 'no'}`);\n  lines.push(`Timezone-sensitive: ${analysis.timezoneSensitive ? 'yes' : 'no'}`);\n  lines.push(`Ambiguous: ${analysis.ambiguous ? 'yes' : 'no'}`);\n  lines.push(`Round-trip safe: ${analysis.roundTripSafe ? 'yes' : 'no'}`);\n  if (analysis.warnings.length > 0) {\n    lines.push('Warnings:');\n    for (const w of analysis.warnings) {\n      lines.push(`  [${w.code}] ${w.message}`);\n    }\n  }\n  return lines.join('\\n');\n}\n\n// isValidFormat: true iff tokenize() accepts the string without\n// throwing. Distinct from analyzeFormat's `parseable` flag — a format\n// string can be valid (tokenizes cleanly) but not parseable (contains\n// a format-only token like `do`). Both checks are exposed since callers\n// want different things: validity for \"will format() throw\", parseability\n// for \"will parse() throw\".\nexport function isValidFormat(formatStr: string): boolean {\n  if (formatStr.length > MAX_FORMAT_LENGTH) return false;\n  try {\n    tokenize(formatStr);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// validateFormat: throws on invalid format strings instead of\n// returning a boolean. Mirrors the existing strict-validation\n// convention (descriptive thrown errors, never silent failures).\n// Returns the analysis for callers who want both — validate-then-use.\nexport function validateFormat(formatStr: string): FormatAnalysis {\n  const analysis = analyzeFormat(formatStr);\n  return analysis;\n}\n\n// Exported for callers that want to query the token table without\n// touching internals. Kept here rather than re-exported from\n// tokenMetadata.ts so this module is the single import for \"anything\n// analyzer-related.\"\nexport { TOKEN_METADATA, ALL_TOKEN_NAMES } from './tokenMetadata.js';\n\n// Re-export FORMAT_ONLY_TOKENS so callers don't have to import from\n// pattern.ts (which is a lower-level module they shouldn't need to\n// know about).\nexport { FORMAT_ONLY_TOKENS } from './pattern.js';\n\n// Used by callers that need to look up which field a token requires —\n// e.g. the ESLint plugin's \"type mismatch\" check (section Y) wants to\n// answer \"does the type the caller passed to format() carry this\n// field?\" without having to actually call format() and catch the\n// thrown error. Mirrors the same lookup format.ts does internally.\nexport function fieldForToken(token: string): keyof TemporalLike | undefined {\n  return _handlerFor(token)?.field;\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Calendar utility helpers. These are pure functions\n// over the TemporalLike shape — no Temporal namespace needed, same\n// approach as isoWeek.ts and the field-reading helpers in format.ts.\n// Letting callers compute dayOfYear/weekOfYear/etc. without going\n// through format() means they can build their own derived values\n// without committing to a string format.\n//\n// Calendar-sensitivity: the helpers in this module assume the\n// iso8601 (Gregorian) calendar — that's what TemporalLike fields\n// carry for the overwhelming majority of callers. Non-Gregorian\n// calendars (hebrew, islamic, etc.) need their own helpers; this\n// module doesn't try to be calendar-polymorphic the way Temporal\n// itself is. Documented limitation, not a design choice — see\n// VERIFICATION.md for the rationale.\n\nimport { isGregorianLeapYear, dayOfYear, isoWeekYearAndWeek, dayOfWeekFromCivil } from './isoWeek.js';\n\n// A subset of TemporalLike that has the date fields these helpers need,\n// plus optional time fields. PlainTime isn't a DateFieldView (no\n// year/month/day), but PlainDateTime / ZonedDateTime / PlainDate all\n// match. Time fields are optional so callers can pass a PlainDate\n// to startOf(value, 'month') without having to populate hour/minute/etc.\n// Exported so the comparison/arithmetic modules can use the same\n// narrowing.\nexport interface DateFieldView {\n  year?: number;\n  month?: number;\n  day?: number;\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n  dayOfWeek?: number;\n  calendarId?: string;\n}\n\nfunction requireFields(view: DateFieldView, fields: Array<keyof DateFieldView>): void {\n  for (const f of fields) {\n    if (typeof view[f] !== 'number') {\n      throw new Error(\n        `temporal-fmt: calendar helper requires \"${String(f)}\", which this value doesn't have. ` +\n        `Pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n      );\n    }\n  }\n}\n\nexport function daysInMonth(view: DateFieldView): number {\n  requireFields(view, ['year', 'month']);\n  const { year, month } = view;\n  // Standard Gregorian month lengths. February's length depends on\n  // whether `year` is a leap year — the same isGregorianLeapYear check\n  // isoWeek.ts uses for dayOfYear arithmetic.\n  const LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n  if (month === 2 && isGregorianLeapYear(year!)) return 29;\n  return LENGTHS[(month! - 1)!]!;\n}\n\nexport function daysInYear(view: DateFieldView): 365 | 366 {\n  requireFields(view, ['year']);\n  return isGregorianLeapYear(view.year!) ? 366 : 365;\n}\n\nexport function monthsInYear(_view: DateFieldView): 12 {\n  // Gregorian always has 12 months. Other calendars (Hebrew leap years\n  // have 13) need calendar-aware logic this module doesn't carry — see\n  // the file-level comment. The `_view` parameter is kept so the\n  // signature mirrors the other helpers and a future calendar-aware\n  // implementation can use it without changing call sites.\n  return 12;\n}\n\nexport function isLeapYear(view: DateFieldView): boolean {\n  requireFields(view, ['year']);\n  return isGregorianLeapYear(view.year!);\n}\n\n// `isLeapMonth` would require knowing which month of a leap-year-aware\n// calendar is the leap month — Gregorian doesn't have one, so this\n// returns false unconditionally. Kept here so the public surface\n// matches the module's listing; non-Gregorian calendars need\n// a different implementation.\nexport function isLeapMonth(_view: DateFieldView): boolean {\n  return false;\n}\n\nexport function dayOfYearHelper(view: DateFieldView): number {\n  requireFields(view, ['year', 'month', 'day']);\n  return dayOfYear(view.year!, view.month!, view.day!);\n}\n\n// ISO 8601 week and week-year. Delegates to isoWeek.ts's\n// isoWeekYearAndWeek, which does the full Thursday-of-week\n// computation to handle the year-boundary cases (Dec 29-31 belonging\n// to week 1 of next year, Jan 1-3 belonging to week 52/53 of the\n// previous year).\nexport function weekOfYear(view: DateFieldView): number {\n  requireFields(view, ['year', 'month', 'day', 'dayOfWeek']);\n  return isoWeekYearAndWeek(view.year!, view.month!, view.day!, view.dayOfWeek!).week;\n}\n\nexport function weekYear(view: DateFieldView): number {\n  requireFields(view, ['year', 'month', 'day', 'dayOfWeek']);\n  return isoWeekYearAndWeek(view.year!, view.month!, view.day!, view.dayOfWeek!).isoYear;\n}\n\n/**\n * Fiscal-quarter options. `startMonth` is the calendar month (1-12) the\n * fiscal year begins on — e.g. `7` for a fiscal year starting in July.\n * Omitted or `1` gives the calendar-quarter behavior getQuarter() has\n * always had (Jan-Mar = Q1, etc.), so existing callers passing nothing\n * see no change.\n */\nexport interface QuarterOptions {\n  startMonth?: number;\n}\n\nfunction validateStartMonth(startMonth: number): void {\n  if (!Number.isInteger(startMonth) || startMonth < 1 || startMonth > 12) {\n    throw new Error(\n      `temporal-fmt: getQuarter's startMonth must be an integer from 1 to 12 (got ${startMonth}).`\n    );\n  }\n}\n\nexport function getQuarter(view: DateFieldView, options: QuarterOptions = {}): number {\n  requireFields(view, ['month']);\n  const startMonth = options.startMonth ?? 1;\n  validateStartMonth(startMonth);\n  if (startMonth === 1) {\n    // Mirrors the Q token: months 1-3 → Q1, 4-6 → Q2, 7-9 → Q3, 10-12 → Q4.\n    return Math.ceil(view.month! / 3);\n  }\n  // Fiscal case: shift the month so startMonth becomes month 1 of the\n  // fiscal year (mod 12, 1-indexed), then apply the same ceil(/3) rule.\n  // E.g. startMonth=7 (fiscal year starts July): July→1, Aug→2, ...,\n  // Dec→6, Jan→7, ..., June→12. Then Q1 = fiscal months 1-3 (Jul-Sep),\n  // matching the common \"FY starts in July\" convention where Q1 is the\n  // first quarter of the fiscal year, not a quarter numbered by which\n  // calendar quarter it falls in.\n  const shifted = ((view.month! - startMonth + 12) % 12) + 1;\n  return Math.ceil(shifted / 3);\n}\n\n// `getMonth` / `getWeekday` look trivial (just read the field) but\n// they're kept as real functions for API surface consistency with the\n// rest of this module. They also normalize: getWeekday returns 1-7\n// (Mon-Sun, matching Temporal's spec) regardless of what numbering the\n// caller's underlying value uses.\nexport function getMonth(view: DateFieldView): number {\n  requireFields(view, ['month']);\n  return view.month!;\n}\n\nexport function getWeekday(view: DateFieldView): number {\n  requireFields(view, ['dayOfWeek']);\n  return view.dayOfWeek!;\n}\n\n// startOf / endOf return new field bags (not Temporal objects — this\n// module is polyfill-free) with the relevant fields zeroed/extended.\n// Callers can pass the result to a Temporal constructor if they want\n// a typed value.\nexport type StartOfUnit = 'day' | 'month' | 'year' | 'hour' | 'minute' | 'second';\n\n// Returns true if the given unit (when used with startOf/endOf) should\n// also touch the time fields. 'day', 'month', 'year' all imply a\n// resolution coarser than an hour, so startOf zeroes the time fields\n// and endOf maxes them. Sub-hour units (hour/minute/second) only touch\n// the fields finer than themselves.\nfunction touchesTime(unit: StartOfUnit): boolean {\n  return unit === 'day' || unit === 'month' || unit === 'year';\n}\n\n// startOf/endOf reassign year/month/day, which invalidates any\n// dayOfWeek carried over from the input — a plain { ...view } spread\n// leaves the old value sitting there unchanged. Same failure mode\n// businessCalendar.ts's isBusinessDay() works around for add(); we\n// recompute here rather than trust the copied field.\nfunction recomputeDayOfWeek(view: DateFieldView): void {\n  if (typeof view.dayOfWeek !== 'number') return;\n  /* c8 ignore start @preserve -- unreachable: startOf()/endOf() both call\n   * asDateFieldView() before this, which already throws if year/month/day\n   * aren't all numbers — so by the time a value with a numeric dayOfWeek\n   * reaches here, year/month/day are guaranteed present too. */\n  if (typeof view.year !== 'number' || typeof view.month !== 'number' || typeof view.day !== 'number') return;\n  /* c8 ignore stop @preserve */\n  // dayOfWeekFromCivil: O(1) proleptic-Gregorian weekday. The old\n  // Date.UTC(year, month-1, day) form remapped years 0-99 to 1900-1999\n  // (ECMAScript spec), so startOf/endOf of a first-century date carried\n  // a weekday from the wrong century.\n  view.dayOfWeek = dayOfWeekFromCivil(view.year, view.month, view.day);\n}\n\nexport function startOf(value: unknown, unit: StartOfUnit): DateFieldView {\n  const view = asDateFieldView(value);\n  const result: DateFieldView = { ...view };\n  if (unit === 'year') {\n    result.month = 1;\n    result.day = 1;\n  } else if (unit === 'month') {\n    result.day = 1;\n  }\n  recomputeDayOfWeek(result);\n  if (touchesTime(unit)) {\n    result.hour = 0;\n    result.minute = 0;\n    result.second = 0;\n    result.millisecond = 0;\n  } else if (unit === 'hour') {\n    result.minute = 0;\n    result.second = 0;\n    result.millisecond = 0;\n  } else if (unit === 'minute') {\n    result.second = 0;\n    result.millisecond = 0;\n  } else if (unit === 'second') {\n    result.millisecond = 0;\n  }\n  return result;\n}\n\nexport function endOf(value: unknown, unit: StartOfUnit): DateFieldView {\n  const view = asDateFieldView(value);\n  const result: DateFieldView = { ...view };\n  if (unit === 'year') {\n    result.month = 12;\n    result.day = daysInMonth({ year: result.year!, month: 12 });\n  } else if (unit === 'month') {\n    result.day = daysInMonth({ year: result.year!, month: result.month! });\n  }\n  recomputeDayOfWeek(result);\n  if (touchesTime(unit)) {\n    result.hour = 23;\n    result.minute = 59;\n    result.second = 59;\n    result.millisecond = 999;\n  } else if (unit === 'hour') {\n    result.minute = 59;\n    result.second = 59;\n    result.millisecond = 999;\n  } else if (unit === 'minute') {\n    result.second = 59;\n    result.millisecond = 999;\n  } else if (unit === 'second') {\n    result.millisecond = 999;\n  }\n  return result;\n}\n\n// Type-narrowing helpers used by the comparison/arithmetic modules.\n// Lets them accept any of the four date-carrying Temporal types without\n// importing Temporal itself.\nexport function asDateFieldView(value: unknown): DateFieldView {\n  if (typeof value !== 'object' || value === null) {\n    throw new Error(`temporal-fmt: expected a date-carrying Temporal value, got ${String(value)}.`);\n  }\n  // Temporal instances expose year/month/day/etc. as prototype getters,\n  // not own enumerable properties — so `{ ...value }` would lose them.\n  // Read them explicitly. Only the fields actually present on this\n  // value type end up in the returned view.\n  const v = value as Record<string, unknown>;\n  const out: DateFieldView = {};\n  if (typeof v.year === 'number') out.year = v.year;\n  if (typeof v.month === 'number') out.month = v.month;\n  if (typeof v.day === 'number') out.day = v.day;\n  if (typeof v.hour === 'number') out.hour = v.hour;\n  if (typeof v.minute === 'number') out.minute = v.minute;\n  if (typeof v.second === 'number') out.second = v.second;\n  if (typeof v.millisecond === 'number') out.millisecond = v.millisecond;\n  if (typeof v.dayOfWeek === 'number') out.dayOfWeek = v.dayOfWeek;\n  if (typeof v.calendarId === 'string') out.calendarId = v.calendarId;\n  if (out.year === undefined || out.month === undefined || out.day === undefined) {\n    throw new Error(\n      `temporal-fmt: value is missing year/month/day fields — pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n    );\n  }\n  return out;\n}\n\n// Re-export the TemporalType alias so callers can import everything\n// from one place.\nexport type { TemporalType } from './tokenMetadata.js';\n// Re-export TemporalLike for the same reason.\nexport type { TemporalLike } from './tokens.js';","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Comparison helpers. Pure functions over the field\n// shape, no Temporal namespace needed — same convention as\n// calendarUtils.ts. All comparisons are field-based, not identity-based,\n// so a polyfill PlainDate compares equal to a native PlainDate with the\n// same year/month/day.\n\nimport { asDateFieldView, type DateFieldView } from './calendarUtils.js';\nimport { dayOfWeekFromCivil, daysFromCivil } from './isoWeek.js';\n\ninterface DateTimeFieldView extends DateFieldView {\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n}\n\nfunction toComparableMs(view: DateTimeFieldView): number {\n  // Exact proleptic-Gregorian day count (Howard Hinnant's days_from_civil,\n  // same algorithm arithmetic.ts/interval.ts use) plus the time-of-day —\n  // NOT an approximation. The previous implementation multiplied the\n  // year offset by an average 365.2425 days/year, on the theory that the\n  // error \"is constant for any given year, so it cancels out in a diff\".\n  // That's only true when both dates fall in the same year: the year\n  // term's error differs by up to ~0.76 days between adjacent years\n  // (365.2425 vs 365/366 actual), which corrupts cross-year comparisons\n  // near the boundary — e.g. isAfter(2025-01-01T00:00, 2024-12-31T18:12)\n  // returned false (truth: ~5.8h after), and isEqual() returned true for\n  // instants ~18h apart (2025-01-01T00:00 vs 2024-12-31T05:49:12).\n  // Exact arithmetic has no such error term. The day count itself comes\n  // from isoWeek.ts's daysFromCivil (Howard Hinnant's days_from_civil:\n  // O(1), correct for negative years — the inlined era formula this\n  // replaced double-corrected pre-year-0 dates by a day via Math.floor\n  // of the -399-offset numerator).\n  const days = daysFromCivil(view.year!, view.month!, view.day!);\n\n  const MS_PER_HOUR = 3_600_000;\n  const MS_PER_MINUTE = 60_000;\n  const MS_PER_SECOND = 1_000;\n\n  return days * 86_400_000\n    + (view.hour ?? 0) * MS_PER_HOUR\n    + (view.minute ?? 0) * MS_PER_MINUTE\n    + (view.second ?? 0) * MS_PER_SECOND\n    + (view.millisecond ?? 0);\n}\n\nfunction asDateTimeFieldView(value: unknown): DateTimeFieldView {\n  const v = asDateFieldView(value);\n  return v as DateTimeFieldView;\n}\n\n// Returns < 0 if a < b, 0 if a === b, > 0 if a > b. Same convention as\n// Array.prototype.sort and Temporal.PlainDate.compare. Lets callers\n// pass this directly as a comparator.\nexport function compare(a: unknown, b: unknown): number {\n  const av = asDateTimeFieldView(a);\n  const bv = asDateTimeFieldView(b);\n  const am = toComparableMs(av);\n  const bm = toComparableMs(bv);\n  if (am < bm) return -1;\n  if (am > bm) return 1;\n  return 0;\n}\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n  return compare(a, b) === 0;\n}\n\nexport function isBefore(a: unknown, b: unknown): boolean {\n  return compare(a, b) < 0;\n}\n\nexport function isAfter(a: unknown, b: unknown): boolean {\n  return compare(a, b) > 0;\n}\n\nexport function min(values: unknown[]): unknown {\n  if (!Array.isArray(values) || values.length === 0) {\n    throw new Error('temporal-fmt: min() requires a non-empty array of values.');\n  }\n  let best = values[0];\n  for (let i = 1; i < values.length; i++) {\n    if (compare(values[i], best) < 0) best = values[i];\n  }\n  return best;\n}\n\nexport function max(values: unknown[]): unknown {\n  if (!Array.isArray(values) || values.length === 0) {\n    throw new Error('temporal-fmt: max() requires a non-empty array of values.');\n  }\n  let best = values[0];\n  for (let i = 1; i < values.length; i++) {\n    if (compare(values[i], best) > 0) best = values[i];\n  }\n  return best;\n}\n\nexport function clamp(value: unknown, lo: unknown, hi: unknown): unknown {\n  if (compare(value, lo) < 0) return lo;\n  if (compare(value, hi) > 0) return hi;\n  return value;\n}\n\nexport function isBetween(value: unknown, lo: unknown, hi: unknown): boolean {\n  return compare(value, lo) >= 0 && compare(value, hi) <= 0;\n}\n\n// Semantic helpers — same-day/week/month/quarter/year tests. Useful for\n// UI (\"is this event today?\") and for grouping/aggregation. All take a\n// reference value to compare against; the \"isToday\" / \"isTomorrow\" /\n// \"isYesterday\" variants compute the reference from the current system\n// date themselves so callers don't have to.\nfunction readYearMonthDay(value: unknown): { year: number; month: number; day: number } {\n  const v = asDateFieldView(value);\n  return { year: v.year!, month: v.month!, day: v.day! };\n}\n\nfunction todayYearMonthDay(): { year: number; month: number; day: number } {\n  const now = new Date();\n  return { year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate() };\n}\n\nfunction dateEqualYearMonthDay(a: { year: number; month: number; day: number }, b: { year: number; month: number; day: number }): boolean {\n  return a.year === b.year && a.month === b.month && a.day === b.day;\n}\n\nexport function isSameDay(value: unknown, reference: unknown): boolean {\n  return dateEqualYearMonthDay(readYearMonthDay(value), readYearMonthDay(reference));\n}\n\nexport function isToday(value: unknown): boolean {\n  return dateEqualYearMonthDay(readYearMonthDay(value), todayYearMonthDay());\n}\n\nfunction tomorrowYearMonthDay(): { year: number; month: number; day: number } {\n  const d = new Date();\n  d.setDate(d.getDate() + 1);\n  return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nfunction yesterdayYearMonthDay(): { year: number; month: number; day: number } {\n  const d = new Date();\n  d.setDate(d.getDate() - 1);\n  return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nexport function isTomorrow(value: unknown): boolean {\n  return dateEqualYearMonthDay(readYearMonthDay(value), tomorrowYearMonthDay());\n}\n\nexport function isYesterday(value: unknown): boolean {\n  return dateEqualYearMonthDay(readYearMonthDay(value), yesterdayYearMonthDay());\n}\n\nfunction sameWeek(yearA: number, monthA: number, dayA: number, yearB: number, monthB: number, dayB: number): boolean {\n  // Same week iff the dates are within 7 days of each other AND the earlier\n  // one's weekday is ≤ the later one's weekday (so we don't say \"Sun and\n  // the following Mon are in the same week\" — ISO weeks run Mon-Sun).\n  // Easier: compute ISO week numbers via isoWeekYearAndWeek, compare both\n  // year and week. That handles the year-boundary case (Dec 31 vs Jan 1 of\n  // the next year, which can be in the same ISO week).\n  // Local import to avoid module-cycle: isoWeek.ts doesn't import from here.\n  // Lazy require-style dynamic via inline static import at top would be\n  // cleaner; this inline computation is fine for a pure helper.\n  // ...actually let's just compute weekday offsets directly. Same-ISO-week\n  // iff |d1 - d2| < 7 days AND the earlier date's ISO weekday ≤ the later\n  // date's ISO weekday so they fall in the same Mon-Sun span.\n  const daysSince = (y: number, m: number, d: number): number => {\n    // daysFromCivil: O(1), correct for negative years. (The inlined\n    // formula this replaced was the one remaining copy of the\n    // Math.floor-of-offset era bug — see daysFromCivil's comment.)\n    return daysFromCivil(y, m, d);\n  };\n  const a = daysSince(yearA, monthA, dayA);\n  const b = daysSince(yearB, monthB, dayB);\n  if (Math.abs(a - b) >= 7) return false;\n  // Same week iff both dates round to the same Monday. Compute the\n  // Monday-of-week for each: subtract (weekday - 1) days, where weekday\n  // is 1=Mon..7=Sun. Use the standard Zeller formula for weekday.\n  const weekdayOf = (y: number, m: number, d: number): number => {\n    // O(1) proleptic-Gregorian weekday from isoWeek.ts's dayOfWeekFromCivil.\n    // The old Date.UTC(y, m-1, d) form remapped years 0-99 to 1900-1999\n    // (ECMAScript spec), computing the weekday of the wrong century for\n    // first-century dates.\n    return dayOfWeekFromCivil(y, m, d);\n  };\n  const wa = a - (weekdayOf(yearA, monthA, dayA) - 1);\n  const wb = b - (weekdayOf(yearB, monthB, dayB) - 1);\n  return wa === wb;\n}\n\nexport function isSameWeek(value: unknown, reference: unknown): boolean {\n  const a = readYearMonthDay(value);\n  const b = readYearMonthDay(reference);\n  return sameWeek(a.year, a.month, a.day, b.year, b.month, b.day);\n}\n\nexport function isSameMonth(value: unknown, reference: unknown): boolean {\n  const a = readYearMonthDay(value);\n  const b = readYearMonthDay(reference);\n  return a.year === b.year && a.month === b.month;\n}\n\nexport function isSameQuarter(value: unknown, reference: unknown): boolean {\n  const a = readYearMonthDay(value);\n  const b = readYearMonthDay(reference);\n  return a.year === b.year && Math.ceil(a.month / 3) === Math.ceil(b.month / 3);\n}\n\nexport function isSameYear(value: unknown, reference: unknown): boolean {\n  return readYearMonthDay(value).year === readYearMonthDay(reference).year;\n}\n\n// isWeekend / isWeekday depend on dayOfWeek — present on PlainDate,\n// PlainDateTime, ZonedDateTime, but NOT on PlainTime. Callers passing\n// PlainTime get a descriptive throw. Doesn't call asDateFieldView\n// because that would reject PlainTime (no year/month/day) before\n// reaching the dayOfWeek check — and the error we want here is the\n// \"no dayOfWeek field\" one, not the \"no date fields\" one.\nexport function isWeekend(value: unknown): boolean {\n  if (typeof value !== 'object' || value === null) {\n    throw new Error(`temporal-fmt: isWeekend() expected a Temporal value, got ${String(value)}.`);\n  }\n  const v = value as { dayOfWeek?: unknown };\n  if (typeof v.dayOfWeek !== 'number') {\n    throw new Error(\n      `temporal-fmt: isWeekend() needs a value with a dayOfWeek field (PlainDate / PlainDateTime / ZonedDateTime).`\n    );\n  }\n  // 6=Sat, 7=Sun in Temporal's Mon=1..Sun=7 numbering.\n  return v.dayOfWeek === 6 || v.dayOfWeek === 7;\n}\n\nexport function isWeekday(value: unknown): boolean {\n  return !isWeekend(value);\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Rounding helpers. Pure functions over field bags,\n// same convention as arithmetic.ts/calendarUtils.ts.\n\nimport { asDateFieldView, type DateFieldView } from './calendarUtils.js';\nimport { InvalidDurationError } from './errors.js';\nimport { daysFromCivil } from './isoWeek.js';\n\ntype RoundingUnit = 'day' | 'hour' | 'minute' | 'second' | 'millisecond';\ntype RoundingMode = 'nearest' | 'floor' | 'ceil' | 'trunc';\n\ninterface DateTimeFieldView extends DateFieldView {\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n}\n\n// Ms-per-unit table. Used by round() to convert a field bag to ms,\n// apply the rounding mode, and convert back. Mirrors how add() in\n// arithmetic.ts handles sub-day arithmetic.\nconst MS_PER_UNIT: Record<RoundingUnit, number> = {\n  day: 86_400_000,\n  hour: 3_600_000,\n  minute: 60_000,\n  second: 1_000,\n  millisecond: 1,\n};\n\nfunction applyMode(ms: number, mode: RoundingMode, increment: number): number {\n  // Operates on the SIGNED value. The absolute-value-then-reapply-sign\n  // version this replaced inverted floor/ceil for every negative input\n  // (Unix-epoch ms < 0 = any date before 1970-01-01): floor(-0.5 days)\n  // came out as 0 (= 1970-01-01) instead of -1 (= 1969-12-31), i.e.\n  // floor and ceil were literally swapped for pre-epoch dates, and\n  // 'nearest' broke ties away-from-epoch (10:30 pre-epoch → 10:00 while\n  // the identical post-epoch clock time → 11:00). Signed Math.* calls\n  // are epoch-consistent by construction: floor always moves toward\n  // −∞ (the earlier boundary), ceil toward +∞, trunc toward zero,\n  // nearest ties up (Math.round semantics, both sides of the epoch).\n  const stepped = ms / increment;\n  let rounded: number;\n  switch (mode) {\n    case 'nearest': rounded = Math.round(stepped); break;\n    case 'floor': rounded = Math.floor(stepped); break;\n    case 'ceil': rounded = Math.ceil(stepped); break;\n    case 'trunc': rounded = Math.trunc(stepped); break;\n  }\n  return rounded * increment;\n}\n\nfunction toMs(v: DateTimeFieldView): number {\n  // Returns ms-since-(Howard Hinnant epoch). Used internally — the\n  // absolute value is meaningful only relative to the same epoch used\n  // by fromMs. daysFromCivil is O(1) and correct for negative years;\n  // the forward era previously inlined here (Math.floor of the -399-\n  // offset numerator) shifted pre-year-0 dates by one day.\n  const days = daysFromCivil(v.year!, v.month!, v.day!);\n  return days * MS_PER_UNIT.day\n    + (v.hour ?? 0) * MS_PER_UNIT.hour\n    + (v.minute ?? 0) * MS_PER_UNIT.minute\n    + (v.second ?? 0) * MS_PER_UNIT.second\n    + (v.millisecond ?? 0);\n}\n\nfunction fromMs(ms: number, base: DateTimeFieldView): DateTimeFieldView {\n  // Convert absolute ms (on the same epoch as toMs) back to a field bag.\n  // Walks the Howard Hinnant days_from_civil inverse inline.\n  const MS_PER_DAY = MS_PER_UNIT.day;\n  const totalDays = Math.floor(ms / MS_PER_DAY);\n  let withinDay = ms - totalDays * MS_PER_DAY; // ms since midnight\n  // Defensive floating-point guard: given totalDays = Math.floor(ms /\n  // MS_PER_DAY), withinDay = ms - totalDays * MS_PER_DAY is\n  // mathematically guaranteed non-negative (that's what Math.floor\n  // division gives you), verified against extreme values including\n  // Number.MIN_SAFE_INTEGER and sub-ms fractional noise near day\n  // boundaries. Kept in case a future change to how ms is computed\n  // upstream breaks that guarantee.\n  /* c8 ignore next */\n  if (withinDay < 0) withinDay += MS_PER_DAY;\n  const hour = Math.floor(withinDay / MS_PER_UNIT.hour);\n  const minute = Math.floor((withinDay % MS_PER_UNIT.hour) / MS_PER_UNIT.minute);\n  const second = Math.floor((withinDay % MS_PER_UNIT.minute) / MS_PER_UNIT.second);\n  const millisecond = withinDay % MS_PER_UNIT.second;\n  // Convert totalDays back to year/month/day via Howard Hinnant's\n  // civil_from_days. The era term MUST use truncating division — the\n  // -146096 offset exists precisely so trunc lands the era correctly;\n  // Math.floor double-shifts every z < 0 by one day. (Same fix as\n  // arithmetic.ts's shiftDays.)\n  const z = totalDays + 719468;\n  const era = Math.trunc((z >= 0 ? z : z - 146096) / 146097);\n  const doe = z - era * 146097;\n  const yoe = Math.floor((doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365);\n  const y2 = 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  const year = m <= 2 ? y2 + 1 : y2;\n  return { ...base, year, month: m, day: d, hour, minute, second, millisecond };\n}\n\nfunction shiftDays(v: DateTimeFieldView, days: number): DateTimeFieldView {\n  // daysFromCivil (isoWeek.ts): O(1) and correct for negative years —\n  // the forward era previously inlined here (Math.floor of Hinnant's\n  // -399-offset numerator) double-corrected, and the inverse era's\n  // Math.floor (see fromMs) canceled it only for round-trips, leaving\n  // one-way consumers off by a day for pre-year-0 dates.\n  const totalDays = daysFromCivil(v.year!, v.month!, v.day!) + days;\n  const z = totalDays + 719468;\n  const era2 = Math.trunc((z >= 0 ? z : z - 146096) / 146097);\n  const doe2 = z - era2 * 146097;\n  const yoe2 = Math.floor((doe2 - Math.floor(doe2 / 1460) + Math.floor(doe2 / 36524) - Math.floor(doe2 / 146096)) / 365);\n  const y2out = yoe2 + era2 * 400;\n  const doy2 = doe2 - (365 * yoe2 + Math.floor(yoe2 / 4) - Math.floor(yoe2 / 100));\n  const mp = Math.floor((5 * doy2 + 2) / 153);\n  const d2 = doy2 - Math.floor((153 * mp + 2) / 5) + 1;\n  const m2out = mp < 10 ? mp + 3 : mp - 9;\n  const yOut = m2out <= 2 ? y2out + 1 : y2out;\n  return { ...v, year: yOut, month: m2out, day: d2 };\n}\n\nexport interface RoundOptions {\n  unit: RoundingUnit;\n  mode?: RoundingMode;\n  roundingIncrement?: number;\n}\n\nexport function round(value: unknown, options: RoundOptions): DateTimeFieldView {\n  const base = asDateFieldView(value) as DateTimeFieldView;\n  const mode = options.mode ?? 'nearest';\n  const increment = (options.roundingIncrement ?? 1) * MS_PER_UNIT[options.unit];\n  if (increment <= 0) {\n    throw new Error(`temporal-fmt: round() requires a positive roundingIncrement (got ${options.roundingIncrement}).`);\n  }\n  const ms = toMs(base);\n  const rounded = applyMode(ms, mode, increment);\n  return fromMs(rounded, base);\n}\n\nexport function floor(value: unknown, unit: RoundingUnit, roundingIncrement: number = 1): DateTimeFieldView {\n  return round(value, { unit, mode: 'floor', roundingIncrement });\n}\n\nexport function ceil(value: unknown, unit: RoundingUnit, roundingIncrement: number = 1): DateTimeFieldView {\n  return round(value, { unit, mode: 'ceil', roundingIncrement });\n}\n\nexport function truncate(value: unknown, unit: RoundingUnit, roundingIncrement: number = 1): DateTimeFieldView {\n  return round(value, { unit, mode: 'trunc', roundingIncrement });\n}\n\n// Duration rounding. Takes a duration field bag and rounds it to the\n// requested unit. Operates on the duration's own fields (years/months\n// for calendar-bound units, days/hours/minutes/seconds/ms/µs/ns for\n// absolute units). Mirrors Temporal.Duration.prototype.round's surface\n// — but operates on plain field bags rather than real Temporal.Duration\n// instances, same convention as the rest of this module set.\nexport interface DurationFields {\n  years?: number;\n  months?: number;\n  weeks?: number;\n  days?: number;\n  hours?: number;\n  minutes?: number;\n  seconds?: number;\n  milliseconds?: number;\n  microseconds?: number;\n  nanoseconds?: number;\n}\n\n// Converts one absolute-unit field to nanoseconds, exactly. Integer\n// values keep the exact BigInt path (arbitrary magnitude). Fractional\n// values — which parseISODuration legitimately produces (\"P1.5D\") —\n// scale in floating point and are accepted only when the product is a\n// safe integer, so P1.5D balances to exactly 1 day + 12 hours. A\n// fractional value whose product can't be represented exactly (large\n// fractional day counts) throws the typed InvalidDurationError instead\n// of the opaque \"TypeError: Cannot convert 1.5 to a BigInt\" the old\n// BigInt(v) call produced. Shared by roundDuration (here) and the\n// duration.ts arithmetic helpers — duration.ts already imports from\n// this module, so exporting keeps the dependency direction acyclic.\nexport function fieldToNs(v: number, nsPer: bigint, field: string): bigint {\n  if (Number.isInteger(v)) return BigInt(v) * nsPer;\n  const scaled = v * Number(nsPer);\n  if (Number.isSafeInteger(scaled)) return BigInt(scaled);\n  throw new InvalidDurationError({\n    reason: `field \"${field}\" (${v}) cannot be converted to nanoseconds exactly — the value is too large for a fractional unit; use smaller units`,\n  });\n}\n\ntype DurationUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds' | 'microseconds' | 'nanoseconds';\n\nconst DURATION_UNIT_TO_NS: Record<DurationUnit, bigint> = {\n  years: 0n, // calendar-bound, can't convert without relativeTo\n  months: 0n, // same\n  weeks: 0n, // same\n  days: 86_400n * 1_000_000_000n,\n  hours: 3_600n * 1_000_000_000n,\n  minutes: 60n * 1_000_000_000n,\n  seconds: 1_000_000_000n,\n  milliseconds: 1_000_000n,\n  microseconds: 1_000n,\n  nanoseconds: 1n,\n};\n\n// Absolute units (days and below) can be rounded without a relativeTo\n// because their length is fixed in nanoseconds. Calendar-bound units\n// (years/months/weeks) can't — would need a Temporal.Duration round()\n// call with a relativeTo. This helper throws if the caller tries to\n// round to/from a calendar-bound unit, rather than silently producing\n// a wrong result.\nfunction isCalendarBound(unit: DurationUnit): boolean {\n  return unit === 'years' || unit === 'months' || unit === 'weeks';\n}\n\nexport function roundDuration(duration: DurationFields, options: {\n  unit: DurationUnit;\n  mode?: RoundingMode;\n  roundingIncrement?: number;\n}): DurationFields {\n  const mode = options.mode ?? 'nearest';\n  // Default first, then validate: roundDuration({hours:1}, {unit:'hours'})\n  // (no increment) must keep meaning \"increment 1\", not trip the guard.\n  // A fractional value (2.5) used to reach BigInt() and throw a raw V8\n  // RangeError (\"The number 2.5 cannot be converted to a BigInt\") —\n  // inconsistent with round(), which accepts fractional increments via\n  // float math, and with the typed-error surface this library promises.\n  const incrementValue = options.roundingIncrement ?? 1;\n  if (typeof incrementValue !== 'number' || !Number.isInteger(incrementValue) || incrementValue < 1) {\n    throw new InvalidDurationError({\n      reason:\n        `temporal-fmt: roundDuration() requires a positive roundingIncrement (got ${String(incrementValue)})` +\n        (Number.isInteger(incrementValue) ? '' : ' — fractional increments aren\\'t supported here (use round() for those)'),\n    });\n  }\n  const increment = BigInt(incrementValue);\n  if (isCalendarBound(options.unit)) {\n    throw new Error(\n      `temporal-fmt: roundDuration() to \"${options.unit}\" requires a Temporal.Duration with a relativeTo — ` +\n      `this helper operates on plain field bags without calendar context. Use Temporal.Duration.prototype.round() directly.`\n    );\n  }\n\n  // Sum all absolute-unit contributions into total nanoseconds.\n  let totalNs = 0n;\n  for (const u of ['days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds', 'nanoseconds'] as DurationUnit[]) {\n    const v = duration[u] ?? 0;\n    totalNs += fieldToNs(v, DURATION_UNIT_TO_NS[u], u);\n  }\n\n  // Apply rounding on the SIGNED total (see applyMode for why the\n  // abs-then-sign form was wrong for negatives: floor/ceil inverted,\n  // ties asymmetric). BigInt division truncates toward zero, so floor\n  // and ceil need explicit adjustment for negative remainders, and\n  // 'nearest' follows Math.round's ties-toward-+∞ exactly (r of exactly\n  // −½ steps stays at the truncation quotient, which is the higher\n  // boundary — matching round() above instead of the old away-from-zero\n  // tie break that disagreed with it for negative values).\n  const stepNs = increment * DURATION_UNIT_TO_NS[options.unit];\n  const sign = totalNs < 0n ? -1n : 1n;\n  const abs = totalNs < 0n ? -totalNs : totalNs;\n  const stepped = abs / stepNs;\n  const remainder = abs % stepNs;\n  let rounded: bigint;\n  switch (mode) {\n    case 'nearest':\n      // Banker's rounding would be the Temporal spec, but Math.round-style\n      // half-up is what callers typically expect from a \"round\" function.\n      // Going with half-up to match round() above and avoid surprising anyone\n      // who reads the output.\n      rounded = remainder * 2n >= stepNs ? stepped + 1n : stepped;\n      break;\n    // floor/ceil are computed from the truncating quotient adjusted by\n    // the SIGN of totalNs: floor moves toward −∞ (one step earlier for a\n    // negative value with a remainder), ceil toward +∞.\n    case 'floor': rounded = sign < 0n && remainder > 0n ? stepped + 1n : stepped; break;\n    case 'ceil': rounded = sign > 0n && remainder > 0n ? stepped + 1n : stepped; break;\n    case 'trunc': rounded = stepped; break;\n  }\n  const newTotalNs = sign * rounded * stepNs;\n\n  // Distribute back into the largest unit ≤ the requested unit. This\n  // produces a balanced duration (e.g. rounding 90s to minutes gives\n  // 1m30s in the minute field, not 90s).\n  const result: DurationFields = { ...duration };\n  let remaining = newTotalNs;\n  // Clear all absolute units, then re-populate from largest to smallest so\n  // the balanced output has all its value concentrated at the target unit\n  // and below.\n  const unitsInOrder: DurationUnit[] = ['days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds', 'nanoseconds'];\n  const startIdx = unitsInOrder.indexOf(options.unit);\n  // Units finer than the rounding target are zeroed: all their value was\n  // folded into `remaining` above, and whatever survives rounding now\n  // lives at the target unit and above. (Units coarser than the target\n  // are re-written by the distribution loop below — their value is\n  // already inside `remaining`, so the spread copy is overwritten with\n  // the same number.)\n  for (let i = startIdx + 1; i < unitsInOrder.length; i++) {\n    result[unitsInOrder[i]!] = 0;\n  }\n  // Re-populate from the largest absolute unit down to the target, so the\n  // result has all its value concentrated at the target unit and above.\n  for (let i = 0; i <= startIdx; i++) {\n    const u = unitsInOrder[i]!;\n    const unitNs = DURATION_UNIT_TO_NS[u];\n    // Dead by construction: unitsInOrder only lists days/hours/minutes/\n    // seconds/milliseconds/microseconds/nanoseconds, none of which are\n    // 0n in DURATION_UNIT_TO_NS (only years/months/weeks are, and those\n    // never appear in this array). Kept in case unitsInOrder grows to\n    // include a calendar-bound unit later.\n    /* c8 ignore next */\n    if (unitNs === 0n) continue;\n    const count = remaining / unitNs;\n    remaining -= count * unitNs;\n    // Assign unconditionally (zero counts write 0): the units at and above\n    // the target are fully re-derived from the rounded total, so any\n    // original spread-copied value must be overwritten either way —\n    // conditionally skipping zero counts would leave the caller's stale\n    // value sitting in the field.\n    result[u] = Number(count);\n  }\n  return result;\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Serialization / interop helpers. Standardized\n// parse/format pairs for ISO 8601, RFC 3339, RFC 2822, HTTP-date,\n// plus epoch conversions to/from unix seconds/ms/µs/ns.\n//\n// All of these wrap the existing parse()/format() surface rather than\n// reimplementing the formats — same convention as the rest of the\n// library (one tokenizer, one parser, one constructor path). The\n// standard-format helpers are essentially pre-baked format strings\n// with the right tokens, plus stricter input validation where the\n// standard demands it (e.g. RFC 3339 requires UTC-offset-only zones,\n// not named IANA zones).\n\nimport { parse } from './parse.js';\nimport { format } from './format.js';\nimport { getFormatImpl, getParseImpl } from './runtime.js';\nimport { getTemporal, type TemporalNamespace } from './temporalProvider.js';\nimport { FormatSyntaxError, InvalidDateError } from './errors.js';\n\n// Build a Temporal instance from a field bag. Used by the parse helpers\n// to construct PlainDate / PlainDateTime / ZonedDateTime / Instant from\n// the fields the standard format carries. Throws on construction errors\n// (Feb 30, etc.) wrapped in InvalidDateError so callers get the typed\n// error surface.\nfunction constructFromFields(fields: Record<string, unknown>, kind: 'PlainDate' | 'PlainDateTime' | 'ZonedDateTime' | 'Instant'): unknown {\n  const temporal = getTemporal();\n  try {\n    switch (kind) {\n      case 'PlainDate':\n        return temporal.PlainDate.from(fields as Record<string, number | string | undefined>, { overflow: 'reject' });\n      case 'PlainDateTime':\n        return temporal.PlainDateTime.from(fields as Record<string, number | string | undefined>, { overflow: 'reject' });\n      case 'ZonedDateTime':\n        return temporal.ZonedDateTime.from(fields as Record<string, number | string | undefined>, { overflow: 'reject' });\n      case 'Instant': {\n        // Instant.from takes an ISO string, not a field bag. Build the\n        // ISO string ourselves and parse it.\n        const iso = buildISOFromFields(fields);\n        if (!temporal.Instant) {\n          throw new Error('temporal-fmt: Temporal.Instant is not available in this implementation.');\n        }\n        return temporal.Instant.from(iso);\n      }\n    }\n  } catch (err) {\n    throw new InvalidDateError({ input: JSON.stringify(fields), reason: (err as Error).message });\n  }\n}\n\nfunction buildISOFromFields(fields: Record<string, unknown>): string {\n  const y = String(fields.year).padStart(4, '0');\n  const m = String(fields.month).padStart(2, '0');\n  const d = String(fields.day).padStart(2, '0');\n  const h = fields.hour !== undefined ? `T${String(fields.hour).padStart(2, '0')}` : '';\n  const min = fields.minute !== undefined ? `:${String(fields.minute).padStart(2, '0')}` : '';\n  const sec = fields.second !== undefined ? `:${String(fields.second).padStart(2, '0')}` : '';\n  const frac = fields.millisecond !== undefined && (fields.millisecond as number) > 0\n    ? `.${String(fields.millisecond).padStart(3, '0')}`\n    : '';\n  const tz = typeof fields.timeZone === 'string' ? fields.timeZone : 'Z';\n  return `${y}-${m}-${d}${h}${min}${sec}${frac}${tz}`;\n}\n\n// ISO 8601 is the most permissive of the standards here — accepts\n// calendar dates, week dates, ordinal dates, times with optional\n// fractional seconds, timezone offsets or 'Z'. Delegates to\n// Temporal's own ISO parsing (which is ISO 8601-compliant) by\n// constructing from the raw ISO string.\n\nexport function parseISO(input: string): unknown {\n  const temporal = getTemporal();\n  // Detect what kind of Temporal object the ISO string describes.\n  // ISO 8601 strings have a date part, optional time part, optional\n  // timezone. We dispatch to the right Temporal constructor based on\n  // which parts are present.\n  try {\n    if (/^\\d{4}-\\d{2}-\\d{2}T/.test(input) || /T\\d{2}:\\d{2}/.test(input)) {\n      // Has a time component.\n      if (/[zZ]$/.test(input) || /[+-]\\d{2}:?\\d{2}$/.test(input)) {\n        // ZonedDateTime. Temporal.ZonedDateTime.from accepts ISO with\n        // a zone bracket (e.g. \"2026-08-04T15:45:30[UTC]\") but rejects\n        // a bare offset with no bracket. For \"Z\" suffix, expand to\n        // \"+00:00[UTC]\"; for a numeric offset, append that same offset\n        // as the bracket (e.g. \"+05:30\" → \"+05:30[+05:30]\").\n        let iso = input;\n        if (/[zZ]$/.test(iso)) {\n          iso = iso.slice(0, -1) + '+00:00[UTC]';\n        } else {\n          const offsetMatch = /([+-]\\d{2}:?\\d{2})$/.exec(iso);\n          if (offsetMatch) {\n            iso = `${iso}[${offsetMatch[1]}]`;\n          }\n        }\n        return temporal.ZonedDateTime.from(iso as unknown as Record<string, number | string | undefined>, { overflow: 'reject' });\n      }\n      return temporal.PlainDateTime.from(input as unknown as Record<string, number | string | undefined>, { overflow: 'reject' });\n    }\n    if (/^\\d{4}-\\d{2}-\\d{2}/.test(input)) {\n      return temporal.PlainDate.from(input as unknown as Record<string, number | string | undefined>, { overflow: 'reject' });\n    }\n    if (/^\\d{2}:\\d{2}/.test(input)) {\n      return temporal.PlainTime.from(input as unknown as Record<string, number | string | undefined>);\n    }\n    throw new Error(`temporal-fmt: parseISO(\"${input}\") doesn't look like an ISO 8601 string.`);\n  } catch (err) {\n    throw new InvalidDateError({ input, reason: (err as Error).message });\n  }\n}\n\nexport function formatISO(value: unknown): string {\n  // Temporal objects expose toString() which produces ISO 8601 output\n  // by spec. So formatting IS just toString().\n  const v = value as { toString?: () => string };\n  if (typeof v?.toString !== 'function') {\n    throw new FormatSyntaxError({ reason: `formatISO() expects a Temporal value with toString(), got ${typeof value}.` });\n  }\n  return v.toString();\n}\n\n// RFC 3339 is a profile of ISO 8601 used in network protocols (HTTP,\n// JSON-RPC, etc.). Stricter than ISO 8601: requires full date+time,\n// requires seconds, requires UTC offset or 'Z', disallows IANA zone\n// names. Delegates to parseISO then validates the constraints.\n\nexport function parseRFC3339(input: string): unknown {\n  // RFC 3339 grammar (https://www.rfc-editor.org/rfc/rfc3339#section-5.6):\n  //   date-fullyear   = 4DIGIT\n  //   date-month      = 2DIGIT  ; 01-12\n  //   date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31\n  //   time-hour       = 2DIGIT  ; 00-23\n  //   time-minute     = 2DIGIT  ; 00-59\n  //   time-second     = 2DIGIT  ; 00-58, 00-59, 00-60 (leap second)\n  //   time-secfrac    = \".\" 1*DIGIT\n  //   time-numoffset  = (\"+\" / \"-\") time-hour \":\" time-minute\n  //   time-offset     = \"Z\" / time-numoffset\n  //   partial-time    = time-hour \":\" time-minute \":\" time-second [time-secfrac]\n  //   full-date       = date-fullyear \"-\" date-month \"-\" date-mday\n  //   full-time       = partial-time time-offset\n  //   date-time       = full-date \"T\" full-time\n  const re = /^(\\d{4})-(\\d{2})-(\\d{2})[Tt](\\d{2}):(\\d{2}):(\\d{2})(\\.\\d+)?([Zz]|[+-]\\d{2}:\\d{2})$/;\n  const m = re.exec(input);\n  if (!m) {\n    throw new FormatSyntaxError({ input, reason: 'does not match RFC 3339 date-time grammar' });\n  }\n  // Construct via parseISO with the same expansion for bare Z.\n  const iso = input.replace(/[tT]/, 'T').replace(/[zZ]$/, '+00:00[UTC]');\n  return parseISO(iso);\n}\n\nexport function formatRFC3339(value: unknown): string {\n  // RFC 3339 output is ISO 8601 with a UTC offset. toString() on a\n  // ZonedDateTime produces this shape; we just verify the result looks\n  // like RFC 3339 and pass it through.\n  const s = formatISO(value);\n  if (!/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?(Z|[+-][0-9]{2}:[0-9]{2})$/.test(s)) {\n    throw new FormatSyntaxError({ input: s, reason: 'value did not produce RFC 3339-compliant output' });\n  }\n  return s;\n}\n\n// RFC 2822 date-time (used in email Message-ID headers, etc.). Format:\n//   day-of-week, day month year hour:minute:second zone\n// e.g. \"Mon, 04 Aug 2026 15:45:30 +0000\"\n// JS Date can parse this natively, so we use Date.parse and convert\n// to a Temporal.Instant. (Date.parse's RFC 2822 support is universal\n// across engines, unlike its ISO 8601 support which varies.)\n\nexport function parseRFC2822(input: string): unknown {\n  // Strict shape pre-check: Date.parse is far more permissive than RFC 2822\n  // (it happily accepts ISO 8601 and other dialects), so without this gate\n  // parseRFC2822(\"2026-08-04\") would succeed despite not being an RFC 2822\n  // date at all. The regex mirrors RFC 2822 §3.3's date-time grammar:\n  // optional day-of-week, 1-2 digit day, month name, 2-4 digit year (the\n  // obsolete two-digit form included), time with optional seconds, and a\n  // zone that is either a numeric ±HHMM offset or an alphabetic zone name.\n  const RFC2822_SHAPE =\n    /^(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?\\d{1,2}\\s+(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s+\\d{2,4}\\s+\\d{2}:\\d{2}(?::\\d{2})?\\s+(?:[+-]\\d{4}|[A-Za-z]{1,5})$/;\n  if (!RFC2822_SHAPE.test(input.trim())) {\n    throw new FormatSyntaxError({ input, reason: 'not a valid RFC 2822 date' });\n  }\n  const ms = Date.parse(input);\n  if (Number.isNaN(ms)) {\n    throw new FormatSyntaxError({ input, reason: 'not a valid RFC 2822 date' });\n  }\n  return requireInstant().fromEpochMilliseconds(ms);\n}\n\nexport function formatRFC2822(value: unknown): string {\n  // Format using format() with the right tokens, then construct via\n  // the value's epoch ms. RFC 2822 requires a fixed offset, not an\n  // IANA zone, so we read the value's offset directly.\n  const v = value as { toEpochMilliseconds?: () => number; epochMilliseconds?: number; toInstant?: () => { epochMilliseconds: number } };\n  let ms: number | undefined;\n  if (typeof v?.toEpochMilliseconds === 'function') {\n    ms = v.toEpochMilliseconds();\n  } else if (typeof v?.epochMilliseconds === 'number') {\n    // Temporal.Instant exposes epochMilliseconds as a property.\n    ms = v.epochMilliseconds;\n  } else if (typeof v?.toInstant === 'function') {\n    // ZonedDateTime.toInstant() → Instant.\n    const inst = v.toInstant();\n    if (typeof (inst as { epochMilliseconds?: number }).epochMilliseconds === 'number') {\n      ms = (inst as { epochMilliseconds: number }).epochMilliseconds;\n    }\n  }\n  if (ms === undefined) {\n    throw new FormatSyntaxError({ reason: `formatRFC2822() expects a value with epochMilliseconds, toEpochMilliseconds(), or toInstant(), got ${typeof value}.` });\n  }\n  return formatRFC2822FromMs(ms);\n}\n\nfunction formatRFC2822FromMs(ms: number): string {\n  // Use Intl.DateTimeFormat with the en-US POSIX locale and the rfc822\n  // format option. Modern Node ships Intl with this option; if not\n  // available, fall back to manual formatting.\n  try {\n    const fmt = new Intl.DateTimeFormat('en-US', {\n      weekday: 'short', day: '2-digit', month: 'short', year: 'numeric',\n      hour: '2-digit', minute: '2-digit', second: '2-digit',\n      timeZone: 'UTC', timeZoneName: 'shortOffset',\n      hour12: false,\n    });\n    const parts = fmt.formatToParts(new Date(ms));\n    /* c8 ignore start -- every part type get() is called with (weekday,\n       day, month, year, hour, minute, second, timeZoneName) is always\n       present given the fixed options above, so the ?? '' fallback\n       can't fire without a different Intl implementation. */\n    const get = (t: string) => parts.find((p) => p.type === t)?.value ?? '';\n    /* c8 ignore stop */\n    const tzRaw = get('timeZoneName');\n    // Intl's shortOffset returns \"GMT+0\", \"GMT-8\", \"GMT+5:30\", etc.\n    // RFC 2822 wants \"+0000\", \"-0800\", \"+0530\". Parse and reformat.\n    const tzMatch = tzRaw?.match(/GMT([+-])(\\d+)(?::(\\d+))?/);\n    let tz: string;\n    if (tzMatch) {\n      const sign = tzMatch[1]!;\n      const hours = tzMatch[2]!.padStart(2, '0');\n      const minutes = (tzMatch[3] ?? '0').padStart(2, '0');\n      tz = `${sign}${hours}${minutes}`;\n    /* c8 ignore start @preserve -- timeZone is hardcoded to 'UTC' above,\n       which always resolves cleanly, so shortOffset always returns a\n       parseable \"GMT+0\"-shaped string in this environment's ICU. This\n       branch only guards against an ICU build whose shortOffset output\n       doesn't match the regex; can't trigger it without mocking Intl.\n       The ignore starts before the closing brace of the if-block so it\n       covers the whole else-branch node c8 tracks as a single unit. */\n    } else {\n      tz = '+0000';\n    }\n    /* c8 ignore stop @preserve */\n    let hour = get('hour');\n    /* c8 ignore start @preserve -- hour12:false with a fixed UTC zone\n       never yields \"24\" in this environment's ICU (midnight formats as\n       \"00\"). Some ICU versions/locales are documented to emit \"24\" for\n       hour12:false, so this stays as a defensive normalization; not\n       reachable here without mocking Intl.DateTimeFormat's output. */\n    if (hour === '24') hour = '00';\n    /* c8 ignore stop @preserve */\n    return `${get('weekday')}, ${get('day')} ${get('month')} ${get('year')} ${hour}:${get('minute')}:${get('second')} ${tz}`;\n    /* c8 ignore start @preserve -- Intl.DateTimeFormat is constructed\n       above with a literal, always-valid timeZone: 'UTC' and no other\n       user input reaches the constructor or formatToParts call, so this\n       catch can't be triggered through the public API in a normal Intl\n       environment (e.g. Node with full-icu). Kept as a genuine fallback\n       for runtimes with a broken or absent Intl implementation. */\n  } catch {\n    // Fallback: hand-rolled RFC 2822 format via Date's UTC methods.\n    const d = new Date(ms);\n    const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n    const wd = days[d.getUTCDay()];\n    const dd = String(d.getUTCDate()).padStart(2, '0');\n    const mon = months[d.getUTCMonth()]!;\n    const yyyy = d.getUTCFullYear();\n    const hh = String(d.getUTCHours()).padStart(2, '0');\n    const mm = String(d.getUTCMinutes()).padStart(2, '0');\n    const ss = String(d.getUTCSeconds()).padStart(2, '0');\n    return `${wd}, ${dd} ${mon} ${yyyy} ${hh}:${mm}:${ss} +0000`;\n  }\n  /* c8 ignore stop @preserve */\n}\n\n// RFC 7231 defines three formats: IMF-fixdate, RFC 850, asctime.\n// The canonical format is IMF-fixdate (RFC 2822-like with required\n// seconds and UTC-only). Delegates to Date.parse for parsing and to\n// formatRFC2822 for formatting (they're nearly identical).\n\nexport function parseHTTPDate(input: string): unknown {\n  const trimmed = input.trim();\n  const ms = Date.parse(trimmed);\n  if (Number.isNaN(ms)) {\n    throw new FormatSyntaxError({ input, reason: 'not a valid HTTP-date' });\n  }\n  return requireInstant().fromEpochMilliseconds(ms);\n}\n\nexport function formatHTTPDate(value: unknown): string {\n  // IMF-fixdate format: \"Sun, 06 Nov 1994 08:49:37 GMT\"\n  const instant = (value as { toInstant?: () => { epochMilliseconds: number } })?.toInstant?.()\n    ?? (value as { epochMilliseconds?: number });\n  const ms = typeof instant === 'object' && instant !== null && 'epochMilliseconds' in instant\n    ? (instant as { epochMilliseconds: number }).epochMilliseconds\n    : (() => { throw new FormatSyntaxError({ reason: `formatHTTPDate() expects an Instant or ZonedDateTime, got ${typeof value}.` }); })();\n  const d = new Date(ms);\n  const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n  const wd = days[d.getUTCDay()];\n  const dd = String(d.getUTCDate()).padStart(2, '0');\n  const mon = months[d.getUTCMonth()]!;\n  const yyyy = d.getUTCFullYear();\n  const hh = String(d.getUTCHours()).padStart(2, '0');\n  const mm = String(d.getUTCMinutes()).padStart(2, '0');\n  const ss = String(d.getUTCSeconds()).padStart(2, '0');\n  return `${wd}, ${dd} ${mon} ${yyyy} ${hh}:${mm}:${ss} GMT`;\n}\n\n// All epoch conversions go through Temporal.Instant, which has spec\n// methods for each epoch granularity. Wrapped here for the\n// temporal-fmt surface so callers don't have to import Temporal\n// directly.\n\nfunction getInstant(value: unknown): { epochMilliseconds: number; epochNanoseconds: bigint } {\n  const v = value as { toInstant?: () => { epochMilliseconds: number; epochNanoseconds: bigint }; epochMilliseconds?: number; epochNanoseconds?: bigint };\n  if (typeof v?.toInstant === 'function') {\n    const inst = v.toInstant();\n    // Prefer the instant's own epochNanoseconds when present — same\n    // precision reasoning as below, since toInstant() can return a\n    // real Temporal.Instant carrying both fields.\n    if (typeof (inst as { epochNanoseconds?: bigint }).epochNanoseconds === 'bigint') {\n      return { epochMilliseconds: inst.epochMilliseconds, epochNanoseconds: (inst as { epochNanoseconds: bigint }).epochNanoseconds };\n    }\n    return { epochMilliseconds: inst.epochMilliseconds, epochNanoseconds: BigInt(inst.epochMilliseconds) * 1_000_000n };\n  }\n  // Check epochNanoseconds before epochMilliseconds: a real\n  // Temporal.Instant exposes both, and epochMilliseconds is truncated\n  // to millisecond precision. Deriving epochNanoseconds by scaling\n  // epochMilliseconds back up would silently drop sub-ms precision\n  // that was available on the object all along.\n  if (typeof v?.epochNanoseconds === 'bigint') {\n    return { epochMilliseconds: Number(v.epochNanoseconds / 1_000_000n), epochNanoseconds: v.epochNanoseconds };\n  }\n  if (typeof v?.epochMilliseconds === 'number') {\n    return { epochMilliseconds: v.epochMilliseconds, epochNanoseconds: BigInt(v.epochMilliseconds) * 1_000_000n };\n  }\n  throw new FormatSyntaxError({ reason: `expected an Instant or ZonedDateTime, got ${typeof value}.` });\n}\n\nfunction requireInstant(): NonNullable<TemporalNamespace['Instant']> {\n  const t = getTemporal().Instant;\n  if (!t) throw new Error('temporal-fmt: Temporal.Instant is not available in this implementation.');\n  return t;\n}\n\nexport function toUnixSeconds(value: unknown): number {\n  return getInstant(value).epochMilliseconds / 1000;\n}\n\nexport function fromUnixSeconds(seconds: number): unknown {\n  return requireInstant().fromEpochMilliseconds(seconds * 1000);\n}\n\nexport function fromUnixMilliseconds(ms: number): unknown {\n  return requireInstant().fromEpochMilliseconds(ms);\n}\n\nexport function fromUnixMicroseconds(µs: number): unknown {\n  // Temporal.Instant has no fromEpochMicroseconds in the spec — only\n  // fromEpochMilliseconds and fromEpochNanoseconds. Convert via ns.\n  return requireInstant().fromEpochNanoseconds(BigInt(µs) * 1_000n);\n}\n\nexport function fromUnixNanoseconds(ns: bigint): unknown {\n  return requireInstant().fromEpochNanoseconds(ns);\n}\n\nexport function toUnixMilliseconds(value: unknown): number {\n  return getInstant(value).epochMilliseconds;\n}\n\nexport function toUnixMicroseconds(value: unknown): number {\n  const { epochNanoseconds } = getInstant(value);\n  return Number(epochNanoseconds / 1_000n);\n}\n\nexport function toUnixNanoseconds(value: unknown): bigint {\n  return getInstant(value).epochNanoseconds;\n}\n\n// SQL-oriented helpers. SQL date/time formats are simpler than the\n// network standards above — just 'YYYY-MM-DD' for dates, 'HH:MM:SS'\n// for times, 'YYYY-MM-DD HH:MM:SS' for datetimes. Delegating to\n// parse() with the right format strings keeps the validation surface\n// consistent.\nexport function parseSQL(input: string): unknown {\n  const trimmed = input.trim();\n  const parseImpl = getParseImpl();\n  if (/^\\d{4}-\\d{2}-\\d{2}$/.test(trimmed)) {\n    return parseImpl('yyyy-MM-dd', trimmed);\n  }\n  if (/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/.test(trimmed)) {\n    return parseImpl('yyyy-MM-dd HH:mm:ss', trimmed);\n  }\n  if (/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/.test(trimmed)) {\n    return parseISO(trimmed);\n  }\n  throw new FormatSyntaxError({ input, reason: 'not a recognized SQL date/time format' });\n}\n\nexport function formatSQL(value: unknown): string {\n  // Detect what kind of Temporal value this is and pick the format.\n  const v = value as { year?: number; hour?: number };\n  const formatImpl = getFormatImpl();\n  if (typeof v?.hour === 'number') {\n    return formatImpl(value as Parameters<typeof format>[0], 'yyyy-MM-dd HH:mm:ss');\n  }\n  return formatImpl(value as Parameters<typeof format>[0], 'yyyy-MM-dd');\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\nimport { canonicalCacheKey, normalizeLocaleTag } from './localeVocab.js';\nimport { InvalidLocaleError } from './errors.js';\n\n// A Temporal.Duration doesn't sit on a calendar — it has no year/month/day\n// position the way a PlainDate does — so the date/time token set in\n// tokens.ts doesn't apply. This is a separate token table for the same\n// reason parseRelative() lives in its own module: a different surface\n// deserves its own grammar, not a bolt-on to the existing one.\n//\n// Token design: each unit has three forms, in increasing verbosity.\n//   `y`   — numeric value, no unit text (\"2\")\n//   `yy`  — short unit suffix, plural-aware (\"2y\", or \"1y\" — see below)\n//   `yyy` — full unit word, plural-aware (\"2 years\", \"1 year\")\n// Same for months (`o`/`oo`/`ooo` — `o` not `M` because the duration's\n// own field name in Temporal is \"months\" and the long-form output should\n// read \"month\"/\"months\", but the *token* letter is arbitrary; `o` is\n// chosen so it doesn't visually collide with `m` (minutes) or `M`\n// (months in date format) when a reader skims both tables side by side).\n//\n// Locale-aware rendering: when a `locale` is passed, the short/long\n// forms delegate to `Intl.NumberFormat` with `style: 'unit'`. That gives\n// us pluralization, native unit names, and the locale's preferred\n// spacing for free, matching the same \"delegate to Intl\" approach\n// `formatDistance` already uses. Without a `locale`, the original\n// English-only hardcoded table is used so existing default output stays\n// byte-identical — this is an additive locale option, not a rewrite of\n// the default rendering path.\n\ntype UnitKey = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\ninterface UnitForms {\n  // singular and plural suffixes for the long form (e.g. \"year\", \"years\")\n  longSingular: string;\n  longPlural: string;\n  // singular and plural suffixes for the short form (e.g. \"yr\", \"yrs\")\n  shortSingular: string;\n  shortPlural: string;\n  // the property on Temporal.Duration to read for this unit\n  field: UnitKey;\n  // Intl.NumberFormat unit identifier (used only on the locale-aware path).\n  // Confirmed against the current Intl spec — including `millisecond`, which\n  // is in fact supported by every engine we target (Node 20+, modern ICU).\n  // The task brief flagged this as a possible gap; empirically it isn't.\n  intlUnit: string;\n}\n\nconst DURATION_UNITS: Record<string, UnitForms> = {\n  y: { longSingular: 'year', longPlural: 'years', shortSingular: 'yr', shortPlural: 'yrs', field: 'years', intlUnit: 'year' },\n  o: { longSingular: 'month', longPlural: 'months', shortSingular: 'mo', shortPlural: 'mos', field: 'months', intlUnit: 'month' },\n  w: { longSingular: 'week', longPlural: 'weeks', shortSingular: 'wk', shortPlural: 'wks', field: 'weeks', intlUnit: 'week' },\n  d: { longSingular: 'day', longPlural: 'days', shortSingular: 'd', shortPlural: 'd', field: 'days', intlUnit: 'day' },\n  h: { longSingular: 'hour', longPlural: 'hours', shortSingular: 'h', shortPlural: 'h', field: 'hours', intlUnit: 'hour' },\n  m: { longSingular: 'minute', longPlural: 'minutes', shortSingular: 'm', shortPlural: 'm', field: 'minutes', intlUnit: 'minute' },\n  s: { longSingular: 'second', longPlural: 'seconds', shortSingular: 's', shortPlural: 's', field: 'seconds', intlUnit: 'second' },\n  S: { longSingular: 'millisecond', longPlural: 'milliseconds', shortSingular: 'ms', shortPlural: 'ms', field: 'milliseconds', intlUnit: 'millisecond' },\n};\n\n// Token strings this module recognizes, longest-first for the greedy\n// tokenizer. tokenize() in tokenize.ts already does longest-first via\n// SORTED_TOKEN_STRINGS, but it operates on the *date/time* TOKENS table —\n// not this one. Rather than teach tokenize() about two tables, this\n// module uses its own equivalent scan over DURATION_UNITS keys.\nconst DURATION_TOKEN_STRINGS = Object.keys(DURATION_UNITS)\n  .flatMap((single) => [single + single + single, single + single, single])\n  .sort((a, b) => b.length - a.length);\n\ntype Piece =\n  | { kind: 'token'; value: string; unit: string; form: 'numeric' | 'short' | 'long' }\n  | { kind: 'literal'; value: string };\n\n// Same greedy-match shape as tokenize() in tokenize.ts, but with this\n// module's own token set. Quoted-literal handling is identical so the\n// same documented escaping rules carry over: 'at' is a literal, '' is a\n// literal quote.\nfunction tokenizeDuration(format: string): Piece[] {\n  const pieces: Piece[] = [];\n  let i = 0;\n  while (i < format.length) {\n    const ch = format[i];\n    if (ch === \"'\") {\n      if (format[i + 1] === \"'\") {\n        appendLiteral(pieces, \"'\");\n        i += 2;\n        continue;\n      }\n      let j = i + 1;\n      let literal = '';\n      let closed = false;\n      while (j < format.length) {\n        if (format[j] === \"'\") {\n          if (format[j + 1] === \"'\") {\n            literal += \"'\";\n            j += 2;\n            continue;\n          }\n          closed = true;\n          j += 1;\n          break;\n        }\n        literal += format[j];\n        j += 1;\n      }\n      if (!closed) {\n        throw new Error(`temporal-fmt: unterminated quote in duration format string \"${format}\"`);\n      }\n      appendLiteral(pieces, literal);\n      i = j;\n      continue;\n    }\n    const match = DURATION_TOKEN_STRINGS.find((tok) => format.startsWith(tok, i));\n    if (match) {\n      // single letter = numeric, double = short, triple = long\n      const unit = match[0]!;\n      const form = match.length === 1 ? 'numeric' : match.length === 2 ? 'short' : 'long';\n      pieces.push({ kind: 'token', value: match, unit, form });\n      i += match.length;\n      continue;\n    }\n    appendLiteral(pieces, ch);\n    i += 1;\n  }\n  return pieces;\n}\n\nfunction appendLiteral(pieces: Piece[], value: string): void {\n  const last = pieces[pieces.length - 1];\n  if (last && last.kind === 'literal') {\n    last.value += value;\n  } else {\n    pieces.push({ kind: 'literal', value });\n  }\n}\n\n// Reads a unit value off the duration in a way that works for both real\n// Temporal.Duration objects and field bags ({ hours: 2, minutes: 30 }).\n// Temporal.Duration values are numbers, possibly negative for\n// backwards durations; a field bag the caller passes might leave fields\n// off entirely (undefined → treated as 0 for this unit).\nfunction readUnit(duration: Record<string, unknown>, field: UnitKey): number {\n  const value = duration[field];\n  if (value === undefined || value === null) return 0;\n  if (typeof value === 'number' && Number.isFinite(value)) return value;\n  // Temporal.Duration values are always numbers, but a hand-built field\n  // bag could end up with a string here. Coerce; throw on garbage rather\n  // than silently formatting NaN.\n  const coerced = Number(value);\n  if (!Number.isFinite(coerced)) {\n    throw new Error(\n      `temporal-fmt: duration field \"${field}\" is not a finite number (got ${String(value)}).`\n    );\n  }\n  return coerced;\n}\n\n// Intl.NumberFormat is expensive to construct, and a typical duration\n// render walks 2-4 units — so a tight loop on the same (locale, unit,\n// display) triple would otherwise rebuild the formatter for every token\n// of every row. Cache by canonical-locale + unit + display, same\n// eviction shape as the other locale-keyed caches in this library\n// (formatterCache in tokens.ts, rtfCache in formatDistance.ts).\nconst unitFormatterCache = new Map<string, Intl.NumberFormat>();\nconst MAX_UNIT_FORMATTER_CACHE_SIZE = 200;\n\nfunction getUnitFormatter(locale: string, intlUnit: string, unitDisplay: 'short' | 'long'): Intl.NumberFormat {\n  const key = `${canonicalCacheKey(locale)}|${intlUnit}|${unitDisplay}`;\n  const cached = unitFormatterCache.get(key);\n  if (cached) return cached;\n  if (unitFormatterCache.size >= MAX_UNIT_FORMATTER_CACHE_SIZE) {\n    const oldestKey = unitFormatterCache.keys().next().value;\n    if (oldestKey !== undefined) unitFormatterCache.delete(oldestKey);\n  }\n  let formatter: Intl.NumberFormat;\n  try {\n    formatter = new Intl.NumberFormat(normalizeLocaleTag(locale), {\n      style: 'unit',\n      unit: intlUnit,\n      unitDisplay,\n    });\n  } catch (err) {\n    // Malformed locale tags reach Intl as a bare RangeError; surface the\n    // library's typed error instead. (Every failure mode of these\n    // constructors with a string locale is a RangeError, so converting\n    // unconditionally loses nothing — the original message is preserved\n    // in `reason` either way.)\n    throw new InvalidLocaleError({ actual: locale, reason: (err as Error).message });\n  }\n  unitFormatterCache.set(key, formatter);\n  return formatter;\n}\n\nexport interface DurationFormatOptions extends FormatOptions {\n  /**\n   * When true, units whose value is zero are still emitted in the output\n   * (e.g. \"0 hours, 30 minutes\" instead of \"30 minutes\"). Default is\n   * false: zero-value units are omitted, matching how date-fns's\n   * formatDuration works and how most callers rendering a duration to\n   * a human would want it.\n   */\n  showZeroValues?: boolean;\n}\n\n/**\n * Format a Temporal.Duration (or a plain field bag { years, months, ...\n * }) using a duration-specific token string. Token grammar is documented\n * in the README under \"Duration formatting\" — it does NOT reuse the\n * date/time token table, since a duration has no calendar position.\n *\n * Zero-value units are omitted by default; pass { showZeroValues: true }\n * to force them to appear.\n *\n * Unit-name localization: without a `locale`, output is the original\n * English hardcoded singular/plural forms (byte-identical to previous\n * versions). With a `locale`, the short/long forms delegate to\n * `Intl.NumberFormat`'s `style: 'unit'` — same approach `formatDistance`\n * already uses for `Intl.RelativeTimeFormat`. Numeric-only tokens\n * (`y`, `o`, `w`, ...) are not affected by `locale`; they remain ASCII\n * digits, matching the rest of this library's \"numbers stay Western\"\n * convention.\n *\n * @example\n * formatDuration(Temporal.Duration.from({ years: 2, months: 1 }), 'yyy ooo')\n * // \"2 years 1 month\"\n * formatDuration({ hours: 2, minutes: 30 }, 'hhh mmm', { locale: 'fr-FR' })\n * // \"2 heures 30 minutes\"\n */\nexport function formatDuration(\n  duration: Record<string, unknown>,\n  formatStr: string,\n  options: DurationFormatOptions = {},\n): string {\n  return renderDurationPieces(duration, formatStr, options).map((p) => p.value).join('');\n}\n\n// One rendered piece of a duration format string: either literal text or\n// a token with its already-rendered value (empty string for a\n// zero-suppressed token, matching formatDurationToParts' documented\n// contract of emitting an empty token part rather than dropping it).\nexport interface RenderedDurationPiece {\n  kind: 'literal' | 'token';\n  value: string;\n  token?: string;\n}\n\n// Shared renderer behind both formatDuration() (joins the pieces) and\n// formatDurationToParts() (returns them). Single source of truth, so the\n// joined string and the parts can never disagree — the old\n// formatDurationToParts re-derived part boundaries by searching the\n// rendered string with indexOf and mis-sliced whenever a literal's text\n// also occurred inside an earlier token's rendered value.\nexport function renderDurationPieces(\n  duration: Record<string, unknown>,\n  formatStr: string,\n  options: DurationFormatOptions = {},\n): RenderedDurationPiece[] {\n  if (formatStr.length > MAX_FORMAT_LENGTH) {\n    throw new Error(\n      `temporal-fmt: duration format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n      `(got ${formatStr.length}).`\n    );\n  }\n\n  const showZeroes = options.showZeroValues === true;\n  // Undefined locale → keep the original hardcoded English path so\n  // existing default output is byte-identical. Any locale string passed\n  // (including 'en-US') takes the Intl.NumberFormat path — so an\n  // explicit `locale: 'en-US'` will produce Intl's spacing/word choices\n  // rather than the hand-rolled English table. That's intentional: the\n  // locale-aware path delegates to Intl, the default path doesn't.\n  const locale = options.locale;\n  const useIntl = locale !== undefined;\n\n  const pieces = tokenizeDuration(formatStr);\n  const out: RenderedDurationPiece[] = [];\n\n  for (const piece of pieces) {\n    if (piece.kind === 'literal') {\n      out.push({ kind: 'literal', value: piece.value });\n      continue;\n    }\n\n    const unit = DURATION_UNITS[piece.unit];\n    // Dead by construction: piece.unit always comes from match[0] where\n    // match is a member of DURATION_TOKEN_STRINGS, itself built\n    // exhaustively from DURATION_UNITS' own keys — so this lookup can\n    // never miss. Kept in case tokenizeDuration's token construction\n    // ever diverges from DURATION_UNITS.\n    /* c8 ignore start */\n    if (!unit) {\n      throw new Error(`temporal-fmt: unknown duration token \"${piece.value}\"`);\n    }\n    /* c8 ignore stop */\n\n    const value = readUnit(duration, unit.field);\n    if (value === 0 && !showZeroes) {\n      // Omit zero-value units entirely. The token's contribution to the\n      // output is empty — but this can leave a dangling separator literal\n      // (e.g. \"2 hours, \" with nothing after). Callers who want clean\n      // output should structure their format string to not put a\n      // separator after a unit that might be zero, or use showZeroValues.\n      out.push({ kind: 'token', value: '', token: piece.value });\n      continue;\n    }\n\n    if (piece.form === 'numeric') {\n      out.push({ kind: 'token', value: String(value), token: piece.value });\n      continue;\n    }\n\n    if (useIntl) {\n      // Intl.NumberFormat handles pluralization, native unit names, and\n      // locale-appropriate spacing all in one call — no point replicating\n      // that here. We pass the value as-is so negative durations\n      // (`-1 hour`) round-trip the sign the way Intl expects.\n      const unitDisplay = piece.form === 'short' ? 'short' : 'long';\n      const formatter = getUnitFormatter(locale!, unit.intlUnit, unitDisplay);\n      out.push({ kind: 'token', value: formatter.format(value), token: piece.value });\n      continue;\n    }\n\n    // Default-path English. Plural rule based on absolute value matches\n    // what Intl does for unit style on en-US — only |value| === 1 is\n    // singular, including for negatives like \"-1 hour\" (which is what\n    // Intl produces for en-US too).\n    if (piece.form === 'short') {\n      out.push({ kind: 'token', value: value + (value === 1 || value === -1 ? unit.shortSingular : unit.shortPlural), token: piece.value });\n    } else {\n      out.push({ kind: 'token', value: value + ' ' + (value === 1 || value === -1 ? unit.longSingular : unit.longPlural), token: piece.value });\n    }\n  }\n\n  return out;\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Duration extensions. The existing formatDuration()\n// in formatDuration.ts stays as-is; this module adds the rest of the\n// duration surface: parseDuration, parseISODuration, formatISODuration,\n// formatDurationToParts, balanceDuration, roundDuration (re-exported\n// from rounding.ts), totalDuration, compareDuration, addDuration,\n// subtractDuration.\n//\n// All operate on plain field bags ({ years, months, weeks, days, hours,\n// minutes, seconds, milliseconds, microseconds, nanoseconds }) rather\n// than Temporal.Duration instances — same convention as the rest of\n// this module set, so callers can use these without committing to a\n// Temporal implementation. addDuration/subtractDuration produce a new\n// field bag; totalDuration produces a number; compareDuration produces\n// -1/0/1.\n\nimport { roundDuration, fieldToNs, type DurationFields } from './rounding.js';\nimport { formatDuration, renderDurationPieces } from './formatDuration.js';\nimport { InvalidDurationError, FormatSyntaxError } from './errors.js';\n\n// Re-export roundDuration here so callers can import everything duration-\n// related from one place.\nexport { roundDuration };\nexport type { DurationFields };\n\n// Mirrors formatToParts in format.ts. Returns the same piece list\n// formatDuration() would consume, but split into parts instead of\n// joined. Useful for callers building custom UIs (one DOM node per\n// unit) or doing their own unit suppression logic.\n\nimport type { Piece } from './tokenize.js';\n\nexport interface DurationPart {\n  type: 'literal' | 'token';\n  value: string;\n  token?: string;\n}\n\n// Delegates to formatDuration()'s own piece renderer, so the joined\n// string and the parts can never disagree. (This used to re-tokenize the\n// format string and re-derive part boundaries by searching the rendered\n// string with indexOf — which mis-sliced whenever a literal's text also\n// occurred inside an earlier token's rendered value, e.g. a \"s\"\n// separator against \"5 seconds\".) Zero-suppressed tokens emit an empty\n// token part and their neighboring literals are kept, matching the\n// documented formatDurationToParts contract.\nexport function formatDurationToParts(\n  duration: Record<string, unknown>,\n  formatStr: string,\n  options: Parameters<typeof formatDuration>[2] = {},\n): DurationPart[] {\n  return renderDurationPieces(duration, formatStr, options).map((p) =>\n    p.kind === 'token' ? { type: 'token' as const, value: p.value, token: p.token } : { type: 'literal' as const, value: p.value },\n  );\n}\n\n// ISO 8601 duration format: P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S\n// e.g. \"P3Y6M4DT12H30M5S\", \"PT1H30M\", \"P1W\", \"P0D\".\n// Parsed into a DurationFields bag.\nexport function parseISODuration(input: string): DurationFields {\n  // Loose grammar: [-]P [years Y] [months M] [weeks W] [days D] [T [hours H] [minutes M] [seconds S]]\n  // Weeks is an ISO 8601-2 extension; widely supported. The optional\n  // leading '-' is ISO's negative-duration form (the same sign\n  // formatISODuration now emits — it used to produce \"PT-30S\", which\n  // this parser rejects, so the pair didn't round-trip).\n  const re = /^(-)?P(?:(?:(\\d+(?:\\.\\d+)?)Y)?(?:(\\d+(?:\\.\\d+)?)M)?(?:(\\d+(?:\\.\\d+)?)W)?(?:(\\d+(?:\\.\\d+)?)D)?)?(?:T(?:(\\d+(?:\\.\\d+)?)H)?(?:(\\d+(?:\\.\\d+)?)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/;\n  const m = re.exec(input);\n  if (!m) {\n    throw new InvalidDurationError({ input, reason: 'does not match ISO 8601 duration grammar ([-]P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S)' });\n  }\n  // All-zero / empty: P0D is valid ISO for zero duration.\n  if (m.slice(2).every((g) => g === undefined)) {\n    throw new InvalidDurationError({ input, reason: 'duration has no fields (use \"P0D\" for zero duration)' });\n  }\n  const toNum = (s: string | undefined): number => s === undefined ? 0 : Number(s);\n  // Avoid -0 (deep-equal-unequal to 0 and confusing in JSON): only\n  // actual nonzero values pick up the sign.\n  const negate = (n: number): number => m[1] === '-' && n !== 0 ? -n : n;\n  return {\n    years: negate(toNum(m[2])),\n    months: negate(toNum(m[3])),\n    weeks: negate(toNum(m[4])),\n    days: negate(toNum(m[5])),\n    hours: negate(toNum(m[6])),\n    minutes: negate(toNum(m[7])),\n    seconds: negate(toNum(m[8])),\n  };\n}\n\nexport function formatISODuration(duration: DurationFields): string {\n  // ISO 8601 expresses a negative duration with a leading '-' on the\n  // whole designator (\"−PT30S\"), never with negative components — the\n  // old format emitted \"PT-30S\", which parseISODuration (and every\n  // other ISO 8601 reader) rejects. Emit the sign up front and absolute\n  // components after it, so the output round-trips through this\n  // module's own parser.\n  const negative = (duration.years ?? 0) < 0 || (duration.months ?? 0) < 0 || (duration.weeks ?? 0) < 0\n    || (duration.days ?? 0) < 0 || (duration.hours ?? 0) < 0 || (duration.minutes ?? 0) < 0\n    || (duration.seconds ?? 0) < 0;\n  const sign = negative ? '-' : '';\n  const years = Math.abs(duration.years ?? 0);\n  const months = Math.abs(duration.months ?? 0);\n  const weeks = Math.abs(duration.weeks ?? 0);\n  const days = Math.abs(duration.days ?? 0);\n  const hours = Math.abs(duration.hours ?? 0);\n  const minutes = Math.abs(duration.minutes ?? 0);\n  const seconds = Math.abs(duration.seconds ?? 0);\n  const parts: string[] = [`${sign}P`];\n  if (years) parts.push(`${years}Y`);\n  if (months) parts.push(`${months}M`);\n  if (weeks) parts.push(`${weeks}W`);\n  if (days) parts.push(`${days}D`);\n  if (hours || minutes || seconds) {\n    parts.push('T');\n    if (hours) parts.push(`${hours}H`);\n    if (minutes) parts.push(`${minutes}M`);\n    if (seconds) parts.push(`${seconds}S`);\n  }\n  // parts is just ['P'] (or ['-P']) when every field is zero -- ISO has\n  // no empty duration, so fall back to P0D.\n  if (parts.length === 1) parts.push('0D');\n  return parts.join('');\n}\n\n// Minimal tokenizer for the duration format string. Reuses the same\n// quoted-literal and greedy-match logic as tokenize.ts.\nfunction tokenizeDurationFormat(formatStr: string): Array<Piece & { unit?: string }> {\n  const DURATION_TOKEN_STRINGS = ['y', 'o', 'w', 'd', 'h', 'm', 's', 'S']\n    .flatMap((single) => [single + single + single, single + single, single])\n    .sort((a, b) => b.length - a.length);\n  const pieces: Array<Piece & { unit?: string }> = [];\n  let i = 0;\n  while (i < formatStr.length) {\n    const ch = formatStr[i];\n    if (ch === \"'\") {\n      if (formatStr[i + 1] === \"'\") {\n        appendLiteral(pieces, \"'\");\n        i += 2;\n        continue;\n      }\n      let j = i + 1;\n      let literal = '';\n      let closed = false;\n      while (j < formatStr.length) {\n        if (formatStr[j] === \"'\") {\n          if (formatStr[j + 1] === \"'\") {\n            literal += \"'\";\n            j += 2;\n            continue;\n          }\n          closed = true;\n          j += 1;\n          break;\n        }\n        literal += formatStr[j]!;\n        j += 1;\n      }\n      if (!closed) throw new FormatSyntaxError({ format: formatStr, reason: 'unterminated quote' });\n      appendLiteral(pieces, literal);\n      i = j;\n      continue;\n    }\n    const match = DURATION_TOKEN_STRINGS.find((tok) => formatStr.startsWith(tok, i));\n    if (match) {\n      pieces.push({ kind: 'token', value: match, unit: match[0] });\n      i += match.length;\n      continue;\n    }\n    appendLiteral(pieces, ch);\n    i += 1;\n  }\n  return pieces;\n}\n\nfunction appendLiteral(pieces: Array<Piece & { unit?: string }>, value: string): void {\n  const last = pieces[pieces.length - 1];\n  if (last && last.kind === 'literal') {\n    last.value += value;\n  } else {\n    pieces.push({ kind: 'literal', value });\n  }\n}\n\nfunction findNextLiteralStart(\n  tokens: Array<Piece & { unit?: string }>,\n  _currentTok: Piece & { unit?: string },\n  full: string,\n  pos: number,\n): number {\n  // Find the position in `full` where the next literal after the\n  // current token starts. For now, just return the end of `full` —\n  // formatDurationToParts is best-effort for the common case where\n  // tokens are separated by literals, and degrades gracefully when\n  // they aren't.\n  // A more precise implementation would walk the tokens array from\n  // the current position and use the next literal piece's text to\n  // find the boundary in `full`. Doing it correctly requires handling\n  // zero-value unit suppression, which is why this helper exists.\n  // For now, we use the next literal piece's value as a search anchor.\n  const idx = tokens.indexOf(_currentTok);\n  for (let j = idx + 1; j < tokens.length; j++) {\n    const t = tokens[j]!;\n    if (t.kind === 'literal') {\n      const found = full.indexOf(t.value, pos);\n      if (found >= 0) return found;\n    }\n  }\n  return full.length;\n}\n\n// ISO 8601 duration format: P[n]Y[n]M[n]W[n]DT[n]H[n]M[n]S\n// Parses a duration-format string (the tokenized format formatDuration\n// accepts) into a DurationFields bag. Inverse of formatDuration().\nexport function parseDuration(input: string, formatStr: string, options: { locale?: string } = {}): DurationFields {\n  // Build a capturing regex from the format string. Each token\n  // captures a number; literals are matched literally.\n  const tokens = tokenizeDurationFormat(formatStr);\n  const fields: DurationFields = {};\n  const groupSpecs: Array<{ unit: keyof DurationFields; form: 'numeric' | 'short' | 'long' }> = [];\n  let regex = '';\n  for (const tok of tokens) {\n    if (tok.kind === 'literal') {\n      regex += tok.value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n    } else {\n      const unit = tok.unit!;\n      const form = tok.value.length === 1 ? 'numeric' : tok.value.length === 2 ? 'short' : 'long';\n      // Map token letter to DurationFields key.\n      /* c8 ignore start @preserve -- the final `: null` branch, and the\n         `if (key === null)` throw it feeds, are both unreachable: tok.unit\n         is always one of the 8 letters in DURATION_TOKEN_STRINGS (the same\n         source set this ternary checks against), so `null` can't be\n         produced by any token the tokenizer emits. Kept as a guard against\n         a future letter being added to one set without the other. */\n      const key: keyof DurationFields | null = (\n        unit === 'y' ? 'years'\n        : unit === 'o' ? 'months'\n        : unit === 'w' ? 'weeks'\n        : unit === 'd' ? 'days'\n        : unit === 'h' ? 'hours'\n        : unit === 'm' ? 'minutes'\n        : unit === 's' ? 'seconds'\n        : unit === 'S' ? 'milliseconds'\n        : null\n      );\n      if (key === null) {\n        throw new FormatSyntaxError({ format: formatStr, token: tok.value, reason: 'unknown duration token' });\n      }\n      /* c8 ignore stop @preserve */\n      // Numeric form: capture digits (and optional sign).\n      // Short/long form: capture digits followed by optional unit text.\n      // We'll handle unit-text stripping after the match.\n      if (form === 'numeric') {\n        regex += '(-?\\\\d+)';\n      } else {\n        // Short form like \"2y\" or \"2yrs\"; long form like \"2 years\" or \"2 year\".\n        // Capture the number; unit text is matched but not captured.\n        regex += '(\\\\d+)\\\\s*\\\\w*';\n      }\n      groupSpecs.push({ unit: key, form });\n    }\n  }\n  const re = new RegExp(`^${regex}$`, 'u');\n  const m = re.exec(input);\n  if (!m) {\n    throw new FormatSyntaxError({ input, format: formatStr, reason: 'does not match duration format' });\n  }\n  groupSpecs.forEach((spec, i) => {\n    const raw = m[i + 1]!;\n    const value = Number(raw);\n    if (!Number.isFinite(value)) {\n      throw new InvalidDurationError({ input, reason: `token for ${spec.unit} matched \"${raw}\" but isn't a finite number` });\n    }\n    fields[spec.unit] = value;\n  });\n  return fields;\n}\n\n// Balances a duration's absolute fields (days/hours/minutes/seconds/ms/µs/ns)\n// so each carries its natural range and excess carries into the next\n// larger unit. Doesn't touch calendar-bound fields (years/months/weeks)\n// since those need a relativeTo to balance correctly.\nexport function balanceDuration(duration: DurationFields): DurationFields {\n  const NS_PER: Array<[keyof DurationFields, bigint]> = [\n    ['days', 86_400n * 1_000_000_000n],\n    ['hours', 3_600n * 1_000_000_000n],\n    ['minutes', 60n * 1_000_000_000n],\n    ['seconds', 1_000_000_000n],\n    ['milliseconds', 1_000_000n],\n    ['microseconds', 1_000n],\n    ['nanoseconds', 1n],\n  ];\n  // Sum everything from days down to ns.\n  let totalNs = 0n;\n  for (const [k, nsPer] of NS_PER) {\n    const v = duration[k];\n    if (typeof v === 'number') totalNs += fieldToNs(v, nsPer, k);\n  }\n  // Re-distribute.\n  const result: DurationFields = { ...duration };\n  let remaining = totalNs;\n  for (const [k, nsPer] of NS_PER) {\n    const count = remaining / nsPer;\n    remaining -= count * nsPer;\n    result[k] = Number(count);\n  }\n  return result;\n}\n\n// Sums all absolute fields into a single number expressed in the\n// requested unit. Throws for calendar-bound target units (years/months/\n// weeks) since those need a relativeTo.\nexport function totalDuration(duration: DurationFields, unit: 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds' | 'microseconds' | 'nanoseconds'): number {\n  const NS_PER: Record<string, bigint> = {\n    days: 86_400n * 1_000_000_000n,\n    hours: 3_600n * 1_000_000_000n,\n    minutes: 60n * 1_000_000_000n,\n    seconds: 1_000_000_000n,\n    milliseconds: 1_000_000n,\n    microseconds: 1_000n,\n    nanoseconds: 1n,\n  };\n  let totalNs = 0n;\n  for (const k of Object.keys(NS_PER) as Array<keyof typeof NS_PER>) {\n    const v = duration[k as keyof DurationFields];\n    if (typeof v === 'number') totalNs += fieldToNs(v, NS_PER[k]!, k);\n  }\n  const divisor = NS_PER[unit];\n  if (!divisor) {\n    throw new InvalidDurationError({ reason: `totalDuration() does not support unit \"${unit}\" (calendar-bound units need a relativeTo)` });\n  }\n  return Number(totalNs) / Number(divisor);\n}\n\n// Compares two durations by their total absolute length. Returns -1/0/1.\nexport function compareDuration(a: DurationFields, b: DurationFields): number {\n  const aNs = totalDurationNs(a);\n  const bNs = totalDurationNs(b);\n  if (aNs < bNs) return -1;\n  if (aNs > bNs) return 1;\n  return 0;\n}\n\nfunction totalDurationNs(d: DurationFields): bigint {\n  const NS_PER: Record<string, bigint> = {\n    days: 86_400n * 1_000_000_000n,\n    hours: 3_600n * 1_000_000_000n,\n    minutes: 60n * 1_000_000_000n,\n    seconds: 1_000_000_000n,\n    milliseconds: 1_000_000n,\n    microseconds: 1_000n,\n    nanoseconds: 1n,\n  };\n  let total = 0n;\n  for (const k of Object.keys(NS_PER)) {\n    const v = d[k as keyof DurationFields];\n    if (typeof v === 'number') total += fieldToNs(v, NS_PER[k]!, k);\n  }\n  return total;\n}\n\n// Adds two durations field-by-field. Doesn't balance — call\n// balanceDuration() afterwards if you want a balanced result.\nexport function addDuration(a: DurationFields, b: DurationFields): DurationFields {\n  const keys: Array<keyof DurationFields> = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds', 'nanoseconds'];\n  const result: DurationFields = {};\n  for (const k of keys) {\n    result[k] = (a[k] ?? 0) + (b[k] ?? 0);\n  }\n  return result;\n}\n\nexport function subtractDuration(a: DurationFields, b: DurationFields): DurationFields {\n  return addDuration(a, negateDuration(b));\n}\n\nfunction negateDuration(d: DurationFields): DurationFields {\n  const result: DurationFields = {};\n  for (const k of Object.keys(d) as Array<keyof DurationFields>) {\n    result[k] = -(d[k] ?? 0);\n  }\n  return result;\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// locale registration + lookup. builds on the registerLocaleVocab()\n// stuff already in localeVocab.ts, adds registerLocale() / getLocale() /\n// hasLocale() plus a beefier LocaleVocab that covers quarters, eras,\n// ordinals, duration units, and relative-time words.\n//\n// localeVocab.ts itself is unchanged and still handles months/weekdays/\n// day-periods (what tokens.ts reads for MMMM/MMM/EEEE/EEE/a). this module\n// just wraps that and bolts the extra fields on top\n\nimport { registerLocaleVocab, getLocaleVocab, type LocaleVocab as BaseLocaleVocab } from './localeVocab.js';\nimport { InvalidLocaleError } from './errors.js';\n\nexport interface ExtendedLocaleVocab extends BaseLocaleVocab {\n  // Q1-Q4 long form (\"First quarter\" etc). falls back to \"Q1\"..\"Q4\" if\n  // nothing's registered\n  quartersLong?: string[];\n  quartersShort?: string[];\n  // like [\"BC\", \"AD\"] for gregory. defaults to [\"BC\", \"AD\"]\n  erasLong?: string[];\n  erasShort?: string[];\n  // suffixes like [\"st\", \"nd\", \"rd\", \"th\"] for English. empty by default —\n  // the 'do' token already has English ordinal logic hardcoded in\n  // tokens.ts, this just lets a custom locale override that\n  ordinals?: string[];\n  // long singular/plural names per unit. used by formatDuration's\n  // locale-aware path for cases where Intl.NumberFormat won't cut it,\n  // like a made-up locale Intl's never heard of\n  durationUnits?: {\n    years: [string, string];\n    months: [string, string];\n    weeks: [string, string];\n    days: [string, string];\n    hours: [string, string];\n    minutes: [string, string];\n    seconds: [string, string];\n    milliseconds: [string, string];\n  };\n  // words for \"ago\" / \"in\" / \"now\". used by formatRelative()'s\n  // locale-aware path when Intl.RelativeTimeFormat isn't around or\n  // doesn't know about a locale someone registered\n  relativeTime?: {\n    past: string;\n    future: string;\n    now: string;\n  };\n}\n\n// bounded indirectly — everything added here goes through registerLocale(),\n// which calls registerLocaleVocab() first, and THAT registry already caps\n// out at 500 new locales (MAX_CUSTOM_VOCABS, throws RangeError past it).\n// so extendedVocabs can never actually exceed 500 keys, no need for a\n// separate cap here (would just be dead code anyway)\nconst extendedVocabs = new Map<string, ExtendedLocaleVocab>();\nconst MAX_LOCALE_TAG_LENGTH = 256;\nconst MAX_VOCAB_STRING_LENGTH = 256;\n\nfunction canonicalKey(locale: string): string {\n  try {\n    return new Intl.Locale(locale.replace(/_/g, '-')).toString().toLowerCase();\n  } catch {\n    return locale;\n  }\n}\n\nexport function registerLocale(locale: string, vocab: ExtendedLocaleVocab): void {\n  if (typeof locale !== 'string' || locale.length === 0) {\n    throw new InvalidLocaleError({ actual: String(locale), reason: 'locale string must be non-empty' });\n  }\n  if (locale.length > MAX_LOCALE_TAG_LENGTH) {\n    throw new InvalidLocaleError({ actual: String(locale.length), reason: `locale tag must be at most ${MAX_LOCALE_TAG_LENGTH} characters` });\n  }\n  // base vocab fields (months/weekdays/day-periods) get validated by\n  // registerLocaleVocab already, it's got the strict shape checks\n  registerLocaleVocab(locale, vocab);\n  // extended fields are all optional, only check the ones actually there\n  validateExtended(vocab, locale);\n  const key = canonicalKey(locale);\n  extendedVocabs.set(key, { ...vocab });\n}\n\nfunction validateExtended(vocab: ExtendedLocaleVocab, locale: string): void {\n  const checkArray = (val: unknown, key: string, length: number) => {\n    if (val === undefined) return;\n    if (!Array.isArray(val)) {\n      throw new InvalidLocaleError({ actual: String(val), reason: `locale \"${locale}\": \"${key}\" must be an array` });\n    }\n    if (val.length !== length) {\n      throw new InvalidLocaleError({ actual: String(val.length), reason: `locale \"${locale}\": \"${key}\" must have ${length} entries (got ${val.length})` });\n    }\n    for (let i = 0; i < val.length; i++) {\n      if (typeof val[i] !== 'string' || val[i]!.length === 0) {\n        throw new InvalidLocaleError({ actual: String(val[i]), reason: `locale \"${locale}\": \"${key}[${i}]\" must be a non-empty string` });\n      }\n      if (val[i]!.length > MAX_VOCAB_STRING_LENGTH) {\n        throw new InvalidLocaleError({ actual: String(val[i]!.length), reason: `locale \"${locale}\": \"${key}[${i}]\" must be at most ${MAX_VOCAB_STRING_LENGTH} characters` });\n      }\n    }\n  };\n  checkArray(vocab.quartersLong, 'quartersLong', 4);\n  checkArray(vocab.quartersShort, 'quartersShort', 4);\n  checkArray(vocab.erasLong, 'erasLong', 2);\n  checkArray(vocab.erasShort, 'erasShort', 2);\n  checkArray(vocab.ordinals, 'ordinals', 4);\n}\n\nexport function getLocale(locale: string): ExtendedLocaleVocab | undefined {\n  // gives back the extended vocab for a locale, or undefined if there's\n  // nothing (falls back to Intl at that point). combines the base vocab\n  // (from localeVocab.ts, Intl-derived) with whatever extended fields\n  // got registered here\n  const key = canonicalKey(locale);\n  const ext = extendedVocabs.get(key);\n  if (ext) return ext;\n  // nothing extended registered — just fall back to the base Intl vocab\n  try {\n    const base = getLocaleVocab(locale);\n    return { ...base };\n  } catch {\n    return undefined;\n  }\n}\n\nexport function hasLocale(locale: string): boolean {\n  const key = canonicalKey(locale);\n  return extendedVocabs.has(key);\n}\n\n// re-exporting the base vocab types in case anyone wants them\nexport type { LocaleVocab } from './localeVocab.js';\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// central config stuff. per-call options is the convention we use\n// everywhere else in this lib (formatDistance's cutoffs did it this way\n// first — deliberately NOT a global). so this module just gives callers\n// a typed config object they can build once and pass around, defaults\n// match whatever the per-call defaults already were.\n//\n// no global mutable state, on purpose. don't want a setConfig() anywhere —\n// createConfig() just hands back a frozen object and that's it.\n\nimport { DEFAULT_LOCALE } from './tokens.js';\nimport type { NumberingSystemOption } from './numbering.js';\n\nexport interface TemporalFmtConfig {\n  // BCP-47 tag, defaults to 'en-US'\n  locale: string;\n  // 'gregory', 'hebrew', whatever — leave undefined and it'll just use\n  // whatever the locale defaults to\n  calendar?: string;\n  // IANA id like 'America/New_York', or leave it undefined for system tz\n  timezone?: string;\n  // defaults to 'latn'. 'auto' is accepted too — resolved per call from\n  // the effective locale via Intl (see numbering.ts), so one config can\n  // drive different digits per locale instead of pinning a single system\n  numberingSystem: NumberingSystemOption;\n  // 1 = Monday, 7 = Sunday. default's 1, matches what isoWeek.ts already does\n  firstDayOfWeek: 1 | 7;\n  // for round()/roundDuration(), defaults to 'nearest'\n  roundingMode: 'nearest' | 'floor' | 'ceil' | 'trunc';\n  // what to do when a ZonedDateTime construction hits a gap/overlap.\n  // defaults to 'compatible' since that's Temporal's own default too\n  disambiguation: 'compatible' | 'earlier' | 'later' | 'reject';\n  // handles stuff like Feb 30 when building fields. defaults to 'reject',\n  // same as what parse() already did before this existed\n  overflow: 'constrain' | 'reject';\n  // strict by default (false)\n  parseLenient: boolean;\n  // false by default so zero values just get omitted, not printed\n  durationShowZeroValues: boolean;\n}\n\nexport const DEFAULT_CONFIG: Readonly<TemporalFmtConfig> = Object.freeze({\n  locale: DEFAULT_LOCALE,\n  numberingSystem: 'latn',\n  firstDayOfWeek: 1,\n  roundingMode: 'nearest',\n  disambiguation: 'compatible',\n  overflow: 'reject',\n  parseLenient: false,\n  durationShowZeroValues: false,\n});\n// Frozen: this is exported shared module state, and the module's own\n// header promises \"no global mutable state\" — but DEFAULT_CONFIG was\n// assignable, so one import site writing DEFAULT_CONFIG.locale = 'fr-FR'\n// changed what every subsequent createConfig() in the process returned.\n// Spread ({...DEFAULT_CONFIG}) still makes un-frozen copies wherever\n// defaults feed a merge, so freezing costs nothing.\n\n// merges whatever overrides get passed in on top of the defaults, then\n// freezes it so nobody can mutate it after — Temporal's own options\n// work this way too so figured we'd match that\nexport function createConfig(overrides: Partial<TemporalFmtConfig> = {}): Readonly<TemporalFmtConfig> {\n  const merged: TemporalFmtConfig = { ...DEFAULT_CONFIG, ...overrides };\n  // sanity checks before we freeze it\n  if (typeof merged.locale !== 'string' || merged.locale.length === 0) {\n    throw new Error(`temporal-fmt: config.locale must be a non-empty string (got ${String(merged.locale)}).`);\n  }\n  if (merged.numberingSystem !== undefined && typeof merged.numberingSystem !== 'string') {\n    throw new Error(`temporal-fmt: config.numberingSystem must be a string (got ${String(merged.numberingSystem)}).`);\n  }\n  if (merged.firstDayOfWeek !== 1 && merged.firstDayOfWeek !== 7) {\n    throw new Error(`temporal-fmt: config.firstDayOfWeek must be 1 (Monday) or 7 (Sunday) (got ${merged.firstDayOfWeek}).`);\n  }\n  if (!['nearest', 'floor', 'ceil', 'trunc'].includes(merged.roundingMode)) {\n    throw new Error(`temporal-fmt: config.roundingMode \"${merged.roundingMode}\" is not recognized.`);\n  }\n  if (!['compatible', 'earlier', 'later', 'reject'].includes(merged.disambiguation)) {\n    throw new Error(`temporal-fmt: config.disambiguation \"${merged.disambiguation}\" is not recognized.`);\n  }\n  if (!['constrain', 'reject'].includes(merged.overflow)) {\n    throw new Error(`temporal-fmt: config.overflow \"${merged.overflow}\" is not recognized.`);\n  }\n  return Object.freeze(merged);\n}\n\n// merges a config into per-call options — whatever's already set in\n// per-call wins. format()/parse()/etc use this to fold config in\ninterface ConfigOverrides {\n  locale?: string;\n  calendar?: string;\n  timezone?: string;\n  numberingSystem?: string;\n  lenient?: boolean;\n}\n\nexport function mergeWithConfig<T extends Record<string, unknown>>(\n  config: Readonly<TemporalFmtConfig> | undefined,\n  perCall: T,\n): Record<string, unknown> & ConfigOverrides {\n  if (!config) return perCall;\n  // Returns a fresh object typed by its own actual shape (perCall's\n  // fields plus these five, each optionally overridden) instead of\n  // asserting the result back into the generic T. A `{ ...perCall } as T\n  // & {...}` cast here previously claimed a freshly spread object was\n  // still exactly T, which isn't something a spread can guarantee for an\n  // arbitrary caller-supplied T — tsc rightly rejected that once this\n  // generic got exercised through a real call site (mergeWithConfig's\n  // override wrapper in modApi.ts). Nothing in this codebase currently\n  // calls mergeWithConfig and relies on getting T back rather than this\n  // wider shape, so there's no correctness cost to being honest about\n  // what's actually returned.\n  const extras: ConfigOverrides = {};\n  if (perCall.locale === undefined) extras.locale = config.locale;\n  if (perCall.calendar === undefined && config.calendar !== undefined) extras.calendar = config.calendar;\n  if (perCall.timezone === undefined && config.timezone !== undefined) extras.timezone = config.timezone;\n  if (perCall.numberingSystem === undefined) extras.numberingSystem = config.numberingSystem;\n  if (perCall.lenient === undefined && config.parseLenient) extras.lenient = true;\n  return { ...perCall, ...extras };\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Intervals / ranges. An interval is a pair of\n// (start, end) Temporal values with bounds semantics: open, closed,\n// or half-open. Operations: contains, overlaps, intersects, isBefore,\n// isAfter, intersection, union, difference, subtract, mergeIntervals,\n// splitInterval. Plus formatRange / formatRangeToParts with intelligent\n// collapsing.\n//\n// All operations are field-based (no instanceof), matching the rest of\n// the library. Internally uses the comparison helpers from comparison.ts\n// to order endpoints.\n\nimport { compare } from './comparison.js';\nimport { formatToParts, format as baseFormat, type FormattedPart } from './format.js';\nimport { callFormatImplBatch } from './runtime.js';\nimport { asDateFieldView, type DateFieldView } from './calendarUtils.js';\nimport { normalizeLocaleTag } from './localeVocab.js';\nimport { daysFromCivil } from './isoWeek.js';\nimport type { FormatOptions } from './tokens.js';\n\nexport type IntervalBounds = 'open' | 'closed' | 'half-open-start' | 'half-open-end';\n\nexport interface Interval {\n  start: unknown;\n  end: unknown;\n  bounds: IntervalBounds;\n}\n\nexport function interval(start: unknown, end: unknown, bounds: IntervalBounds = 'closed'): Interval {\n  // Validate that start ≤ end, otherwise the interval is malformed.\n  const cmp = compare(start, end);\n  if (cmp > 0) {\n    throw new Error(\n      `temporal-fmt: interval start must be ≤ end (got start > end). Pass them in chronological order.`\n    );\n  }\n  return { start, end, bounds };\n}\n\n// Inclusive containment check accounting for bounds semantics.\n// - 'closed': [start, end] — both endpoints included\n// - 'open': (start, end) — neither endpoint included\n// - 'half-open-start': (start, end] — start excluded, end included\n// - 'half-open-end': [start, end) — start included, end excluded\n//\n// The two half-open conditions below used to have their labels swapped —\n// 'half-open-end' excluded the start and included the end (the exact\n// behavior 'half-open-start' documents, and vice versa) — which made\n// contains() disagree with difference() (whose labels were correct all\n// along) and silently broke splitInterval's partition (see below).\n// startOpen/beginOpen naming below says which *endpoint* is excluded, so\n// the mapping to the label can't drift again.\nfunction startIncluded(bounds: IntervalBounds): boolean {\n  return bounds === 'closed' || bounds === 'half-open-end';\n}\nfunction endIncluded(bounds: IntervalBounds): boolean {\n  return bounds === 'closed' || bounds === 'half-open-start';\n}\n\nexport function contains(iv: Interval, value: unknown): boolean {\n  const startCmp = compare(value, iv.start);\n  const endCmp = compare(value, iv.end);\n  const afterStart = startIncluded(iv.bounds) ? startCmp >= 0 : startCmp > 0;\n  const beforeEnd = endIncluded(iv.bounds) ? endCmp <= 0 : endCmp < 0;\n  return afterStart && beforeEnd;\n}\n\n// Two intervals overlap iff their ranges intersect, regardless of bounds.\n// intersects() is the boolean form; intersection() returns the actual\n// overlap interval.\nexport function overlaps(a: Interval, b: Interval): boolean {\n  return intersects(a, b);\n}\n\nexport function intersects(a: Interval, b: Interval): boolean {\n  // Two intervals intersect iff they share at least one point. The old\n  // version returned true whenever the spans touched, regardless of\n  // bounds — so (Jan 1, Jan 5) and (Jan 5, Jan 10), which share no point\n  // (Jan 5 belongs to neither), reported as overlapping, and\n  // intersection() returned a degenerate non-empty-looking result for\n  // the empty intersection. Computing the candidate shared span and\n  // consulting contains() at the single shared point handles every\n  // bounds combination uniformly.\n  const loCmp = compare(a.start, b.start);\n  const lo = loCmp >= 0 ? a.start : b.start; // later start\n  const hiCmp = compare(a.end, b.end);\n  const hi = hiCmp <= 0 ? a.end : b.end; // earlier end\n  const inner = compare(lo, hi);\n  if (inner < 0) return true; // strictly inside — a real span is shared\n  if (inner > 0) return false; // spans don't reach each other\n  // lo === hi: the only possible shared point is that single value —\n  // it has to be contained in BOTH intervals.\n  return contains(a, lo) && contains(b, lo);\n}\n\nexport function isBefore(a: Interval, b: Interval): boolean {\n  return compare(a.end, b.start) < 0;\n}\n\nexport function isAfter(a: Interval, b: Interval): boolean {\n  return compare(a.start, b.end) > 0;\n}\n\n// Returns the intersection of two intervals, or null if they don't\n// overlap. The result's bounds at each endpoint come from whichever\n// interval OWNS that endpoint (the later start, the earlier end) — when\n// both intervals supply the same endpoint, intersection inclusivity is\n// the AND of the two (a point is in a∩b only if it's in both).\nexport function intersection(a: Interval, b: Interval): Interval | null {\n  if (!intersects(a, b)) return null;\n  const aStartLater = compare(a.start, b.start) > 0;\n  const start = aStartLater ? a.start : b.start;\n  const aEndEarlier = compare(a.end, b.end) < 0;\n  const end = aEndEarlier ? a.end : b.end;\n  // Start-side inclusivity: owned by the later-start interval, or the\n  // conjunction when the starts are equal.\n  const startInc = aStartLater\n    ? startIncluded(a.bounds)\n    : compare(b.start, a.start) > 0\n      ? startIncluded(b.bounds)\n      : startIncluded(a.bounds) && startIncluded(b.bounds);\n  // End-side inclusivity: owned by the earlier-end interval, or the\n  // conjunction when the ends are equal.\n  const endInc = aEndEarlier\n    ? endIncluded(a.bounds)\n    : compare(a.end, b.end) > 0\n      ? endIncluded(b.bounds)\n      : endIncluded(a.bounds) && endIncluded(b.bounds);\n  const bounds: IntervalBounds = startInc\n    ? (endInc ? 'closed' : 'half-open-end')\n    : (endInc ? 'half-open-start' : 'open');\n  return { start, end, bounds };\n}\n\n// Returns the union of two intervals (the smallest interval containing\n// both), or null if they don't overlap (caller should use mergeIntervals\n// for that case). Union inclusivity at each endpoint comes from the\n// interval that extends further, or the disjunction when both reach the\n// same endpoint.\nexport function union(a: Interval, b: Interval): Interval | null {\n  if (!intersects(a, b)) return null;\n  const aStartEarlier = compare(a.start, b.start) < 0;\n  const start = aStartEarlier ? a.start : b.start;\n  const aEndLater = compare(a.end, b.end) > 0;\n  const end = aEndLater ? a.end : b.end;\n  const startInc = aStartEarlier\n    ? startIncluded(a.bounds)\n    : compare(b.start, a.start) < 0\n      ? startIncluded(b.bounds)\n      : startIncluded(a.bounds) || startIncluded(b.bounds);\n  const endInc = aEndLater\n    ? endIncluded(a.bounds)\n    : compare(a.end, b.end) < 0\n      ? endIncluded(b.bounds)\n      : endIncluded(a.bounds) || endIncluded(b.bounds);\n  const bounds: IntervalBounds = startInc\n    ? (endInc ? 'closed' : 'half-open-end')\n    : (endInc ? 'half-open-start' : 'open');\n  return { start, end, bounds };\n}\n\n// Returns the part of `a` that is not in `b`. May produce 0, 1, or 2\n// intervals depending on the overlap shape.\n//\n// Bounds semantics: each surviving piece keeps the inclusivity of the\n// original endpoint it inherits from `a`, and the endpoint created by the\n// cut is always exclusive (it is `b`'s edge, which belongs to the removed\n// overlap). The old implementation derived both bounds from a lossy\n// helper that collapsed several of these combinations — the pieces'\n// endpoints were right, but the bounds metadata was stricter than the\n// actual remainder for open/half-open inputs.\nexport function difference(a: Interval, b: Interval): Interval[] {\n  if (!intersects(a, b)) return [a];\n  const result: Interval[] = [];\n  // Part of `a` before `b` starts. Its end is b.start; that point stays\n  // in the remainder iff a still contains it AND b doesn't — a cut edge\n  // is only removed when the removed interval actually includes it (a\n  // cut against an open-bounded b used to drop the edge point even\n  // though b never owned it).\n  if (compare(a.start, b.start) < 0) {\n    const endInc = contains(a, b.start) && !contains(b, b.start);\n    result.push({\n      start: a.start,\n      end: b.start,\n      bounds: startIncluded(a.bounds)\n        ? (endInc ? 'closed' : 'half-open-end')\n        : (endInc ? 'half-open-start' : 'open'),\n    });\n  }\n  // Part of `a` after `b` ends — mirror image of the above.\n  if (compare(a.end, b.end) > 0) {\n    const startInc = contains(a, b.end) && !contains(b, b.end);\n    result.push({\n      start: b.end,\n      end: a.end,\n      bounds: startInc\n        ? (endIncluded(a.bounds) ? 'closed' : 'half-open-end')\n        : (endIncluded(a.bounds) ? 'half-open-start' : 'open'),\n    });\n  }\n  return result;\n}\n\n// Alias for difference() — \"subtract\" reads more naturally at some\n// call sites than \"difference\" does.\nexport const subtract = difference;\n\n// Merges a list of intervals, combining overlapping ones. Returns a\n// sorted list of disjoint intervals. The inputs are treated as\n// immutable — the merged result carries shallow copies of any interval\n// object it extends, so a caller's own `end` reference is never\n// reassigned under them (mergeIntervals used to write `last.end =\n// current.end` straight into the caller's object).\nexport function mergeIntervals(intervals: Interval[]): Interval[] {\n  if (intervals.length === 0) return [];\n  const sorted = [...intervals].sort((a, b) => compare(a.start, b.start));\n  // Shallow-copy EVERY interval placed into the result, not just the\n  // first — the inputs are documented as immutable and the merged\n  // object is mutated below (last.end is reassigned), so aliasing any\n  // input would write through to the caller's objects. Non-merged\n  // intervals used to be pushed by reference.\n  const result: Interval[] = [{ ...sorted[0]! }];\n  for (let i = 1; i < sorted.length; i++) {\n    const current = sorted[i]!;\n    const last = result[result.length - 1]!;\n    // Touching endpoints merge only when at least one interval actually\n    // contains the shared point — [1,5) + [5,10] union to [1,10], but\n    // (1,5) + (5,10) leave a hole at exactly 5 and must stay separate.\n    // (Plain overlaps always merge, per intersects().)\n    const touching = compare(last.end, current.start) === 0;\n    const touchMerges = touching && (endIncluded(last.bounds) || startIncluded(current.bounds));\n    if (intersects(last, current) || touchMerges) {\n      // Extend to the farther end, carrying that interval's end\n      // inclusivity over (and when the ends are equal, the union of the\n      // two end inclusivities).\n      const endCmp = compare(current.end, last.end);\n      if (endCmp > 0) {\n        last.end = current.end;\n        last.bounds = startIncluded(last.bounds)\n          ? (endIncluded(current.bounds) ? 'closed' : 'half-open-end')\n          : (endIncluded(current.bounds) ? 'half-open-start' : 'open');\n      } else if (endCmp === 0) {\n        last.bounds = startIncluded(last.bounds)\n          ? (endIncluded(last.bounds) || endIncluded(current.bounds) ? 'closed' : 'half-open-end')\n          : (endIncluded(last.bounds) || endIncluded(current.bounds) ? 'half-open-start' : 'open');\n      }\n    } else {\n      result.push({ ...current });\n    }\n  }\n  return result;\n}\n\n// Widest instant JS Date can represent (±8.64e15 ms, i.e. ±100,000,000\n// days from the Unix epoch). splitInterval rebuilds endpoints via Date,\n// so anything outside this window would silently produce Invalid Date\n// objects with NaN year/month/day fields — reject it descriptively\n// instead.\nconst MAX_DATE_MS = 8.64e15;\n\n// Splits an interval into N equal sub-intervals. Throws if N ≤ 0.\n// Equality is by ms-distance between start and end — for date ranges\n// this approximates \"equal time slices\", which is the most useful\n// interpretation. For calendar-bound splits (e.g. \"split this month\n// into weeks\"), callers should use recurrence() instead.\nexport function splitInterval(iv: Interval, n: number): Interval[] {\n  if (n <= 0) throw new Error(`temporal-fmt: splitInterval requires n > 0 (got ${n}).`);\n  if (n === 1) return [iv];\n  const startFields = asDateFieldView(iv.start) as DateFieldView & { hour?: number; minute?: number; second?: number; millisecond?: number };\n  const endFields = asDateFieldView(iv.end) as DateFieldView & { hour?: number; minute?: number; second?: number; millisecond?: number };\n  const startMs = toMs(startFields);\n  const endMs = toMs(endFields);\n  if (Math.abs(startMs) > MAX_DATE_MS || Math.abs(endMs) > MAX_DATE_MS) {\n    throw new RangeError(\n      `temporal-fmt: splitInterval() endpoints are outside the representable Date range ` +\n      `(approximately ±275,760 years). Split the interval into smaller ranges first.`\n    );\n  }\n  const step = (endMs - startMs) / n;\n  const result: Interval[] = [];\n  // A partition: slice 0 keeps the caller's start inclusivity, slices\n  // 1..n-1 start exactly where the previous slice ended (exclusively),\n  // so their starts are INCLUDED, and every slice except the last\n  // excludes its end; the last slice keeps the caller's end inclusivity.\n  // Together: [s0, s1) [s1, s2) ... [s_{n-1}, s_n] for a closed input —\n  // every point in exactly one slice. (The old version labeled the\n  // middle slices 'half-open-start' — which under the pre-fix, swapped\n  // contains() semantics accidentally behaved like [s, e) — and left\n  // the ORIGINAL end point out of the last slice entirely.)\n  const ivStartInc = startIncluded(iv.bounds);\n  const ivEndInc = endIncluded(iv.bounds);\n  for (let i = 0; i < n; i++) {\n    const sliceStart = startMs + i * step;\n    const sliceEnd = i === n - 1 ? endMs : sliceStart + step;\n    const startInc = i === 0 ? ivStartInc : true;\n    const endInc = i === n - 1 ? ivEndInc : false;\n    result.push({\n      start: fromMs(sliceStart, startFields),\n      end: fromMs(sliceEnd, endFields),\n      // The 'half-open-start' arm on the last line below is structurally\n      // unreachable: startInc is false only for slice 0 (later slices\n      // start included), and slice 0's endInc is always false (only the\n      // last slice carries the input's end inclusivity) — a slice with an\n      // exclusive start AND inclusive end would require n === 1, which\n      // returns [iv] unchanged above. The other arms are live and covered.\n      /* c8 ignore next 3 @preserve */\n      bounds: startInc\n        ? (endInc ? 'closed' : 'half-open-end')\n        : (endInc ? 'half-open-start' : 'open'),\n    });\n  }\n  return result;\n}\n\nfunction toMs(v: DateFieldView & { hour?: number; minute?: number; second?: number; millisecond?: number }): number {\n  // daysFromCivil (isoWeek.ts) is the O(1) Hinnant day count, correct\n  // for negative years. The formula previously inlined here carried a\n  // Math.floor applied to Hinnant's -399-offset numerator — a double\n  // correction that shifted every pre-year-0 date by one day (the\n  // offset form is only equivalent under truncating division, which JS\n  // doesn't have).\n  const days = daysFromCivil(v.year!, v.month!, v.day!);\n  return days * 86_400_000\n    + (v.hour ?? 0) * 3_600_000\n    + (v.minute ?? 0) * 60_000\n    + (v.second ?? 0) * 1_000\n    + (v.millisecond ?? 0);\n}\n\nfunction fromMs(ms: number, base: DateFieldView & { hour?: number; minute?: number; second?: number; millisecond?: number }): DateFieldView {\n  const MS_PER_DAY = 86_400_000;\n  const dayOverflow = Math.floor(ms / MS_PER_DAY);\n  let withinDay = ms % MS_PER_DAY;\n  if (withinDay < 0) withinDay += MS_PER_DAY;\n  const hour = Math.floor(withinDay / 3_600_000);\n  const minute = Math.floor((withinDay % 3_600_000) / 60_000);\n  const second = Math.floor((withinDay % 60_000) / 1_000);\n  const millisecond = withinDay % 1_000;\n  // `ms` (and therefore `dayOverflow`) is already an absolute epoch-ms /\n  // epoch-day value — toMs() computed it via Howard Hinnant's algorithm\n  // from scratch, not as an offset from `base`. So the date only needs\n  // reconstructing from the Unix epoch itself; `base` is just a template\n  // for whatever extra (non-date) fields get spread into the result.\n  // (Previously this added dayOverflow on top of base's own epoch-ms,\n  // double-counting base's offset and landing tens of thousands of days\n  // away from the intended date for any non-epoch base.)\n  const newMs = dayOverflow * MS_PER_DAY;\n  const d = new Date(newMs);\n  return {\n    ...base,\n    year: d.getUTCFullYear(),\n    month: d.getUTCMonth() + 1,\n    day: d.getUTCDate(),\n    hour,\n    minute,\n    second,\n    millisecond,\n  };\n}\n\n// Formats an interval as a single string, collapsing shared fields.\n// E.g. \"August 4 – August 6, 2026\" rather than \"August 4, 2026 – August 6, 2026\".\n// Uses Intl.DateTimeFormat's formatRange when available (most engines),\n// falling back to format(start, fmt) + '–' + format(end, fmt) when not.\n\nexport function formatRange(\n  iv: Interval,\n  formatStr: string,\n  options: FormatOptions = {},\n): string {\n  // The formatStr parameter is this function's contract — the caller\n  // asked for their token format on both endpoints. Honor it first:\n  // format each side with the caller's format string and join with an\n  // en dash. (This used to try Intl.DateTimeFormat.formatRange() first,\n  // which ignores formatStr entirely — formatRange(iv, 'yyyy-MM-dd')\n  // silently returned locale-default output like \"8/4/2026 – 8/6/2026\"\n  // instead of \"2026-08-04 – 2026-08-06\".) Intl's range collapsing is\n  // kept as a fallback for inputs the token path can't render.\n  try {\n    // Both endpoints in one call: with a mod's format() override bridged\n    // to a subprocess, each format() is a pipe round trip, and the batch\n    // form halves that. With no override it's just the two calls this\n    // used to make.\n    const [startStr, endStr] = callFormatImplBatch([iv.start, iv.end] as Array<Parameters<typeof baseFormat>[0]>, formatStr, options);\n    return `${startStr} – ${endStr}`;\n  } catch (err) {\n    // Fallback: Intl.DateTimeFormat.formatRange is the standard\n    // mechanism with native field-collapse behavior, but it has no\n    // knowledge of the caller's token format string.\n    try {\n      const fmt = new Intl.DateTimeFormat(normalizeLocaleTag(options.locale ?? 'en-US'), {});\n      // Cast the interval endpoints to Date for the Intl call. Both\n      // endpoints must be Temporal values that can convert to a Date;\n      // for non-ZonedDateTime values we synthesize a Date via the field\n      // shape (year/month/day/hour/...).\n      const startDate = toJSDate(iv.start);\n      const endDate = toJSDate(iv.end);\n      return fmt.formatRange(startDate, endDate);\n    } catch {\n      // Neither path could render — surface the token-path error, since\n      // the formatStr contract is the primary one.\n      throw err;\n    }\n  }\n}\n\nexport function formatRangeToParts(\n  iv: Interval,\n  formatStr: string,\n  options: FormatOptions = {},\n): FormattedPart[] {\n  // Best-effort: returns formatToParts for the start, then a literal\n  // \" – \" part, then formatToParts for the end. Doesn't currently\n  // expose Intl.DateTimeFormat.formatRangeToParts's collapsed shape —\n  // that would require mapping Intl's part types back to temporal-fmt's\n  // token strings, which is locale-dependent and not stable across\n  // engines.\n  const startParts = formatToParts(iv.start as Parameters<typeof formatToParts>[0], formatStr, options);\n  const endParts = formatToParts(iv.end as Parameters<typeof formatToParts>[0], formatStr, options);\n  const result: FormattedPart[] = [...startParts];\n  result.push({ type: 'literal', value: ' – ' });\n  result.push(...endParts);\n  return result;\n}\n\nfunction toJSDate(value: unknown): Date {\n  const v = value as { year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; millisecond?: number; toInstant?: () => { epochMilliseconds: number } };\n  if (typeof v?.toInstant === 'function') {\n    return new Date(v.toInstant().epochMilliseconds);\n  }\n  if (typeof v?.year === 'number' && typeof v?.month === 'number' && typeof v?.day === 'number') {\n    return new Date(Date.UTC(v.year, v.month - 1, v.day, v.hour ?? 0, v.minute ?? 0, v.second ?? 0, v.millisecond ?? 0));\n  }\n  throw new Error(`temporal-fmt: formatRange() expected Temporal values with year/month/day, got ${typeof value}.`);\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Date arithmetic helpers. Pure functions returning\n// field bags, same convention as calendarUtils.ts/comparison.ts — no\n// Temporal namespace needed. Callers can pass the result back into a\n// Temporal constructor to get a typed value, or chain operations\n// without committing to a Temporal implementation.\n\nimport { asDateFieldView, daysInMonth, type DateFieldView } from './calendarUtils.js';\nimport { dayOfWeekFromCivil, daysFromCivil } from './isoWeek.js';\n\nexport type AddUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\ninterface DateTimeFieldView extends DateFieldView {\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n}\n\nfunction asDateTime(value: unknown): DateTimeFieldView {\n  return asDateFieldView(value) as DateTimeFieldView;\n}\n\n// Recomputes dayOfWeek after year/month/day change. Mirrors\n// calendarUtils.ts's recomputeDayOfWeek — same fix, needed here too\n// since add()/subtract() mutate the date fields via a shallow spread\n// that otherwise leaves the old dayOfWeek sitting there, silently wrong.\nfunction recomputeDayOfWeek(view: DateTimeFieldView): void {\n  if (typeof view.dayOfWeek !== 'number') return;\n  /* c8 ignore start @preserve -- unreachable: every call site (add()'s\n     'years'/'months' cases, shiftDays()) passes a `result` whose\n     year/month/day were just explicitly set, and the value originally\n     came from asDateTime()/asDateFieldView(), which throws unless\n     year/month/day are all present as numbers. So by the time this guard\n     runs, all three are guaranteed valid. Kept in case a future caller\n     constructs a DateTimeFieldView bypassing that validation. */\n  if (typeof view.year !== 'number' || typeof view.month !== 'number' || typeof view.day !== 'number') return;\n  /* c8 ignore stop @preserve */\n  // dayOfWeekFromCivil: O(1) proleptic-Gregorian weekday. The old\n  // Date.UTC(year, month-1, day) form silently remaps years 0-99 to\n  // 1900-1999 (ECMAScript spec behavior), computing the weekday of the\n  // wrong century — e.g. add(PlainDate('0050-01-01'), 1, 'days') used\n  // to report dayOfWeek 1 (Mon) for a date that's a Sunday.\n  view.dayOfWeek = dayOfWeekFromCivil(view.year, view.month, view.day);\n}\n\n// Adds the requested amount to the value's specified unit. Returns a\n// new field bag; the input is not mutated. Handles month/year overflow\n// by clamping to the last valid day of the target month (Feb 29 + 1\n// year on a non-leap year → Feb 28) — Temporal's `constrain` overflow\n// mode, which is the closest match to \"do the obvious thing\" callers\n// expect from arithmetic.\nexport function add(value: unknown, amount: number, unit: AddUnit): DateTimeFieldView {\n  const v = asDateTime(value);\n  let result: DateTimeFieldView = { ...v };\n  switch (unit) {\n    case 'years': {\n      /* c8 ignore start @preserve -- the `?? 0` fallback is unreachable:\n         asDateTime()/asDateFieldView() (called at the top of add()) throws\n         unless year is present as a number, so result.year is never\n         undefined here. Kept as a guard against a future change that\n         relaxes that validation. */\n      result.year = (result.year ?? 0) + amount;\n      /* c8 ignore stop @preserve */\n      // Clamp day-of-month to the new month's length.\n      const maxDay = daysInMonth({ year: result.year!, month: result.month! });\n      if (result.day! > maxDay) result.day = maxDay;\n      recomputeDayOfWeek(result);\n      break;\n    }\n    case 'months': {\n      // Total months = year*12 + month + amount, then split back with\n      // floor division/modulo. JS's % keeps the sign of the dividend, so\n      // a hand-rolled negative-modulo fixup used to double-borrow the\n      // year for totals < 0: add(PlainDate('0001-01-15'), -13, 'months')\n      // returned year -2 / month 12 instead of Temporal's -0001-12-15\n      // (floorDiv already accounted for the borrow; the fixup took\n      // another year off on top).\n      /* c8 ignore start @preserve -- both `??` fallbacks are unreachable\n         for the same reason as the 'years' case above: asDateFieldView()\n         guarantees year and month are present numbers before add() ever\n         reaches here. */\n      const total = (result.year ?? 0) * 12 + (result.month ?? 1) - 1 + amount;\n      /* c8 ignore stop @preserve */\n      result.year = Math.floor(total / 12);\n      result.month = total - result.year * 12 + 1; // floorMod(total, 12) + 1, always in 1..12\n      const maxDay = daysInMonth({ year: result.year!, month: result.month! });\n      if (result.day! > maxDay) result.day = maxDay;\n      recomputeDayOfWeek(result);\n      break;\n    }\n    case 'weeks':\n      result = shiftDays(result, amount * 7);\n      break;\n    case 'days':\n      result = shiftDays(result, amount);\n      break;\n    case 'hours':\n      result = shiftTime(result, amount * 3_600_000);\n      break;\n    case 'minutes':\n      result = shiftTime(result, amount * 60_000);\n      break;\n    case 'seconds':\n      result = shiftTime(result, amount * 1_000);\n      break;\n    case 'milliseconds':\n      result = shiftTime(result, amount);\n      break;\n  }\n  return result;\n}\n\nfunction shiftDays(v: DateTimeFieldView, days: number): DateTimeFieldView {\n  // Convert Y/M/D to a day count, add, convert back. The forward\n  // direction uses isoWeek.ts's daysFromCivil — the era term previously\n  // inlined here applied Math.floor to Hinnant's -399-offset numerator,\n  // which double-corrects for negative years (the offset form assumes\n  // truncating division; JS's is flooring), shifting every pre-year-0\n  // date by one day. The inverse (civil_from_days) below is floor-safe\n  // as written (its out-of-range `doe` cases self-compensate through the\n  // yoe formula — property-tested over years -1000..3000, all months,\n  // round-trip identity holds).\n  const totalDays = daysFromCivil(v.year!, v.month!, v.day!) + days;\n\n  // Invert: totalDays → Y/M/D. Same source (Howard Hinnant's\n  // civil_from_days). The era term MUST use truncating division — the\n  // -146096 offset exists so that trunc lands the era correctly; with\n  // Math.floor every z < 0 came out one day early (the forward formula's\n  // matching error used to hide this on round-trips; now that the\n  // forward direction is exact, the inverse has to be too).\n  const z = totalDays + 719468;\n  const era2 = Math.trunc((z >= 0 ? z : z - 146096) / 146097);\n  const doe2 = z - era2 * 146097;\n  const yoe2 = Math.floor((doe2 - Math.floor(doe2 / 1460) + Math.floor(doe2 / 36524) - Math.floor(doe2 / 146096)) / 365);\n  const y2out = yoe2 + era2 * 400;\n  const doy2 = doe2 - (365 * yoe2 + Math.floor(yoe2 / 4) - Math.floor(yoe2 / 100));\n  const mp = Math.floor((5 * doy2 + 2) / 153);\n  const d2 = doy2 - Math.floor((153 * mp + 2) / 5) + 1;\n  const m2out = mp < 10 ? mp + 3 : mp - 9;\n  const yOut = m2out <= 2 ? y2out + 1 : y2out;\n\n  const result: DateTimeFieldView = { ...v, year: yOut, month: m2out, day: d2 };\n  recomputeDayOfWeek(result);\n  return result;\n}\n\nfunction shiftTime(v: DateTimeFieldView, msDelta: number): DateTimeFieldView {\n  // Convert all time fields to ms, add, then split back. Day overflow\n  // propagates to shiftDays; sub-second precision is preserved (caller\n  // asking for hours/minutes/seconds/milliseconds gets ms-resolution\n  // arithmetic, which is the limit of these helpers — nanoseconds\n  // aren't supported here, only via Temporal.Duration's own add).\n  const MS_PER_DAY = 86_400_000;\n  const MS_PER_HOUR = 3_600_000;\n  const MS_PER_MINUTE = 60_000;\n  const MS_PER_SECOND = 1_000;\n\n  const totalMs = (v.hour ?? 0) * MS_PER_HOUR\n    + (v.minute ?? 0) * MS_PER_MINUTE\n    + (v.second ?? 0) * MS_PER_SECOND\n    + (v.millisecond ?? 0)\n    + msDelta;\n\n  // Split into day-overflow + within-day ms.\n  const dayOverflow = Math.floor(totalMs / MS_PER_DAY);\n  let withinDay = totalMs % MS_PER_DAY;\n  if (withinDay < 0) { withinDay += MS_PER_DAY; }\n\n  const hour = Math.floor(withinDay / MS_PER_HOUR);\n  const minute = Math.floor((withinDay % MS_PER_HOUR) / MS_PER_MINUTE);\n  const second = Math.floor((withinDay % MS_PER_MINUTE) / MS_PER_SECOND);\n  const millisecond = withinDay % MS_PER_SECOND;\n\n  const result: DateTimeFieldView = { ...v, hour, minute, second, millisecond };\n  if (dayOverflow !== 0) {\n    return shiftDays(result, dayOverflow);\n  }\n  return result;\n}\n\nexport function subtract(value: unknown, amount: number, unit: AddUnit): DateTimeFieldView {\n  return add(value, -amount, unit);\n}\n\n// Per-unit convenience wrappers — matches the grouping of\n// addYears / addMonths / ... / subtractNanoseconds. Nanosecond variants\n// aren't provided here because these helpers operate on field bags, and\n// the millisecond/microsecond/nanosecond split isn't preserved through\n// arithmetic at sub-millisecond precision the way Temporal.Duration's\n// own add preserves it. For ns-precision arithmetic, use Temporal.Duration\n// directly.\nexport const addYears = (v: unknown, n: number) => add(v, n, 'years');\nexport const addMonths = (v: unknown, n: number) => add(v, n, 'months');\nexport const addWeeks = (v: unknown, n: number) => add(v, n, 'weeks');\nexport const addDays = (v: unknown, n: number) => add(v, n, 'days');\nexport const addHours = (v: unknown, n: number) => add(v, n, 'hours');\nexport const addMinutes = (v: unknown, n: number) => add(v, n, 'minutes');\nexport const addSeconds = (v: unknown, n: number) => add(v, n, 'seconds');\nexport const addMilliseconds = (v: unknown, n: number) => add(v, n, 'milliseconds');\n\nexport const subtractYears = (v: unknown, n: number) => subtract(v, n, 'years');\nexport const subtractMonths = (v: unknown, n: number) => subtract(v, n, 'months');\nexport const subtractWeeks = (v: unknown, n: number) => subtract(v, n, 'weeks');\nexport const subtractDays = (v: unknown, n: number) => subtract(v, n, 'days');\nexport const subtractHours = (v: unknown, n: number) => subtract(v, n, 'hours');\nexport const subtractMinutes = (v: unknown, n: number) => subtract(v, n, 'minutes');\nexport const subtractSeconds = (v: unknown, n: number) => subtract(v, n, 'seconds');\nexport const subtractMilliseconds = (v: unknown, n: number) => subtract(v, n, 'milliseconds');\n\n// difference(): returns the count of `unit` boundaries between two values.\n// Pure-integer math, no Temporal.Duration involved. For sub-day\n// precision the result is an integer count of the requested unit (not\n// a Duration field bag) — matches the most common caller expectation\n// (\"how many days between these two dates?\").\nexport type DiffUnit = 'years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';\n\nexport function difference(a: unknown, b: unknown, unit: DiffUnit): number {\n  const av = asDateTime(a);\n  const bv = asDateTime(b);\n\n  // For day-granular units (years/months/weeks/days), compute via\n  // calendar arithmetic on the date fields. For sub-day units, compute\n  // via total-ms and divide.\n  if (unit === 'years') {\n    return bv.year! - av.year!;\n  }\n  if (unit === 'months') {\n    return (bv.year! * 12 + bv.month! - 1) - (av.year! * 12 + av.month! - 1);\n  }\n  if (unit === 'weeks' || unit === 'days') {\n    const aDays = toDayCount(av);\n    const bDays = toDayCount(bv);\n    const days = bDays - aDays;\n    return unit === 'weeks' ? Math.trunc(days / 7) : days;\n  }\n\n  // Sub-day units: total-ms math.\n  const MS_PER_HOUR = 3_600_000;\n  const MS_PER_MINUTE = 60_000;\n  const MS_PER_SECOND = 1_000;\n  const aMs = toTotalMs(av);\n  const bMs = toTotalMs(bv);\n  const diffMs = bMs - aMs;\n  switch (unit) {\n    case 'hours': return Math.trunc(diffMs / MS_PER_HOUR);\n    case 'minutes': return Math.trunc(diffMs / MS_PER_MINUTE);\n    case 'seconds': return Math.trunc(diffMs / MS_PER_SECOND);\n    case 'milliseconds': return diffMs;\n  }\n}\n\nfunction toDayCount(v: DateTimeFieldView): number {\n  // daysFromCivil (isoWeek.ts): the O(1) Hinnant day count, correct for\n  // negative years. The era term previously inlined here double-shifted\n  // pre-year-0 dates by one day (see shiftDays).\n  return daysFromCivil(v.year!, v.month!, v.day!);\n}\n\nfunction toTotalMs(v: DateTimeFieldView): number {\n  const MS_PER_DAY = 86_400_000;\n  const MS_PER_HOUR = 3_600_000;\n  const MS_PER_MINUTE = 60_000;\n  const MS_PER_SECOND = 1_000;\n  return toDayCount(v) * MS_PER_DAY\n    + (v.hour ?? 0) * MS_PER_HOUR\n    + (v.minute ?? 0) * MS_PER_MINUTE\n    + (v.second ?? 0) * MS_PER_SECOND\n    + (v.millisecond ?? 0);\n}\n\n// Per-unit difference wrappers — same convenience pattern as the add*\n// wrappers above.\nexport const differenceInYears = (a: unknown, b: unknown) => difference(a, b, 'years');\nexport const differenceInMonths = (a: unknown, b: unknown) => difference(a, b, 'months');\nexport const differenceInWeeks = (a: unknown, b: unknown) => difference(a, b, 'weeks');\nexport const differenceInDays = (a: unknown, b: unknown) => difference(a, b, 'days');\nexport const differenceInHours = (a: unknown, b: unknown) => difference(a, b, 'hours');\nexport const differenceInMinutes = (a: unknown, b: unknown) => difference(a, b, 'minutes');\nexport const differenceInSeconds = (a: unknown, b: unknown) => difference(a, b, 'seconds');\nexport const differenceInMilliseconds = (a: unknown, b: unknown) => difference(a, b, 'milliseconds');","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Recurrence engine. Deterministic RRULE-like\n// recurrence without pulling in a runtime dependency. Supports\n// secondly/minutely/hourly/daily/weekly/monthly/yearly frequencies,\n// interval, count, until, weekdays (incl. ordinal BYDAY like 2MO/-1FR\n// for monthly/yearly), monthDays (incl. negative end-of-month values),\n// exclusions, inclusions.\n//\n// RRULE interop: parseRRule() / formatRRule() convert to/from the\n// standard iCalendar RRULE string format (RFC 5545). Implemented\n// without depending on a RRULE library — the grammar is small enough\n// to handle inline. Not enforced (documented limitation, same as\n// before): BYSETPOS, BYHOUR, BYMINUTE, BYSECOND, WKST.\n\nimport { add } from './arithmetic.js';\nimport { compare } from './comparison.js';\nimport { daysFromCivil } from './isoWeek.js';\nimport { asDateFieldView } from './calendarUtils.js';\n\nexport type RecurrenceFrequency = 'secondly' | 'minutely' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly';\n\nexport interface WeekdayOrdinal {\n  // 2 = \"2nd such weekday of the month\", -1 = \"last such weekday\".\n  // Only meaningful with monthly/yearly frequency (RFC 5545 3.3.10:\n  // the numeric prefix is invalid with WEEKLY, where it's ignored).\n  ordinal: number;\n  weekday: number; // ISO 1=Mon..7=Sun\n}\n\nexport interface RecurrenceRule {\n  frequency: RecurrenceFrequency;\n  interval: number; // default 1 — omitted/null now means 1 (used to mean NaN)\n  count?: number; // max occurrences\n  until?: unknown; // Temporal value (or RRULE UNTIL date form) — recurrence ends after this\n  // For weekly: ISO weekdays to include (1=Mon..7=Sun). Empty = all.\n  byWeekday?: number[];\n  // Ordinal BYDAY parts (2MO, -1FR) parsed from RRULE strings — the nth\n  // weekday of each month/year. Matched in addition to plain byWeekday.\n  byWeekdayOrdinal?: WeekdayOrdinal[];\n  // For monthly/yearly: days of month to include (1-31, or negative\n  // for end-of-month: -1 = last day).\n  byMonthDay?: number[];\n  // For yearly: months to include (1-12).\n  byMonth?: number[];\n  // For weekly: which week of the year (1-53).\n  byWeek?: number[];\n  // Exclusions: dates to skip even if they match the rule.\n  exDates?: unknown[];\n  // Inclusions: dates to add even if they don't match the rule.\n  rDates?: unknown[];\n}\n\nexport interface RecurrenceIterator {\n  next(): { value: unknown; done: boolean } | { value: undefined; done: true };\n  previous(): { value: unknown; done: boolean } | { value: undefined; done: true };\n}\n\nfunction daysInMonthOf(year: number, month: number): number {\n  const LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n  const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n  return month === 2 && leap ? 29 : LENGTHS[month - 1]!;\n}\n\n// Day of week (ISO, 1=Mon..7=Sun) for a proleptic Gregorian y/m/d in\n// O(1): 1970-01-01 was a Thursday (dow 4), so dow = ((days + 3) mod 7) + 1.\nfunction weekdayOf(year: number, month: number, day: number): number {\n  const days = daysFromCivil(year, month, day);\n  return (((days + 3) % 7) + 7) % 7 + 1;\n}\n\n// Day-of-month of the `ordinal`-th `weekday` in the given month\n// (ordinal < 0 counts from the end, -1 = last). Returns null when no\n// such day exists in this month (e.g. 5th Monday of a 4-Monday month).\nfunction nthWeekdayDay(year: number, month: number, weekday: number, ordinal: number): number | null {\n  const last = daysInMonthOf(year, month);\n  if (ordinal > 0) {\n    const firstDow = weekdayOf(year, month, 1);\n    const first = 1 + ((weekday - firstDow + 7) % 7);\n    const day = first + (ordinal - 1) * 7;\n    return day <= last ? day : null;\n  }\n  const lastDow = weekdayOf(year, month, last);\n  const lastOccurrence = last - ((lastDow - weekday + 7) % 7);\n  const day = lastOccurrence + (ordinal + 1) * 7;\n  return day >= 1 ? day : null;\n}\n\n// Creates a recurrence iterator starting from `start`. The first call\n// to next() returns `start` itself (if it matches the rule); subsequent\n// calls return the next matching occurrence.\nexport function recurrence(start: unknown, rule: RecurrenceRule): RecurrenceIterator {\n  if (rule.count !== undefined && (!Number.isSafeInteger(rule.count) || rule.count < 1)) {\n    throw new RangeError(`temporal-fmt: recurrence rule count must be a positive safe integer (got ${String(rule.count)}).`);\n  }\n  // The interface documents interval as \"default 1\" — normalize it here\n  // so a rule object omitting it (or passing undefined) behaves as 1\n  // instead of poisoning every candidate with NaN arithmetic.\n  const interval = rule.interval !== undefined && rule.interval !== null\n    ? rule.interval\n    : 1;\n  if (!Number.isSafeInteger(interval) || interval < 1) {\n    throw new RangeError(`temporal-fmt: recurrence rule interval must be a positive safe integer (got ${String(rule.interval)}).`);\n  }\n  // Programmatic rules skip parseRRule's validation, so re-check the\n  // BY* lists here — garbage used to fall through to `?? 0` fallbacks\n  // in matches() and quietly match nothing (a rule like byMonthDay:[0]\n  // produced an empty sequence with no hint why). Real rules from\n  // parseRRule always pass.\n  if (rule.byMonthDay && rule.byMonthDay.some((d) => !Number.isSafeInteger(d) || d === 0 || d < -31 || d > 31)) {\n    throw new RangeError('temporal-fmt: recurrence rule byMonthDay entries must be nonzero integers in [-31, 31].');\n  }\n  if (rule.byWeekday && rule.byWeekday.some((d) => !Number.isSafeInteger(d) || d < 1 || d > 7)) {\n    throw new RangeError('temporal-fmt: recurrence rule byWeekday entries must be ISO weekdays 1 (Mon) through 7 (Sun).');\n  }\n  if (rule.byMonth && rule.byMonth.some((m) => !Number.isSafeInteger(m) || m < 1 || m > 12)) {\n    throw new RangeError('temporal-fmt: recurrence rule byMonth entries must be months 1 through 12.');\n  }\n  if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.some((o) =>\n    !Number.isSafeInteger(o.ordinal) || o.ordinal === 0 || o.ordinal < -53 || o.ordinal > 53 ||\n    !Number.isSafeInteger(o.weekday) || o.weekday < 1 || o.weekday > 7)) {\n    throw new RangeError('temporal-fmt: recurrence rule byWeekdayOrdinal entries need a nonzero ordinal in [-53, 53] and an ISO weekday 1-7.');\n  }\n  // Track past values for previous() — keeps a ring buffer of the last\n  // N occurrences so previous() can walk back without recomputing.\n  const history: unknown[] = [];\n  const MAX_HISTORY = 10_000;\n  let atEnd = false;\n  let atStart = true;\n\n  // Anchor: the ORIGINAL start, as a field view. Monthly/yearly\n  // candidates are derived from this (not from the previous occurrence)\n  // so the day-of-month never drifts: advancing Jan 31 by months used\n  // to go 01-31 → 02-28 → 03-28 → 04-28 …, permanently stuck on day 28\n  // after the first February clamp. Deriving each period's candidates\n  // from the anchor keeps the original day and skips (rather than\n  // clamps) periods that lack it — RFC 5545 semantics.\n  const anchor = asDateFieldView(start);\n  const originDayCount = daysFromCivil(anchor.year!, anchor.month!, anchor.day!);\n\n  // A plain field-bag start without dayOfWeek used to make every\n  // byWeekday-dependent rule silently produce nothing: matches()'s\n  // `?? 0` never equals a real weekday, and add()'s dayOfWeek\n  // recompute only refreshes a field that already exists — so the\n  // chain never picks one up (a Temporal start works because its\n  // dayOfWeek getter seeds it). Derive it once here so bag starts and\n  // Temporal starts behave identically for BYDAY rules.\n  let current: unknown = start;\n  if (rule.byWeekday && rule.byWeekday.length > 0 && typeof (start as { dayOfWeek?: unknown }).dayOfWeek !== 'number') {\n    current = { ...anchor, dayOfWeek: weekdayOf(anchor.year!, anchor.month!, anchor.day!) };\n  }\n  let count = 0;\n\n  function matches(value: unknown): boolean {\n    // The `?? 0` / `?? []` fallbacks on the lines flagged below are\n    // defensive only and unreachable through the public API: recurrence()\n    // rejects starts missing year/month/day, every generated candidate is\n    // a full field view (fillNextPeriod sets dayOfWeek; add()'s\n    // recomputeDayOfWeek refreshes one seeded at the top), and the\n    // byWeekday gate above runs before plainOk is ever evaluated — so\n    // dayOfWeek is defined whenever `?? 0` would fire, and year/month/day\n    // are always present. The lines they sit on are otherwise live and\n    // test-covered; only the fallback arms need the ignore.\n    const v = value as { dayOfWeek?: number; year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number };\n    if (rule.byWeekday && rule.byWeekday.length > 0) {\n      // `?? 0` is defensive only since the dayOfWeek seeding above: every\n      // value a byWeekday rule tests (seeded start, generated candidates)\n      // carries a number.\n      /* c8 ignore next @preserve */\n      if (!rule.byWeekday.includes(v.dayOfWeek ?? 0)) return false;\n    }\n    if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.length > 0\n      && (rule.frequency === 'monthly' || rule.frequency === 'yearly')) {\n      // Union with the plain-byWeekday check above per RFC: any BYDAY\n      // entry matching is enough. (Monthly/yearly candidates are\n      // generated from the ordinal itself, so this re-check is about\n      // rules that mix plain and ordinal entries.)\n      /* c8 ignore next @preserve */\n      const plainOk = !!rule.byWeekday && rule.byWeekday.length > 0 && rule.byWeekday.includes(v.dayOfWeek ?? 0);\n      /* c8 ignore next @preserve */\n      const ordinalOk = (rule.byWeekdayOrdinal ?? []).some((o) =>\n      /* c8 ignore next @preserve */\n        nthWeekdayDay(v.year ?? 0, v.month ?? 0, o.weekday, o.ordinal) === (v.day ?? 0));\n      if (!plainOk && !ordinalOk) return false;\n    }\n    if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n      // Negative values count back from the end of the month\n      // (-1 = last day). They used to be accepted by parseRRule but\n      // never matched anything — a day-of-month is never negative.\n      /* c8 ignore next @preserve */\n      const day = v.day ?? 0;\n      /* c8 ignore next @preserve */\n      const last = daysInMonthOf(v.year ?? 0, v.month ?? 0);\n      // `?? []` is defensive only: the enclosing if guards byMonthDay\n      // non-empty.\n      /* c8 ignore next @preserve */\n      const hit = (rule.byMonthDay ?? []).some((d) => (d > 0 ? d === day : d + last + 1 === day));\n      if (!hit) return false;\n    }\n    if (rule.byMonth && rule.byMonth.length > 0) {\n      /* c8 ignore next @preserve */\n      if (!rule.byMonth.includes(v.month ?? 0)) return false;\n    }\n    if (rule.exDates && rule.exDates.some((d) => compare(d, value) === 0)) return false;\n    return true;\n  }\n\n  // ---- Monthly/yearly candidate generation ------------------------------\n  // Each interval step yields one period (a month, or a year with its\n  // byMonth months). The period's candidate days are:\n  //   - byMonthDay values, if present (negatives resolved to real days);\n  //   - else ordinal BYDAY days, if present;\n  //   - else the anchor's day (periods lacking it yield nothing).\n  // Candidates carry the anchor's time-of-day and a recomputed\n  // dayOfWeek, and are yielded in chronological order.\n  let pending: unknown[] = [];\n  // Starts at 0: the start's OWN period gets generated first (RFC —\n  // FREQ=MONTHLY;BYMONTHDAY=15 from Jan 1 yields Jan 15 before Feb 15),\n  // with candidates at or before `start` skipped by nextMatch.\n  let periodIndex = 0;\n\n  function fillNextPeriod(): void {\n    // k starts at 0 (the start's own period) and increments AFTER use,\n    // so every period from the anchor's onward is generated exactly once.\n    const k = periodIndex;\n    periodIndex++;\n    let year: number;\n    let months: number[];\n    if (rule.frequency === 'monthly') {\n      const totalMonths = anchor.year! * 12 + anchor.month! - 1 + k * interval;\n      year = Math.floor(totalMonths / 12);\n      months = [totalMonths - year * 12 + 1];\n    } else {\n      year = anchor.year! + k * interval;\n      months = rule.byMonth && rule.byMonth.length > 0\n        ? [...rule.byMonth].sort((a, b) => a - b)\n        : [anchor.month!];\n    }\n    const days: Array<{ month: number; day: number }> = [];\n    for (const m of months) {\n      const last = daysInMonthOf(year, m);\n      if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n        for (const d of rule.byMonthDay) {\n          const real = d > 0 ? d : last + 1 + d;\n          if (real >= 1 && real <= last) days.push({ month: m, day: real });\n        }\n      } else if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.length > 0) {\n        for (const o of rule.byWeekdayOrdinal) {\n          const real = nthWeekdayDay(year, m, o.weekday, o.ordinal);\n          if (real !== null) days.push({ month: m, day: real });\n        }\n      } else {\n        if (anchor.day! <= last) days.push({ month: m, day: anchor.day! });\n      }\n    }\n    days.sort((a, b) => a.month - b.month || a.day - b.day);\n    pending = days.map(({ month, day }) => ({\n      ...anchor,\n      year,\n      month,\n      day,\n      dayOfWeek: weekdayOf(year, month, day),\n    }));\n  }\n\n  // Steps to the next candidate after `value`, by the frequency's own\n  // granularity:\n  //  - monthly/yearly: pop the period queue (refilling as needed);\n  //  - weekly + BYDAY: one day at a time (stepping whole weeks preserves\n  //    the weekday, so a start not already on a BYDAY weekday could\n  //    never match — FREQ=WEEKLY;BYDAY=SA from a Monday used to produce\n  //    an empty sequence), gated to the interval's week windows;\n  //  - everything else: one `interval` step from the current value, the\n  //    same way the original implementation did.\n  function nextMatch(value: unknown): { value: unknown; found: boolean } {\n    let candidate = value;\n    let safetyCounter = 0;\n    const daywise = rule.frequency === 'weekly' && !!rule.byWeekday && rule.byWeekday.length > 0;\n    const periodwise = rule.frequency === 'monthly' || rule.frequency === 'yearly';\n    const unit = rule.frequency === 'secondly' ? 'seconds'\n      : rule.frequency === 'minutely' ? 'minutes'\n      : rule.frequency === 'hourly' ? 'hours'\n      : rule.frequency === 'daily' ? 'days'\n      : 'weeks';\n\n    while (true) {\n      // Count EVERY iteration, including the two `continue` paths below\n      // (empty periods, candidates at/before the start): those used to\n      // skip the increment, so a rule whose every period is empty — e.g.\n      // monthly BYDAY=-6MO, which no month can ever satisfy — spun the\n      // loop forever. The cap is a total-work bound per next() call, not\n      // a candidates-produced bound.\n      safetyCounter++;\n      if (safetyCounter > 2000) {\n        // Defensive — if the rule is so restrictive no match exists\n        // within 2000 steps, give up rather than spin forever. The\n        // caller must treat this as \"no more occurrences\", not as a\n        // real match — returning the unmatched candidate here used to\n        // get handed back to next()'s caller as if it were valid.\n        // (1000 previously; doubled because day-granular stepping for\n        // weekly BYDAY rules legitimately needs up to 7 steps per\n        // occurrence, and monthly skips can chain across short months.)\n        atEnd = true;\n        return { value: candidate, found: false };\n      }\n      if (daywise) {\n        candidate = add(candidate, 1, 'days');\n        // INTERVAL > 1 on a weekly BYDAY rule: only weeks that are a\n        // whole multiple of `interval` away from the anchor's week emit\n        // occurrences (WKST unsupported — the window anchors on the\n        // start's own day).\n        if (interval > 1) {\n          const v = asDateFieldView(candidate);\n          const dayCount = daysFromCivil(v.year!, v.month!, v.day!);\n          if (Math.floor((dayCount - originDayCount) / 7) % interval !== 0) continue;\n        }\n      } else if (periodwise) {\n        if (pending.length === 0) {\n          fillNextPeriod();\n          if (pending.length === 0) continue; // period had no valid days\n        }\n        candidate = pending.shift()!;\n        // The start's own period can contain candidate days at or before\n        // the start itself (BYMONTHDAY=15 generating Jan 15 for a Jan 1\n        // start, where Jan 1..14 precede it) — those aren't occurrences.\n        if (compare(candidate, value) <= 0) continue;\n      } else {\n        candidate = add(candidate, interval, unit as Parameters<typeof add>[2]);\n      }\n      if (rule.until && compare(candidate, rule.until) > 0) {\n        atEnd = true;\n        return { value: candidate, found: false };\n      }\n      if (matches(candidate)) break;\n    }\n    return { value: candidate, found: true };\n  }\n\n  function recordHistory(value: unknown): void {\n    history.push(value);\n    if (history.length > MAX_HISTORY) history.shift();\n  }\n\n  return {\n    next() {\n      if (atEnd) return { value: undefined, done: true };\n      if (atStart) {\n        atStart = false;\n        if (matches(current)) {\n          count++;\n          if (rule.count !== undefined && count >= rule.count) atEnd = true;\n          if (rule.until && compare(current, rule.until) > 0) {\n            atEnd = true;\n            return { value: undefined, done: true };\n          }\n          // Include rDates that match the current value.\n          recordHistory(current);\n          return { value: current, done: false };\n        }\n        // If start doesn't match, advance to first match.\n        const advanced = nextMatch(current);\n        if (!advanced.found) return { value: undefined, done: true };\n        current = advanced.value;\n        count++;\n        if (rule.count !== undefined && count >= rule.count) atEnd = true;\n        recordHistory(current);\n        return { value: current, done: false };\n      }\n      const advanced = nextMatch(current);\n      if (!advanced.found) return { value: undefined, done: true };\n      current = advanced.value;\n      count++;\n      if (rule.count !== undefined && count >= rule.count) atEnd = true;\n      recordHistory(current);\n      return { value: current, done: false };\n    },\n    previous() {\n      if (history.length === 0) return { value: undefined, done: true };\n      const v = history.pop()!;\n      return { value: v, done: false };\n    },\n  };\n}\n\n// Take N occurrences from a recurrence iterator.\nexport function take(iter: RecurrenceIterator, n: number): unknown[] {\n  const result: unknown[] = [];\n  for (let i = 0; i < n; i++) {\n    const r = iter.next();\n    if (r.done) break;\n    result.push(r.value);\n  }\n  return result;\n}\n\n// Upper bound on how many occurrences skip() will collect after its\n// skip phase. skip() used to call take(iter, Number.MAX_SAFE_INTEGER),\n// and an iterator over an unbounded rule (no count, no until — e.g.\n// { frequency: 'daily', interval: 1 }) never returns done: next() always\n// has another day. The call then looped forever, pushing into a result\n// array until the process OOM'd. Same cap style as businessCalendar.ts.\nconst MAX_SKIP_COLLECTION = 100_000;\n// Upper bound on skip()'s skip phase too: skip(iter, 1e9) on an\n// unbounded rule used to burn a billion next() calls before the\n// collection cap was ever reached.\nconst MAX_SKIP_STEPS = 1_000_000;\n\n// Skip N occurrences from a recurrence iterator, returning the ones\n// that follow. Throws a RangeError when the iterator is still producing\n// occurrences after MAX_SKIP_COLLECTION — that means the rule is\n// unbounded (no count/until) and \"everything after the skip\" has no\n// finite answer.\nexport function skip(iter: RecurrenceIterator, n: number): unknown[] {\n  for (let i = 0; i < n; i++) {\n    if (i >= MAX_SKIP_STEPS) {\n      throw new RangeError(\n        `temporal-fmt: skip() was asked to skip more than ${MAX_SKIP_STEPS} occurrences — that's not a bounded operation; use take() on a count/until-bounded rule instead.`\n      );\n    }\n    const r = iter.next();\n    if (r.done) break;\n  }\n  const result: unknown[] = [];\n  while (result.length < MAX_SKIP_COLLECTION) {\n    const r = iter.next();\n    if (r.done) return result;\n    result.push(r.value);\n  }\n  throw new RangeError(\n    `temporal-fmt: skip() collected ${MAX_SKIP_COLLECTION} occurrences and the rule is still ` +\n    `producing — add a count or until to the rule, or use take(iter, n) for a bounded read.`\n  );\n}\n\n// All occurrences between two dates (inclusive of start, exclusive of end).\nexport function between(start: unknown, rule: RecurrenceRule, rangeStart: unknown, rangeEnd: unknown): unknown[] {\n  const iter = recurrence(start, rule);\n  const result: unknown[] = [];\n  // Traversal cap: a fine-grained rule anchored far before rangeEnd\n  // (e.g. daily from year -2000) walks every occurrence since `start`\n  // — bounded work instead of an unbounded loop, same style as skip().\n  const MAX_TRAVERSAL = 1_000_000;\n  let traversed = 0;\n  while (true) {\n    if (traversed++ > MAX_TRAVERSAL) {\n      throw new RangeError(\n        `temporal-fmt: between() walked more than ${MAX_TRAVERSAL} occurrences without reaching rangeEnd — ` +\n        `pass a start closer to the range, or bound the rule with count/until.`\n      );\n    }\n    const r = iter.next();\n    if (r.done) break;\n    if (compare(r.value, rangeEnd) >= 0) break;\n    if (compare(r.value, rangeStart) >= 0) result.push(r.value);\n  }\n  return result;\n}\n\n// Parses an RRULE UNTIL value (RFC 5545 date \"20240110\" or UTC\n// date-time \"20240110T153000Z\") into a comparable field bag. Stored raw\n// previously, so iterating a parsed rule threw \"expected a date-carrying\n// Temporal value\" on the first next() — a parsed RRULE was unusable\n// with UNTIL, the single most common termination form.\nfunction parseUntil(value: string): { year: number; month: number; day: number; hour?: number; minute?: number; second?: number } {\n  const m = /^(\\d{4})(\\d{2})(\\d{2})(?:T(\\d{2})(\\d{2})(\\d{2})Z?)?$/.exec(value.trim());\n  if (!m) {\n    throw new RangeError(\n      `temporal-fmt: RRULE UNTIL must be a date (\"20240110\") or UTC date-time (\"20240110T153000Z\") — got \"${value}\".`\n    );\n  }\n  const year = Number(m[1]);\n  const month = Number(m[2]);\n  const day = Number(m[3]);\n  if (month < 1 || month > 12 || day < 1 || day > 31) {\n    throw new RangeError(`temporal-fmt: RRULE UNTIL carries an out-of-range date \"${value}\".`);\n  }\n  const hour = m[4] !== undefined ? Number(m[4]) : undefined;\n  const minute = m[5] !== undefined ? Number(m[5]) : undefined;\n  const second = m[6] !== undefined ? Number(m[6]) : undefined;\n  if (hour !== undefined && (hour > 23 || minute! > 59 || second! > 59)) {\n    throw new RangeError(`temporal-fmt: RRULE UNTIL carries an out-of-range time \"${value}\".`);\n  }\n  return { year, month, day, hour, minute, second };\n}\n\n// Parses an RRULE string like \"FREQ=DAILY;INTERVAL=2;COUNT=5\" into a\n// RecurrenceRule. Doesn't support every RRULE feature (BYSETPOS,\n// BYHOUR, BYMINUTE, BYSECOND, WKST are not enforced by the recurrence\n// iterator above), but covers the common cases.\nexport function parseRRule(input: string): RecurrenceRule {\n  const parts = input.trim().toUpperCase().replace(/^RRULE:/, '').split(';');\n  const rule: RecurrenceRule = { frequency: 'daily', interval: 1 };\n  const frequencies: ReadonlySet<string> = new Set([\n    'SECONDLY', 'MINUTELY', 'HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY',\n  ]);\n  for (const part of parts) {\n    if (!part) continue;\n    const eq = part.indexOf('=');\n    if (eq < 0) continue;\n    const key = part.slice(0, eq);\n    const value = part.slice(eq + 1);\n    switch (key) {\n      case 'FREQ':\n        if (!frequencies.has(value)) {\n          throw new RangeError(`temporal-fmt: unsupported RRULE frequency \"${value}\".`);\n        }\n        rule.frequency = value.toLowerCase() as RecurrenceFrequency;\n        break;\n      case 'INTERVAL': {\n        const interval = Number(value);\n        if (!Number.isSafeInteger(interval) || interval < 1) {\n          throw new RangeError(`temporal-fmt: RRULE INTERVAL must be a positive safe integer (got \"${value}\").`);\n        }\n        rule.interval = interval;\n        break;\n      }\n      case 'COUNT': {\n        const count = Number(value);\n        if (!Number.isSafeInteger(count) || count < 1) {\n          throw new RangeError(`temporal-fmt: RRULE COUNT must be a positive safe integer (got \"${value}\").`);\n        }\n        rule.count = count;\n        break;\n      }\n      case 'UNTIL':\n        rule.until = parseUntil(value);\n        break;\n      case 'BYDAY': {\n        const WEEKDAY_MAP: Record<string, number> = { MO: 1, TU: 2, WE: 3, TH: 4, FR: 5, SA: 6, SU: 7 };\n        const plain: number[] = [];\n        const ordinals: WeekdayOrdinal[] = [];\n        for (const d of value.split(',')) {\n          // RFC 5545 ordinals run -53..53 — two digits are legal, so the\n          // pattern must accept them (it used to cap at one digit, which\n          // made valid rules like BYDAY=53MO throw \"invalid weekday\" and\n          // pushed out-of-range ordinals past the range check below\n          // instead of reaching it).\n          const m = d.match(/^([+-]?\\d{1,2})?([A-Z]{2})$/);\n          // Unknown tokens used to map to 0 silently — a typo'd BYDAY\n          // entry quietly matched nothing instead of failing loudly.\n          if (!m || WEEKDAY_MAP[m[2]!] === undefined) {\n            throw new RangeError(`temporal-fmt: RRULE BYDAY contains an invalid weekday \"${d}\".`);\n          }\n          const weekday = WEEKDAY_MAP[m[2]!]!;\n          if (m[1] !== undefined) {\n            const ordinal = Number(m[1]);\n            if (!Number.isSafeInteger(ordinal) || ordinal === 0 || ordinal < -53 || ordinal > 53) {\n              throw new RangeError(`temporal-fmt: RRULE BYDAY ordinal out of range in \"${d}\".`);\n            }\n            ordinals.push({ ordinal, weekday });\n          } else {\n            plain.push(weekday);\n          }\n        }\n        rule.byWeekday = plain;\n        if (ordinals.length > 0) rule.byWeekdayOrdinal = ordinals;\n        break;\n      }\n      case 'BYMONTHDAY': {\n        const values = value.split(',').map(Number);\n        if (values.some((day) => !Number.isInteger(day) || day === 0 || day < -31 || day > 31)) {\n          throw new RangeError(`temporal-fmt: RRULE BYMONTHDAY contains an out-of-range value.`);\n        }\n        rule.byMonthDay = values;\n        break;\n      }\n      case 'BYMONTH': {\n        const values = value.split(',').map(Number);\n        if (values.some((month) => !Number.isInteger(month) || month < 1 || month > 12)) {\n          throw new RangeError(`temporal-fmt: RRULE BYMONTH contains an out-of-range value.`);\n        }\n        rule.byMonth = values;\n        break;\n      }\n    }\n  }\n  return rule;\n}\n\nexport function formatRRule(rule: RecurrenceRule): string {\n  const parts: string[] = [`FREQ=${rule.frequency.toUpperCase()}`];\n  // Programmatic rules may omit interval (documented default: 1) — emitting\n  // \"INTERVAL=undefined\" for them produced output that parseRRule itself\n  // rejects, breaking the round-trip. Omit it unless it's an explicit != 1.\n  if (rule.interval !== undefined && rule.interval !== 1) parts.push(`INTERVAL=${rule.interval}`);\n  if (rule.count !== undefined) parts.push(`COUNT=${rule.count}`);\n  if (rule.until !== undefined) parts.push(`UNTIL=${String(rule.until)}`);\n  const WEEKDAY_NAMES: Record<number, string> = { 1: 'MO', 2: 'TU', 3: 'WE', 4: 'TH', 5: 'FR', 6: 'SA', 7: 'SU' };\n  if (rule.byWeekday && rule.byWeekday.length > 0) {\n    parts.push(`BYDAY=${rule.byWeekday.map((d) => WEEKDAY_NAMES[d] ?? String(d)).join(',')}`);\n  }\n  if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.length > 0) {\n    const rendered = rule.byWeekdayOrdinal.map((o) => `${o.ordinal}${WEEKDAY_NAMES[o.weekday] ?? String(o.weekday)}`);\n    // Merge into the plain BYDAY part when both exist (RRULE carries\n    // one combined list).\n    if (rule.byWeekday && rule.byWeekday.length > 0) {\n      parts[parts.length - 1] = `BYDAY=${[...rule.byWeekday.map((d) => WEEKDAY_NAMES[d] ?? String(d)), ...rendered].join(',')}`;\n    } else {\n      parts.push(`BYDAY=${rendered.join(',')}`);\n    }\n  }\n  if (rule.byMonthDay && rule.byMonthDay.length > 0) parts.push(`BYMONTHDAY=${rule.byMonthDay.join(',')}`);\n  if (rule.byMonth && rule.byMonth.length > 0) parts.push(`BYMONTH=${rule.byMonth.join(',')}`);\n  return parts.join(';');\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// business calendar stuff — configurable weekends, holiday sets, observed\n// holidays, working hours, half days if you need em. holiday checking\n// itself is handed off to a HolidayCalendar (holidays.ts) so this file\n// can just worry about the weekday-vs-weekend part\n\nimport { add } from './arithmetic.js';\nimport { dayOfWeekFromCivil } from './isoWeek.js';\nimport type { HolidayCalendar } from './holidays.js';\n\nexport interface BusinessCalendarOptions {\n  // defaults to [6, 7] (Sat/Sun). ISO weekday numbers, 1-7\n  weekend?: number[];\n  // pass a holiday calendar if you want holidays factored in too —\n  // skip it and you just get weekend logic\n  holidays?: HolidayCalendar;\n  // hours per weekday, 1=Mon..7=Sun. defaults to 8hrs weekdays, 0 weekend.\n  // addBusinessDays() uses this for partial-day math\n  workingHours?: Record<number, number>;\n  // which weekdays get reduced hours. empty by default\n  halfDays?: number[];\n}\n\nexport interface BusinessCalendar {\n  weekend: Set<number>;\n  holidays?: HolidayCalendar;\n  workingHours: Record<number, number>;\n  halfDays: Set<number>;\n}\n\nexport function createBusinessCalendar(options: BusinessCalendarOptions = {}): BusinessCalendar {\n  const weekend = new Set(options.weekend ?? [6, 7]);\n  // gotta copy this before filling in defaults — used to write the missing\n  // weekday entries straight into options.workingHours, which mutated\n  // the caller's actual object. so someone's { 1: 6 } would silently grow\n  // keys 2-7 just from \"creating\" a calendar, and if they reused that\n  // object across calendars, the first one's defaults leaked into all of them\n  const workingHours: Record<number, number> = { ...(options.workingHours ?? {}) };\n  for (let i = 1; i <= 7; i++) {\n    if (workingHours[i] === undefined) {\n      workingHours[i] = weekend.has(i) ? 0 : 8;\n    }\n  }\n  return {\n    weekend,\n    holidays: options.holidays,\n    workingHours,\n    halfDays: new Set(options.halfDays ?? []),\n  };\n}\n\nexport function isBusinessDay(cal: BusinessCalendar, value: unknown): boolean {\n  const v = value as { dayOfWeek?: number; year?: number; month?: number; day?: number };\n  // add() over in arithmetic.ts doesn't touch dayOfWeek — it just hands back\n  // whatever dayOfWeek the input had, stale or not. so recompute it from\n  // year/month/day whenever we've got those, don't trust the cached value\n  let dow = v.dayOfWeek;\n  if (typeof v.year === 'number' && typeof v.month === 'number' && typeof v.day === 'number') {\n    // dayOfWeekFromCivil: O(1) proleptic-Gregorian weekday. The old\n    // Date.UTC remapping of years 0-99 to 1900-1999 made a genuine\n    // Sunday PlainDate('0050-01-02') count as a business day here —\n    // and this recomputation OVERWRITES the value's own correct\n    // dayOfWeek, so real Temporal input was affected too.\n    dow = dayOfWeekFromCivil(v.year, v.month, v.day);\n  }\n  if (typeof dow !== 'number') {\n    throw new Error('temporal-fmt: isBusinessDay() needs a value with dayOfWeek (or year/month/day to compute it).');\n  }\n  if (cal.weekend.has(dow)) return false;\n  if (cal.holidays && cal.holidays.isHoliday(value)) return false;\n  return true;\n}\n\nexport function nextBusinessDay(cal: BusinessCalendar, value: unknown): unknown {\n  let candidate = add(value, 1, 'days');\n  // keep going till we hit a business day. capped at 14 just to be safe —\n  // a week is really the natural bound even with weekend + holidays combined\n  for (let i = 0; i < 14; i++) {\n    if (isBusinessDay(cal, candidate)) return candidate;\n    candidate = add(candidate, 1, 'days');\n  }\n  throw new Error('temporal-fmt: nextBusinessDay() gave up after 14 days — likely a misconfigured calendar (e.g. all days are weekends or holidays).');\n}\n\nexport function previousBusinessDay(cal: BusinessCalendar, value: unknown): unknown {\n  let candidate = add(value, -1, 'days');\n  for (let i = 0; i < 14; i++) {\n    if (isBusinessDay(cal, candidate)) return candidate;\n    candidate = add(candidate, -1, 'days');\n  }\n  throw new Error('temporal-fmt: previousBusinessDay() gave up after 14 days — likely a misconfigured calendar.');\n}\n\nconst MAX_BUSINESS_DAY_TRAVERSAL = 100_000;\n\nfunction assertBusinessDayCount(days: number): void {\n  if (!Number.isSafeInteger(days)) {\n    throw new RangeError(\n      `temporal-fmt: business-day count must be a finite safe integer (got ${days}).`,\n    );\n  }\n}\n\nfunction compareDateFields(a: unknown, b: unknown): number {\n  const av = a as { year: number; month: number; day: number };\n  const bv = b as { year: number; month: number; day: number };\n  const ay = av.year * 10000 + av.month * 100 + av.day;\n  const by = bv.year * 10000 + bv.month * 100 + bv.day;\n  return ay - by;\n}\n\nexport function addBusinessDays(cal: BusinessCalendar, value: unknown, days: number): unknown {\n  assertBusinessDayCount(days);\n  if (days === 0) return value;\n  const sign = days > 0 ? 1 : -1;\n  const absDays = Math.abs(days);\n  if (absDays > MAX_BUSINESS_DAY_TRAVERSAL) {\n    throw new RangeError(\n      `temporal-fmt: addBusinessDays() exceeded the ${MAX_BUSINESS_DAY_TRAVERSAL}-day limit.`,\n    );\n  }\n  let candidate = value;\n  for (let i = 0; i < absDays; i++) {\n    candidate = sign > 0 ? nextBusinessDay(cal, candidate) : previousBusinessDay(cal, candidate);\n  }\n  return candidate;\n}\n\nexport function subtractBusinessDays(cal: BusinessCalendar, value: unknown, days: number): unknown {\n  assertBusinessDayCount(days);\n  return addBusinessDays(cal, value, -days);\n}\n\nexport function differenceInBusinessDays(cal: BusinessCalendar, a: unknown, b: unknown): number {\n  const rawDirection = compareDateFields(b, a);\n  if (rawDirection === 0) return 0;\n\n  const direction = rawDirection > 0 ? 1 : -1;\n  let candidate = a;\n  let count = 0;\n  let traversedDays = 0;\n\n  while (compareDateFields(candidate, b) !== 0) {\n    candidate = add(candidate, direction, 'days');\n    traversedDays++;\n    if (traversedDays > MAX_BUSINESS_DAY_TRAVERSAL) {\n      throw new RangeError(\n        `temporal-fmt: differenceInBusinessDays() exceeded the ${MAX_BUSINESS_DAY_TRAVERSAL}-day traversal limit.`,\n      );\n    }\n    if (isBusinessDay(cal, candidate)) count += direction;\n  }\n\n  return count;\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// holiday framework. core just gives you the abstraction — actual\n// country-specific holiday lists live outside this package, could be\n// their own ecosystem packages built on top. a holiday calendar is\n// basically a date -> boolean function (\"is this a holiday\") plus some\n// iteration helpers (nextHoliday, previousHoliday, holidaysBetween)\n\nimport { add } from './arithmetic.js';\nimport { compare } from './comparison.js';\n\nexport interface HolidayCalendar {\n  isHoliday(value: unknown): boolean;\n  // everything in [start, end], inclusive on both ends\n  holidaysBetween(start: unknown, end: unknown): unknown[];\n}\n\nexport interface HolidaySpec {\n  // for fixed-date holidays, like Jan 1 for New Year's\n  month?: number;\n  day?: number;\n  // for the floating ones — give it a year, get back { month, day } for\n  // that year. this is how you'd do \"last Monday of May\" type rules\n  compute?: (year: number) => { month: number; day: number };\n  // just a name, mostly for debugging\n  name?: string;\n}\n\n// cap on how many years holidaysBetween() will walk through. it's a\n// year-by-year loop with no bounds checking on the inputs, so someone\n// passing year 1 to year 300000 would've made it iterate (and cache!)\n// every single year in between. either an accident or someone being\n// hostile, either way that used to just hang the process. 5000 matches\n// the same walk-cap businessCalendar.ts and recurrence.ts already use\nconst MAX_HOLIDAY_YEAR_RANGE = 5_000;\n\nexport function createHolidayCalendar(specs: HolidaySpec[]): HolidayCalendar {\n  // computes a year's holiday list lazily, then caches it\n  const cache = new Map<number, Array<{ month: number; day: number; name?: string }>>();\n  // The per-instance cache never evicted: isHoliday/nextHoliday/\n  // previousHoliday over N distinct years grew N entries forever (a\n  // calendar asked for many years — hostile or just long-lived — held\n  // every year's list in memory permanently). FIFO-evict past the cap,\n  // same convention as the library's other bounded caches. Rebuilding\n  // an evicted year is O(specs), which is the same cost the first\n  // computation already paid.\n  const MAX_CACHE_YEARS = 1000;\n  function forYear(year: number) {\n    let list = cache.get(year);\n    if (list) return list;\n    if (cache.size >= MAX_CACHE_YEARS) {\n      const oldest = cache.keys().next().value;\n      if (oldest !== undefined) cache.delete(oldest);\n    }\n    list = specs.map((s) => {\n      let md: { month: number; day: number };\n      if (s.compute) {\n        md = s.compute(year);\n      } else {\n        md = { month: s.month!, day: s.day! };\n      }\n      return { ...md, name: s.name };\n    });\n    cache.set(year, list);\n    return list;\n  }\n  return {\n    isHoliday(value: unknown) {\n      const v = value as { year?: number; month?: number; day?: number };\n      if (typeof v.year !== 'number' || typeof v.month !== 'number' || typeof v.day !== 'number') {\n        throw new Error('temporal-fmt: isHoliday() needs a value with year/month/day.');\n      }\n      const list = forYear(v.year);\n      return list.some((h) => h.month === v.month && h.day === v.day);\n    },\n    holidaysBetween(start: unknown, end: unknown) {\n      const sv = start as { year: number; month: number; day: number };\n      const ev = end as { year: number; month: number; day: number };\n      if (typeof sv?.year !== 'number' || typeof ev?.year !== 'number') {\n        throw new Error('temporal-fmt: holidaysBetween() needs start/end values with year/month/day.');\n      }\n      if (ev.year - sv.year > MAX_HOLIDAY_YEAR_RANGE) {\n        throw new RangeError(\n          `temporal-fmt: holidaysBetween() year range (${sv.year}–${ev.year}) exceeds the ` +\n          `${MAX_HOLIDAY_YEAR_RANGE}-year limit. Split the query into smaller ranges.`\n        );\n      }\n      const result: unknown[] = [];\n      for (let y = sv.year; y <= ev.year; y++) {\n        const list = forYear(y);\n        for (const h of list) {\n          const date = { year: y, month: h.month, day: h.day };\n          if (compare(date, sv) >= 0 && compare(date, ev) <= 0) {\n            result.push({ year: y, month: h.month, day: h.day });\n          }\n        }\n      }\n      return result;\n    },\n  };\n}\n\n// finds the next holiday strictly after `value`. gives up and returns\n// undefined if nothing shows up within 5 years — sanity cap so this\n// can't loop forever on an empty calendar\nexport function nextHoliday(cal: HolidayCalendar, value: unknown): unknown | undefined {\n  let candidate = add(value, 1, 'days');\n  for (let i = 0; i < 365 * 5; i++) {\n    if (cal.isHoliday(candidate)) return candidate;\n    candidate = add(candidate, 1, 'days');\n  }\n  return undefined;\n}\n\nexport function previousHoliday(cal: HolidayCalendar, value: unknown): unknown | undefined {\n  let candidate = add(value, -1, 'days');\n  for (let i = 0; i < 365 * 5; i++) {\n    if (cal.isHoliday(candidate)) return candidate;\n    candidate = add(candidate, -1, 'days');\n  }\n  return undefined;\n}\n\n// holidaysBetween already exists as a method on HolidayCalendar (above),\n// this is just a standalone version so you don't have to type cal.holidaysBetween\nexport function holidaysBetween(cal: HolidayCalendar, start: unknown, end: unknown): unknown[] {\n  return cal.holidaysBetween(start, end);\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Time-zone subsystem. Wraps Temporal.ZonedDateTime's\n// timezone introspection surface in temporal-fmt's field-based convention.\n// Includes disambiguation modes (compatible/earlier/later/reject) for\n// DST gaps and overlaps, plus transition queries (getNextTransition,\n// getPreviousTransition, getTransitions).\n\nimport { getTemporal, type TemporalNamespace } from './temporalProvider.js';\nimport { add } from './arithmetic.js';\n\nexport type DisambiguationMode = 'compatible' | 'earlier' | 'later' | 'reject';\n\nexport interface ResolveZonedOptions {\n  disambiguation?: DisambiguationMode;\n  overflow?: 'constrain' | 'reject';\n  offset?: 'use' | 'ignore' | 'prefer' | 'reject';\n}\n\n// Resolves a wall-clock time in a timezone, applying disambiguation\n// for DST gaps and overlaps.\nexport function resolveZoned(\n  fields: { year: number; month: number; day: number; hour?: number; minute?: number; second?: number; millisecond?: number; microsecond?: number; nanosecond?: number },\n  timeZone: string,\n  options: ResolveZonedOptions = {},\n): unknown {\n  const temporal = getTemporal();\n  const disambiguation = options.disambiguation ?? 'compatible';\n  const overflow = options.overflow ?? 'constrain';\n  // Cast options to a permissive record — Temporal.ZonedDateTime.from\n  // accepts disambiguation/offset options, but the existing\n  // TemporalFactory.from() signature in temporalProvider.ts is narrower.\n  // The runtime accepts the wider shape; this cast bypasses the type\n  // narrowing without changing runtime behavior.\n  const fromOptions = {\n    overflow,\n    disambiguation,\n    offset: options.offset ?? 'prefer',\n  } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1];\n  try {\n    return temporal.ZonedDateTime.from(\n      {\n        year: fields.year,\n        month: fields.month,\n        day: fields.day,\n        hour: fields.hour ?? 0,\n        minute: fields.minute ?? 0,\n        second: fields.second ?? 0,\n        millisecond: fields.millisecond ?? 0,\n        microsecond: fields.microsecond ?? 0,\n        nanosecond: fields.nanosecond ?? 0,\n        timeZone,\n      },\n      fromOptions,\n    );\n  } catch (err) {\n    // Surface DST gap / overlap errors with a clearer message.\n    const msg = (err as Error).message;\n    if (/no such (wall-clock )?time/i.test(msg) && disambiguation === 'reject') {\n      throw new Error(\n        `temporal-fmt: \"${timeZone}\" has no such wall-clock time on ${fields.year}-${fields.month}-${fields.day}T${fields.hour ?? 0}:${fields.minute ?? 0} — ` +\n        `it falls in a DST gap. Pass { disambiguation: 'compatible' | 'earlier' | 'later' } to pick an instant.`\n      );\n    }\n    throw err;\n  }\n}\n\nexport function getTimeZone(value: unknown): string {\n  const v = value as { timeZoneId?: string };\n  if (typeof v?.timeZoneId !== 'string') {\n    throw new Error(`temporal-fmt: getTimeZone() expected a ZonedDateTime, got ${typeof value}.`);\n  }\n  return v.timeZoneId;\n}\n\nexport function getOffset(value: unknown): string {\n  const v = value as { offset?: string };\n  if (typeof v?.offset !== 'string') {\n    throw new Error(`temporal-fmt: getOffset() expected a ZonedDateTime, got ${typeof value}.`);\n  }\n  return v.offset;\n}\n\nexport function getOffsetNanoseconds(value: unknown): number {\n  const v = value as { offsetNanoseconds?: number; offset?: string };\n  if (typeof v?.offsetNanoseconds === 'number') return v.offsetNanoseconds;\n  if (typeof v?.offset === 'string') {\n    // Parse ±HH:MM → nanoseconds.\n    const m = v.offset.match(/^([+-])(\\d{2}):(\\d{2})$/);\n    if (!m) throw new Error(`temporal-fmt: getOffsetNanoseconds() couldn't parse offset \"${v.offset}\".`);\n    const sign = m[1] === '-' ? -1 : 1;\n    return sign * (Number(m[2]) * 3600 + Number(m[3]) * 60) * 1_000_000_000;\n  }\n  throw new Error(`temporal-fmt: getOffsetNanoseconds() expected a ZonedDateTime, got ${typeof value}.`);\n}\n\n// DST detection: a ZonedDateTime is in DST iff the offset is different\n// from the timezone's standard offset at the same instant. The standard\n// offset is the SMALLER of the zone's Jan 1 and Jul 1 offsets of the\n// same year — DST always shifts toward the sun-facing hemisphere, so\n// whichever of the two mid-winter/mid-summer probes has the smaller\n// offset is standard time, regardless of which hemisphere the zone is\n// in. (The old January-only comparison assumed northern hemisphere and\n// was inverted year-round for Australia/NZ/South America/southern\n// Africa: Sydney in December (AEDT, genuinely DST) reported false,\n// Sydney in July (AEST, standard) reported true.)\nexport function isDST(value: unknown): boolean {\n  const v = value as { timeZoneId?: string; offset?: string; year?: number; toInstant?: () => unknown };\n  if (typeof v?.timeZoneId !== 'string' || typeof v?.offset !== 'string' || typeof v?.year !== 'number') {\n    throw new Error(`temporal-fmt: isDST() expected a ZonedDateTime, got ${typeof value}.`);\n  }\n  const temporal = getTemporal();\n  try {\n    const options = { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1];\n    const jan = temporal.ZonedDateTime.from(\n      { year: v.year, month: 1, day: 1, hour: 12, timeZone: v.timeZoneId }, options,\n    ) as { offset: string; offsetNanoseconds?: bigint };\n    const jul = temporal.ZonedDateTime.from(\n      { year: v.year, month: 7, day: 1, hour: 12, timeZone: v.timeZoneId }, options,\n    ) as { offset: string; offsetNanoseconds?: bigint };\n    // Standard = the smaller of the two offsets. If they're equal the\n    // zone has no DST at all — never in DST. Both arms are normalized to\n    // SECONDS: the offsetNanoseconds path divides by 1e9 (exact for real\n    // zones, whose offsets are whole seconds), so the string-offset\n    // fallback below compares like with like — the two paths used to mix\n    // seconds and nanoseconds, which could never compare equal on the\n    // fallback path and made every non-equal-offset zone read as \"in DST\".\n    const janOff = jan.offsetNanoseconds !== undefined ? Number(jan.offsetNanoseconds) / 1e9 : offsetToSeconds(jan.offset);\n    const julOff = jul.offsetNanoseconds !== undefined ? Number(jul.offsetNanoseconds) / 1e9 : offsetToSeconds(jul.offset);\n    if (janOff === julOff) return false;\n    const standardOff = Math.min(janOff, julOff);\n    return offsetToSeconds(v.offset) !== standardOff;\n  } catch {\n    return false;\n  }\n}\n\n// Parses \"+HH:MM\" (with optional \":SS\" or \".ffffff\" tail) into seconds.\n// Used by isDST's string-offset fallback when the Temporal\n// implementation doesn't expose offsetNanoseconds.\nfunction offsetToSeconds(offset: string): number {\n  const m = /^([+-])(\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?$/.exec(offset);\n  if (!m) return 0;\n  const sign = m[1] === '-' ? -1 : 1;\n  return sign * (Number(m[2]) * 3600 + Number(m[3]) * 60 + Number(m[4] ?? 0));\n}\n\n// Returns the next DST transition strictly after `value`, or undefined\n// if no transition occurs within the next 2 years. Implemented by\n// walking day-by-day checking for offset changes — slow but simple,\n// and correct across all IANA zones.\nexport function getNextTransition(value: unknown): unknown | undefined {\n  return findTransition(value, 1);\n}\n\nexport function getPreviousTransition(value: unknown): unknown | undefined {\n  return findTransition(value, -1);\n}\n\nfunction findTransition(value: unknown, direction: 1 | -1): unknown | undefined {\n  const v = value as { timeZoneId?: string; offset?: string; toInstant?: () => unknown; year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; millisecond?: number };\n  if (typeof v?.timeZoneId !== 'string') {\n    throw new Error(`temporal-fmt: ${direction > 0 ? 'getNextTransition' : 'getPreviousTransition'}() expected a ZonedDateTime, got ${typeof value}.`);\n  }\n  const temporal = getTemporal();\n  const timeZone = v.timeZoneId;\n  let candidateFields = add(value, direction, 'days');\n  // Duck-typed input with no `offset` used to hit a non-null lie\n  // (`v.offset!`) and find a spurious \"transition\" on the first\n  // candidate day; derive the real starting offset instead.\n  const startOffset = typeof v.offset === 'string'\n    ? v.offset\n    : (() => {\n        try {\n          return (temporal.ZonedDateTime.from(\n            { year: v.year, month: v.month, day: v.day, hour: v.hour ?? 12, timeZone },\n            { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n          ) as { offset: string }).offset;\n        } catch {\n          return undefined;\n        }\n      })();\n  if (startOffset === undefined) return undefined;\n  for (let i = 0; i < 365 * 2; i++) {\n    // Rebuild a real ZonedDateTime for this candidate day, in this\n    // timezone, so `.offset` reflects the actual UTC offset on that\n    // day rather than being absent. add() only produces a plain field\n    // bag (it has no notion of timezone), so re-attaching timeZone via\n    // ZonedDateTime.from is what actually lets us detect a DST change\n    // here — using the field bag's own (nonexistent) offset would make\n    // every call \"find\" a transition on the very first day checked.\n    const cf = candidateFields as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number };\n    const candidateZdt = temporal.ZonedDateTime.from(\n      { ...cf, timeZone },\n      { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n    ) as { offset: string; year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number };\n    if (candidateZdt.offset !== startOffset) {\n      // Found a transition day. Bisect the actual transition instant\n      // within the day: the day-before/day-of boundary is somewhere in\n      // the 24h before this candidate. Stepping the reconstruction at\n      // the input's wall-clock time used to return \"2026-03-08T12:00\"\n      // for a spring-forward that actually happens at 02:00 — the\n      // right day, ten hours late.\n      return bisectTransition(temporal, timeZone, candidateZdt, startOffset, direction);\n    }\n    candidateFields = add(candidateFields, direction, 'days');\n  }\n  return undefined;\n}\n\n// Narrows a transition down to the actual boundary minute by binary\n// search over a 24-hour window, probed via a minute-index cursor.\n// `direction` is 1 when scanning forward: the transition lies inside\n// `day` (whose 12:00 already shows the new offset), so the window is\n// [day 00:00, day 24:00). `direction` is -1 when scanning backward:\n// `day` is the last day whose 12:00 still shows the OLD offset, so the\n// transition lies in (day 12:00, day+1 12:00]. Returns a ZonedDateTime\n// at the first minute on the new side. (The old code returned the\n// candidate day reconstructed at the INPUT's wall-clock time — e.g.\n// \"2026-03-08T12:00\" for a spring-forward that happens at 02:00.)\nfunction bisectTransition(\n  temporal: TemporalNamespace,\n  timeZone: string,\n  day: { year: number; month: number; day: number; offset: string },\n  beforeOffset: string,\n  direction: 1 | -1,\n): unknown {\n  const zonedFrom = temporal.ZonedDateTime.from.bind(temporal.ZonedDateTime) as (f: unknown, o?: unknown) => unknown;\n  const options = { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1];\n  // Window anchor: midnight of `day` for forward scans; noon of `day`\n  // for backward scans (the day's noon is known to still be old-side).\n  const windowStart = direction > 0\n    ? { year: day.year, month: day.month, day: day.day, hour: 0, minute: 0 }\n    : { year: day.year, month: day.month, day: day.day, hour: 12, minute: 0 };\n  // Minute m of the window → wall-clock fields via add() (handles\n  // rolling past midnight at the window's end).\n  const fieldsAt = (m: number) => add(windowStart, m, 'minutes') as { year: number; month: number; day: number; hour: number; minute: number };\n  const offsetAt = (m: number): string | undefined => {\n    try {\n      const f = fieldsAt(m);\n      return (zonedFrom({ ...f, timeZone }, options) as { offset: string }).offset;\n    } catch {\n      return undefined;\n    }\n  };\n  // The old side's offset: `beforeOffset` for forward scans, `day`'s own\n  // (still-old) offset for backward scans.\n  const oldOffset = direction > 0 ? beforeOffset : day.offset;\n  // Binary search over minutes [0, 1440): find the first minute whose\n  // offset differs from oldOffset. Unresolvable probes count as\n  // old-side so the search converges to a real boundary.\n  let lo = 0;\n  let hi = 1440;\n  while (hi - lo > 1) {\n    const mid = Math.floor((lo + hi) / 2);\n    const off = offsetAt(mid);\n    if (off === undefined || off === oldOffset) lo = mid;\n    else hi = mid;\n  }\n  // `hi` is the first new-side minute (1440 = the boundary exactly at\n  // the window's end — normalize to the following midnight).\n  const boundary = hi >= 1440 ? fieldsAt(1439) : fieldsAt(hi);\n  try {\n    return zonedFrom({\n      year: boundary.year, month: boundary.month, day: boundary.day,\n      hour: boundary.hour, minute: boundary.minute, timeZone,\n    }, options);\n  } catch {\n    return day;\n  }\n}\n\nexport function getTransitions(start: unknown, end: unknown): unknown[] {\n  const result: unknown[] = [];\n  const startV = start as { timeZoneId?: string; offset?: string; year?: number; month?: number; day?: number };\n  if (typeof startV?.timeZoneId !== 'string') {\n    throw new Error(`temporal-fmt: getTransitions() expected a ZonedDateTime for start, got ${typeof start}.`);\n  }\n  // `end` used to be dereferenced raw (`endV.year`) with no guard —\n  // passing undefined crashed with a bare V8 TypeError.\n  const endV = end as { year?: number; month?: number; day?: number };\n  if (typeof endV?.year !== 'number' || typeof endV?.month !== 'number' || typeof endV?.day !== 'number') {\n    throw new Error(`temporal-fmt: getTransitions() expected a date-carrying value for end, got ${typeof end}.`);\n  }\n  const endYear = endV.year, endMonth = endV.month, endDay = endV.day;\n  const temporal = getTemporal();\n  const timeZone = startV.timeZoneId;\n  let cursorFields = add(start, 1, 'days');\n  let lastOffset = startV.offset!;\n  for (let i = 0; i < 365 * 5; i++) {\n    // Same reconstruction as findTransition() above — add() strips\n    // timezone/offset info, so we rebuild a real ZonedDateTime each\n    // iteration to read its actual offset instead of comparing against\n    // a field bag that never has one.\n    const cf = cursorFields as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number };\n    const cursorZdt = temporal.ZonedDateTime.from(\n      { ...cf, timeZone },\n      { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n    ) as { offset: string; year: number; month: number; day: number };\n    if (cursorZdt.offset !== lastOffset) {\n      // Found a transition.\n      if (cursorZdt.year > endYear || (cursorZdt.year === endYear && (cursorZdt.month > endMonth || (cursorZdt.month === endMonth && cursorZdt.day > endDay)))) break;\n      result.push(cursorZdt);\n      lastOffset = cursorZdt.offset;\n    }\n    cursorFields = add(cursorFields, 1, 'days');\n  }\n  return result;\n}\n\n// Returns the list of possible instants for a wall-clock time in a\n// zone — used to detect gaps (0 instants) and overlaps (2 instants).\nexport function possibleInstantsFor(\n  fields: { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number },\n  timeZone: string,\n): unknown[] {\n  const temporal = getTemporal();\n  // Resolve the same wall-clock fields twice, forcing disambiguation\n  // toward the earlier and later side of any DST boundary. Comparing\n  // the two results tells us which of the three cases we're in:\n  //  - gap (e.g. 2:30am on a spring-forward day): neither result's own\n  //    wall-clock fields match what was requested, since Temporal has\n  //    to shift off the nonexistent time in both directions — 0 instants.\n  //  - overlap (e.g. 1:30am on a fall-back day): both results keep the\n  //    requested wall-clock time but land on different instants (one\n  //    per side of the boundary) — 2 instants.\n  //  - normal time: both results match the requested wall-clock time\n  //    and resolve to the same instant — 1 instant.\n  const earlier = temporal.ZonedDateTime.from(\n    { ...fields, timeZone },\n    { disambiguation: 'earlier', offset: 'ignore' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n  ) as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number; toInstant: () => { epochNanoseconds: bigint } };\n  const later = temporal.ZonedDateTime.from(\n    { ...fields, timeZone },\n    { disambiguation: 'later', offset: 'ignore' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n  ) as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number; toInstant: () => { epochNanoseconds: bigint } };\n\n  const matchesRequestedWallClock = (z: typeof earlier) =>\n    z.year === fields.year && z.month === fields.month && z.day === fields.day &&\n    z.hour === fields.hour && z.minute === fields.minute &&\n    z.second === fields.second && z.millisecond === fields.millisecond;\n\n  if (!matchesRequestedWallClock(earlier) || !matchesRequestedWallClock(later)) {\n    // Gap — the requested wall-clock time doesn't exist in this zone.\n    return [];\n  }\n  if (earlier.toInstant().epochNanoseconds === later.toInstant().epochNanoseconds) {\n    // Normal time — both disambiguation directions agree on the instant.\n    return [earlier];\n  }\n  // Overlap — same wall-clock time, two distinct instants.\n  return [earlier, later];\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// IDE tooling data exports. Provides structured data editor plugins can\n// consume for: token autocomplete, hover docs, inline diagnostics,\n// quick fixes, format preview, token conversion hints from\n// Day.js/date-fns, documentation links.\n//\n// This is the data layer only — an actual VS Code extension is out of\n// scope for this package. A separate package can build the extension\n// on top of these exports.\n\nimport { TOKEN_METADATA, ALL_TOKEN_NAMES } from './tokenMetadata.js';\nimport { analyzeFormat, listTokens } from './analyze.js';\nimport { format as builtinFormat } from './format.js';\nimport { getTemporal } from './temporalProvider.js';\n\nexport interface TokenAutocompleteEntry {\n  label: string;\n  detail: string;\n  documentation: string;\n  // Sort group — same-family tokens sort together in the autocomplete list.\n  family: string;\n}\n\n// Token family grouping for autocomplete organization: year, month,\n// day, etc.\nfunction tokenFamily(name: string): string {\n  if (/^y+$/.test(name)) return 'Year';\n  if (/^[ML]+$/.test(name)) return 'Month';\n  if (/^[decD]+$/.test(name)) return 'Day';\n  if (/^[Ec]+$/.test(name)) return 'Weekday';\n  if (/^[Qq]+$/.test(name)) return 'Quarter';\n  if (/^[Gg]+$/.test(name)) return 'Era';\n  if (/^[Hh]+$/.test(name)) return 'Hour';\n  if (/^m+$/.test(name)) return 'Minute';\n  if (/^s+$/.test(name)) return 'Second';\n  if (/^S+$/.test(name)) return 'Fractional Second';\n  if (name === 'a') return 'Day Period';\n  // z/zzz/zzzz are all zone tokens — only exact 'zzz' used to be\n  // special-cased, leaving 'z' and 'zzzz' filed under 'Other'.\n  if (name === 'z' || name === 'zzz' || name === 'zzzz') return 'Time Zone';\n  if (/^[Xx]+$/.test(name)) return 'UTC Offset';\n  if (name === 'do') return 'Ordinal Day';\n  // Unreachable with the current token set: every name in ALL_TOKEN_NAMES\n  // (the only input — see getAutocompleteData) matches a family above, so\n  // the fall-through below only exists as the catch-all for tokens added\n  // in the future. The first ignored line is the ww/RRRR if, whose V8\n  // fall-through block remaps onto it; the second is the return itself;\n  // the third is the function's implicit end-of-body statement.\n  /* c8 ignore next 3 @preserve */\n  if (name === 'ww' || name === 'RRRR') return 'ISO Week';\n  return 'Other';\n}\n\nexport function getAutocompleteData(): TokenAutocompleteEntry[] {\n  return ALL_TOKEN_NAMES.map((name) => {\n    const meta = TOKEN_METADATA[name]!;\n    return {\n      label: name,\n      detail: meta.meaning,\n      documentation: [\n        meta.meaning,\n        ``,\n        `Format-capable: ${meta.formatCapable}`,\n        `Parse-capable: ${meta.parseCapable}`,\n        `Locale-sensitive: ${meta.localeSensitive}`,\n        `Calendar-sensitive: ${meta.calendarSensitive}`,\n        `Timezone-sensitive: ${meta.timezoneSensitive}`,\n        `Round-trip safe: ${meta.roundTripSafe}`,\n        `Supported types: ${meta.supportedTypes.join(', ')}`,\n      ].join('\\n'),\n      family: tokenFamily(name),\n    };\n  });\n}\n\nexport interface TokenHoverDoc {\n  signature: string;\n  summary: string;\n  details: string;\n  examples?: string[];\n}\n\nexport function getHoverDocs(): Record<string, TokenHoverDoc> {\n  const result: Record<string, TokenHoverDoc> = {};\n  for (const name of ALL_TOKEN_NAMES) {\n    const meta = TOKEN_METADATA[name]!;\n    result[name] = {\n      signature: name,\n      summary: meta.meaning,\n      details: [\n        // every entry in TOKEN_METADATA currently has formatCapable:\n        // true (verified: 51/51). The 'no' branch reflects real,\n        // intended behavior for a future format-incapable token —\n        // there's no such token today, so this isn't reachable data,\n        // not dead logic. Every other field on this line has real\n        // true/false variance across the token table and is exercised\n        // by this same loop running over ALL_TOKEN_NAMES.\n        /* c8 ignore next */\n        `Format-capable: ${meta.formatCapable ? 'yes' : 'no'}`,\n        `Parse-capable: ${meta.parseCapable ? 'yes' : 'no'}`,\n        `Locale-sensitive: ${meta.localeSensitive ? 'yes' : 'no'}`,\n        `Calendar-sensitive: ${meta.calendarSensitive ? 'yes' : 'no'}`,\n        `Timezone-sensitive: ${meta.timezoneSensitive ? 'yes' : 'no'}`,\n        `Round-trip safe: ${meta.roundTripSafe ? 'yes' : 'no'}`,\n        `Supported types: ${meta.supportedTypes.join(', ')}`,\n      ].join('\\n'),\n    };\n  }\n  return result;\n}\n\n// Inline diagnostic data for a format string. Returns a list of issues\n// (warnings + errors) with position + message + suggested fix where\n// available. Mirrors analyzeFormat's warnings but adds the position\n// info an editor needs to draw squigglies.\nexport interface InlineDiagnostic {\n  startColumn: number;\n  endColumn: number;\n  severity: 'error' | 'warning' | 'info';\n  message: string;\n  code: string;\n  // Suggested replacement (for quick-fix). Empty when no quick fix exists.\n  suggestion?: string;\n}\n\nexport function getInlineDiagnostics(formatStr: string): InlineDiagnostic[] {\n  const analysis = analyzeFormat(formatStr);\n  const diagnostics: InlineDiagnostic[] = [];\n  for (const warning of analysis.warnings) {\n    // Find the token that triggered the warning. analyzeFormat doesn't\n    // currently surface which token caused which warning — we'd need\n    // to extend it to track per-warning source positions. For now,\n    // surface as a whole-string diagnostic.\n    let message = warning.message;\n    let suggestion: string | undefined;\n    if (warning.code === 'TWELVE_HOUR_WITHOUT_A') {\n      suggestion = 'Add an \"a\" token (e.g. \"h:mm a\") or use \"H:mm\" for 24-hour.';\n    } else if (warning.code === 'MIXED_12_AND_24_HOUR') {\n      suggestion = 'Pick one form: \"HH:mm\" for 24-hour or \"h:mm a\" for 12-hour.';\n    } else if (warning.code === 'AMBIGUOUS_NUMERIC_RUN') {\n      suggestion = 'Add a separator or use padded forms (e.g. \"MM\" instead of \"M\").';\n    } else if (warning.code === 'FORMAT_ONLY_TOKEN') {\n      suggestion = 'Use a parse-capable variant (e.g. \"d\" instead of \"do\").';\n    }\n    diagnostics.push({\n      startColumn: 0,\n      endColumn: formatStr.length,\n      severity: 'warning',\n      message,\n      code: warning.code,\n      suggestion,\n    });\n  }\n  return diagnostics;\n}\n\n// Day.js / date-fns token conversion hints. Used by the IDE to suggest\n// the temporal-fmt equivalent when a user types a Day.js or date-fns\n// token. Pulls the translation tables from the codemod if available;\n// falls back to inline tables otherwise.\nexport interface TokenConversionHint {\n  from: string;\n  // null means \"real token in the source library, no temporal-fmt\n  // equivalent\" — the codemod throws on these rather than treating\n  // them as unrecognized text (see codemod.ts).\n  to: string | null;\n  notes?: string;\n}\n\n// Day.js → temporal-fmt mappings. Day.js uses Moment-style tokens:\n// `D`/`DD` are day-of-*month* here (unlike date-fns below, where the\n// same letters mean day-of-year). Assumes the AdvancedFormat plugin\n// for `Do`/`Q`/`k`/`kk`/`X`/`x` — see codemod.ts's doc comment for why.\nexport const DAYJS_TO_TEMPORAL_FMT: TokenConversionHint[] = [\n  { from: 'YYYY', to: 'yyyy' },\n  { from: 'YY', to: 'yy' },\n  { from: 'MMMM', to: 'MMMM' },\n  { from: 'MMM', to: 'MMM' },\n  { from: 'MM', to: 'MM' },\n  { from: 'M', to: 'M' },\n  { from: 'DD', to: 'dd' },\n  { from: 'D', to: 'd' },\n  { from: 'Do', to: null, notes: 'Ordinal day (AdvancedFormat) — use temporal-fmt\\'s own \"do\" token instead.' },\n  { from: 'dddd', to: 'EEEE' },\n  { from: 'ddd', to: 'EEE' },\n  { from: 'dd', to: null, notes: 'Min-name weekday (e.g. \"Tu\") — temporal-fmt has no equivalent width.' },\n  { from: 'd', to: null, notes: 'Numeric weekday (0-6) — no temporal-fmt equivalent; not the same as \"d\" here, which is day-of-month.' },\n  { from: 'HH', to: 'HH' },\n  { from: 'H', to: 'H' },\n  { from: 'hh', to: 'hh' },\n  { from: 'h', to: 'h' },\n  { from: 'kk', to: null, notes: 'Hour 1-24 (AdvancedFormat) — no temporal-fmt equivalent.' },\n  { from: 'k', to: null, notes: 'Hour 1-24 (AdvancedFormat) — no temporal-fmt equivalent.' },\n  { from: 'mm', to: 'mm' },\n  { from: 'm', to: 'm' },\n  { from: 'ss', to: 'ss' },\n  { from: 's', to: 's' },\n  // Fractional seconds: Day.js S/SS/SSS are 1/2/3-digit milliseconds,\n  // the same widths temporal-fmt's own S/SS/SSS use. These used to be\n  // missing from the table entirely, so \"S\"/\"SS\" silently translated\n  // to quoted LITERAL text (translateDayjs('S') → \"'S'\") instead of\n  // a token.\n  { from: 'SSS', to: 'SSS' },\n  { from: 'SS', to: 'SS' },\n  { from: 'S', to: 'S' },\n  { from: 'A', to: 'a', notes: 'Uppercase AM/PM in Day.js — temporal-fmt is always lowercase.' },\n  { from: 'a', to: 'a' },\n  { from: 'ZZ', to: 'XX', notes: 'Numeric UTC offset, no colon.' },\n  { from: 'Z', to: 'XXX', notes: 'Numeric UTC offset with colon.' },\n  { from: 'X', to: null, notes: 'Unix timestamp (seconds) — use fromUnixSeconds() instead.' },\n  { from: 'x', to: null, notes: 'Unix timestamp (ms) — use fromUnixMilliseconds() instead.' },\n  { from: 'Qo', to: null, notes: 'Ordinal quarter (AdvancedFormat) — no temporal-fmt equivalent.' },\n  { from: 'Q', to: 'Q' },\n  { from: 'Mo', to: null, notes: 'Ordinal month (AdvancedFormat) — no temporal-fmt equivalent.' },\n  // Day.js w/ww are LOCALE-aware weeks (default en locale: week starts\n  // Sunday, week 1 contains Jan 1) — not the ISO weeks temporal-fmt's\n  // ww computes. Mapping silently would print different week numbers\n  // than the source library for the same date (e.g. 2016-01-01: Day.js\n  // \"1\" vs temporal-fmt \"53\"), so refuse with a note instead.\n  { from: 'ww', to: null, notes: 'Locale-aware week of year — temporal-fmt\\'s \"ww\" is a strict ISO week number and disagrees with Day.js\\'s locale week for the same date. Compute locale weeks separately if needed.' },\n  { from: 'wo', to: null, notes: 'Ordinal locale week (AdvancedFormat) — no temporal-fmt equivalent.' },\n  { from: 'w', to: null, notes: 'Unpadded locale week of year — see the \"ww\" note; temporal-fmt has only ISO weeks.' },\n  { from: 'gg', to: null, notes: 'Two-digit locale week-numbering year — no temporal-fmt equivalent (RRRR is 4-digit ISO).' },\n  { from: 'gggg', to: 'RRRR', notes: 'Week-numbering year — mapped, but Day.js\\'s is locale-week-based while RRRR is strict ISO; values can differ at year boundaries.' },\n  { from: 'L', to: null, notes: 'Localized date format (AdvancedFormat) — write the format string out explicitly.' },\n  { from: 'LL', to: null, notes: 'Localized date format (AdvancedFormat) — write the format string out explicitly.' },\n  { from: 'LLL', to: null, notes: 'Localized date format (AdvancedFormat) — write the format string out explicitly.' },\n  { from: 'LLLL', to: null, notes: 'Localized date format (AdvancedFormat) — write the format string out explicitly.' },\n  { from: 'LT', to: null, notes: 'Localized time format (AdvancedFormat) — write the format string out explicitly.' },\n  { from: 'LTS', to: null, notes: 'Localized time format (AdvancedFormat) — write the format string out explicitly.' },\n];\n\n// date-fns → temporal-fmt mappings. date-fns already uses Unicode/LDML\n// -style tokens close to temporal-fmt's own vocabulary — most strings\n// pass through unchanged. The catch: `D`/`DD` here mean day-of-*year*\n// (same as temporal-fmt's `D`/`DD`), not day-of-month like Day.js's\n// `D`/`DD` above — don't reuse the Day.js table for this, they collide.\nexport const DATE_FNS_TO_TEMPORAL_FMT: TokenConversionHint[] = [\n  { from: 'yyyy', to: 'yyyy' },\n  { from: 'yy', to: 'yy' },\n  // temporal-fmt HAS an unpadded-year token (\"y\", same as date-fns);\n  // this used to map to null and throw even though the token passes\n  // straight through.\n  { from: 'y', to: 'y', notes: 'Unpadded calendar year, opt-in via useAdditionalWeekYearTokens — temporal-fmt has the same \"y\" token.' },\n  { from: 'MMMM', to: 'MMMM' },\n  { from: 'MMM', to: 'MMM' },\n  { from: 'MM', to: 'MM' },\n  { from: 'M', to: 'M' },\n  { from: 'LLLL', to: 'LLLL' },\n  { from: 'LLL', to: 'LLL' },\n  { from: 'dd', to: 'dd' },\n  { from: 'd', to: 'd' },\n  { from: 'do', to: 'do' },\n  { from: 'DDD', to: 'DDD' },\n  { from: 'DD', to: 'DD' },\n  { from: 'D', to: 'D', notes: 'Day-of-year, opt-in via useAdditionalDayOfYearTokens — matches temporal-fmt\\'s own \"D\" already.' },\n  { from: 'EEEE', to: 'EEEE' },\n  { from: 'EEE', to: 'EEE' },\n  { from: 'eeee', to: null, notes: 'Locale-aware numeric weekday — no temporal-fmt equivalent.' },\n  { from: 'cccc', to: 'cccc' },\n  { from: 'ccc', to: 'ccc' },\n  { from: 'HH', to: 'HH' },\n  { from: 'H', to: 'H' },\n  { from: 'hh', to: 'hh' },\n  { from: 'h', to: 'h' },\n  { from: 'mm', to: 'mm' },\n  { from: 'm', to: 'm' },\n  { from: 'ss', to: 'ss' },\n  { from: 's', to: 's' },\n  // Fractional seconds, same widths as temporal-fmt's own tokens —\n  // used to be missing, silently literalizing \"S\"/\"SS\".\n  { from: 'SSS', to: 'SSS' },\n  { from: 'SS', to: 'SS' },\n  { from: 'S', to: 'S' },\n  { from: 'a', to: 'a' },\n  { from: 'aaa', to: 'a' },\n  { from: 'XXX', to: 'XXX' },\n  { from: 'XX', to: 'XX' },\n  { from: 'X', to: 'X', notes: 'Opt-in via useAdditionalDayOfYearTokens-adjacent rules in date-fns v3+; matches temporal-fmt\\'s own \"X\" already.' },\n  { from: 'xxx', to: 'xxx' },\n  { from: 'xx', to: 'xx' },\n  { from: 'x', to: 'x' },\n  { from: 'zzzz', to: 'zzzz' },\n  { from: 'zzz', to: 'zzz' },\n  { from: 'z', to: 'z' },\n  { from: 'QQQ', to: 'QQQ' },\n  { from: 'Q', to: 'Q' },\n  { from: 'QQQQ', to: null, notes: 'Long quarter name — temporal-fmt has Q (numeric) and QQQ (\"Q1\"-style) only.' },\n  { from: 'Qo', to: null, notes: 'Ordinal quarter — no temporal-fmt equivalent.' },\n  { from: 'GGGG', to: 'GGGG' },\n  { from: 'GGG', to: null, notes: 'Abbreviated era — temporal-fmt only has \"G\" (short) and \"GGGG\" (long).' },\n  { from: 'GG', to: null, notes: 'Abbreviated era — temporal-fmt only has \"G\" (short) and \"GGGG\" (long).' },\n  { from: 'G', to: 'G' },\n  // date-fns w/ww are LOCAL week rules (en-US: week starts Sunday, week\n  // 1 contains Jan 1) — temporal-fmt's ww is strict ISO. Silently\n  // mapping prints different numbers than the source library (2016-01-01:\n  // date-fns \"01\" vs temporal-fmt \"53\"), so refuse with a note.\n  { from: 'ww', to: null, notes: 'Local week of year — temporal-fmt\\'s \"ww\" is a strict ISO week number and disagrees with date-fns\\'s locale week for the same date. Compute locale weeks separately if needed.' },\n  { from: 'w', to: null, notes: 'Unpadded local week number — temporal-fmt\\'s \"ww\" is ISO-week and always 2-digit.' },\n  { from: 'RRRR', to: 'RRRR' },\n  { from: 'R', to: null, notes: 'Unpadded ISO week-numbering year — temporal-fmt\\'s \"RRRR\" is always 4-digit.' },\n  { from: 'Y', to: null, notes: 'Week-numbering year (locale week rules), opt-in — no temporal-fmt equivalent; \"RRRR\" is ISO week-numbering, a different rule set.' },\n  { from: 'PPPP', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'PPP', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'PP', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'P', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'pppp', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'ppp', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'pp', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n  { from: 'p', to: null, notes: 'Localized composite format — write the format string out explicitly.' },\n];\n\n// Format preview — for a given format string and a sample Temporal\n// value, returns the formatted string. Editor plugins use this for\n// live preview as the user types.\nexport function previewFormat(formatStr: string, sample?: unknown): string {\n  // Use a fixed sample date if none provided — 2026-08-04T15:45:30,\n  // built as a REAL Temporal.PlainDateTime. Picked because it exercises\n  // every common token: weekday is Tuesday, month name has 5 chars, day\n  // is single-digit, hour is 12-hour-style, minute/second both pad.\n  // (A plain field bag used to be passed instead, which can't render\n  // locale-aware tokens at all — previewFormat('MMMM d') threw \"needs a\n  // value that implements toLocaleString\".)\n  let value = sample;\n  if (value === undefined) {\n    const temporal = getTemporal();\n    value = temporal.PlainDateTime.from({\n      year: 2026, month: 8, day: 4, hour: 15, minute: 45, second: 30, millisecond: 123,\n    });\n  }\n  return builtinFormat(value as Parameters<typeof builtinFormat>[0], formatStr, { locale: 'en-US' });\n}\n\n// Documentation links. Docs used to live under docs/ as one file per\n// token family; they're now consolidated into the root README's \"Token\n// reference\" section, which has no per-token anchors — so this points\n// at the section instead of a token-specific fragment.\nexport function getDocUrl(tokenName: string): string {\n  void tokenName;\n  return 'README.md#token-reference';\n}\n\n// Re-exports for callers that want everything IDE-related from one module.\nexport { listTokens, TOKEN_METADATA, ALL_TOKEN_NAMES };","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// translates Day.js / date-fns format strings — this is what backs the\n// CLI's `translate` subcommand. the mapping tables were already sitting\n// in ideData.ts (built for the IDE tooling), so this just builds the\n// actual string translator on top instead of pulling in anything else.\n//\n// heads up: this only handles format *strings* (\"YYYY-MM-DD\" -> \"yyyy-MM-dd\"),\n// not an actual AST codemod that goes and rewrites call sites in your code.\n// that's a bigger separate thing — check temporal-fmt-codemod if that's\n// what you actually need\n\nimport { DAYJS_TO_TEMPORAL_FMT, DATE_FNS_TO_TEMPORAL_FMT, type TokenConversionHint } from './ideData.js';\n\ninterface SourcePiece {\n  kind: 'token' | 'literal';\n  value: string;\n}\n\n// Day.js and date-fns escape literal text with square brackets — [MM]\n// stays as literal \"MM\" — not single quotes like temporal-fmt does.\n// splitting on brackets first keeps the token scan below from accidentally\n// matching stuff inside an escaped span\nfunction splitOnBrackets(source: string): SourcePiece[] {\n  const pieces: SourcePiece[] = [];\n  let i = 0;\n  while (i < source.length) {\n    if (source[i] === '[') {\n      const end = source.indexOf(']', i + 1);\n      if (end === -1) {\n        pieces.push({ kind: 'token', value: source.slice(i) });\n        break;\n      }\n      pieces.push({ kind: 'literal', value: source.slice(i + 1, end) });\n      i = end + 1;\n    } else {\n      let j = i;\n      while (j < source.length && source[j] !== '[') j += 1;\n      pieces.push({ kind: 'token', value: source.slice(i, j) });\n      i = j;\n    }\n  }\n  return pieces;\n}\n\n// splits a non-bracketed span into runs, matching greedy-longest against\n// the known token table — basically the same idea as tokenize.ts, just\n// scanning the SOURCE library's tokens here instead of temporal-fmt's own\nfunction splitIntoRuns(span: string, sortedFrom: string[]): SourcePiece[] {\n  const pieces: SourcePiece[] = [];\n  let i = 0;\n  while (i < span.length) {\n    const match = sortedFrom.find((tok) => span.startsWith(tok, i));\n    if (match) {\n      pieces.push({ kind: 'token', value: match });\n      i += match.length;\n      continue;\n    }\n    const last = pieces[pieces.length - 1];\n    if (last && last.kind === 'literal') {\n      last.value += span[i];\n    } else {\n      pieces.push({ kind: 'literal', value: span[i] });\n    }\n    i += 1;\n  }\n  return pieces;\n}\n\nfunction translate(source: string, table: TokenConversionHint[], sourceLibLabel: string): string {\n  const byFrom = new Map(table.map((hint) => [hint.from, hint.to]));\n  const sortedFrom = [...byFrom.keys()].sort((a, b) => b.length - a.length);\n\n  const bracketPieces = splitOnBrackets(source);\n  let out = '';\n  for (const piece of bracketPieces) {\n    if (piece.kind === 'literal') {\n      // re-escape for temporal-fmt's quote syntax — any literal quote\n      // char inside the escaped bit needs doubling up\n      out += `'${piece.value.replace(/'/g, \"''\")}'`;\n      continue;\n    }\n    for (const run of splitIntoRuns(piece.value, sortedFrom)) {\n      if (run.kind === 'token') {\n        const mapped = byFrom.get(run.value);\n        if (mapped === undefined || mapped === null) {\n          throw new Error(\n            `temporal-fmt: \"${run.value}\" has no ${sourceLibLabel} -> temporal-fmt mapping ` +\n            `(in format string \"${source}\"). Write the equivalent temporal-fmt token in by hand, ` +\n            `or wrap it in brackets if it was meant as literal text.`\n          );\n        }\n        out += mapped;\n      } else if (/[a-zA-Z]/.test(run.value)) {\n        // can't just let unrecognized letters through as-is — temporal-fmt\n        // would read them as its own tokens by accident. gotta quote the run\n        out += `'${run.value.replace(/'/g, \"''\")}'`;\n      } else {\n        out += run.value;\n      }\n    }\n  }\n  return out;\n}\n\n/**\n * Translates a Day.js format string to the equivalent temporal-fmt\n * token string.\n *\n * ```js\n * translateDayjsFormatString('YYYY-MM-DD HH:mm:ss'); // \"yyyy-MM-dd HH:mm:ss\"\n * translateDayjsFormatString('[Q]Q YYYY');            // \"'Q'Q yyyy\" (bracketed text stays literal)\n * ```\n *\n * Throws if the format string uses a Day.js token with no temporal-fmt\n * equivalent (`Do`, `Mo`, `Qo`, `k`, `kk`, `X`, `x`, the localized\n * `L`-family tokens) — these need to be rewritten by hand, since\n * there's no single temporal-fmt token that means the same thing.\n *\n * Note: `Do`/`Mo`/`Qo`/`k`/`kk`/`X`/`x` only have meaning in Day.js\n * once the `AdvancedFormat` (and, for `X`/`x`, base) plugins are\n * loaded — without them Day.js silently glues the parts together or\n * passes the letters through unrendered instead of erroring. This\n * function assumes the plugin is loaded, since that's the common case\n * for anyone who put these tokens in a format string on purpose.\n */\nexport function translateDayjsFormatString(formatStr: string): string {\n  return translate(formatStr, DAYJS_TO_TEMPORAL_FMT, 'Day.js');\n}\n\n/**\n * Translates a date-fns format string to the equivalent temporal-fmt\n * token string. date-fns already uses Unicode-style tokens close to\n * temporal-fmt's own, so most strings pass through with only a case\n * change on the weekday tokens; the notable divergences are date-fns's\n * `D`/`DD` (day-of-year, matches temporal-fmt already) versus its `d`/\n * `dd` (day-of-month, also matches already) and the locale-dependent\n * `P`/`p` composite tokens, which have no single temporal-fmt token\n * and throw.\n */\nexport function translateDateFnsFormatString(formatStr: string): string {\n  return translate(formatStr, DATE_FNS_TO_TEMPORAL_FMT, 'date-fns');\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Runtime override registry for format() and parse(). Exists for one\n// reason: mods (see modApi.ts) need to be able to swap the real\n// implementation everywhere it's used, not just for whoever imports\n// `format` from the package root. Without this, `interval.ts`'s\n// formatRange() and `serialization.ts`'s formatSQL() would keep calling\n// the original format() forever, since they'd still hold their own\n// direct reference to it — a mod's fix would look like it worked (the\n// export changed) while half the library silently ignored it. That gap\n// is worse than not having overrides at all, so every internal call\n// site that used to `import { format } from './format.js'` now goes\n// through getFormatImpl()/getParseImpl() instead.\n//\n// format.ts and parse.ts themselves are untouched — this module sits\n// beside them, not inside them. Baseline behavior with no mods loaded\n// is exactly what it always was; this is pure indirection, not a\n// rewrite of either implementation.\n\nimport { format as baseFormat, formatToParts as baseFormatToParts } from './format.js';\nimport { parse as baseParse } from './parse.js';\nimport { registerToken } from './tokens.js';\nimport type { CustomToken } from './extensibility.js';\nimport { safeParse as base_safeParse, tryParse as base_tryParse, parseToParts as base_parseToParts } from './parse.js';\nimport { formatDistance as base_formatDistance, formatDistanceToNow as base_formatDistanceToNow } from './formatDistance.js';\nimport { daysInYear as base_daysInYear, getQuarter as base_getQuarter, startOf as base_startOf, endOf as base_endOf } from './calendarUtils.js';\nimport { subtract as base_subtract, difference as base_difference } from './arithmetic.js';\nimport { min as base_min, max as base_max, isWeekend as base_isWeekend } from './comparison.js';\nimport { round as base_round } from './rounding.js';\nimport { parseISO as base_parseISO, formatISO as base_formatISO, formatRFC2822 as base_formatRFC2822, formatHTTPDate as base_formatHTTPDate, fromUnixSeconds as base_fromUnixSeconds, fromUnixMilliseconds as base_fromUnixMilliseconds } from './serialization.js';\nimport { totalDuration as base_totalDuration, addDuration as base_addDuration } from './duration.js';\nimport { formatRelative as base_formatRelative, formatRelativeToNow as base_formatRelativeToNow } from './relativeTime.js';\nimport { convertDigits as base_convertDigits, convertDigitsToAscii as base_convertDigitsToAscii } from './numbering.js';\nimport { intersects as base_intersects, splitInterval as base_splitInterval, formatRange as base_formatRange } from './interval.js';\nimport { recurrence as base_recurrence, take as base_take, skip as base_skip } from './recurrence.js';\nimport { isBusinessDay as base_isBusinessDay, addBusinessDays as base_addBusinessDays, differenceInBusinessDays as base_differenceInBusinessDays, nextBusinessDay as base_nextBusinessDay, previousBusinessDay as base_previousBusinessDay } from './businessCalendar.js';\nimport { holidaysBetween as base_holidaysBetween } from './holidays.js';\nimport { getTimeZone as base_getTimeZone, getOffset as base_getOffset, getOffsetNanoseconds as base_getOffsetNanoseconds, isDST as base_isDST, getTransitions as base_getTransitions } from './timezone.js';\nimport { translateDayjsFormatString as base_translateDayjsFormatString } from './codemod.js';\n\ntype FormatFn = typeof baseFormat;\ntype FormatToPartsFn = typeof baseFormatToParts;\ntype ParseFn = typeof baseParse;\n\ninterface OverrideRecord<Fn> {\n  impl: Fn;\n  // which mod installed this, so a collision or a \"what's active right\n  // now\" query can name it instead of just saying \"something\"\n  installedBy: string;\n}\n\nlet formatOverride: OverrideRecord<FormatFn> | undefined;\nlet formatToPartsOverride: OverrideRecord<FormatToPartsFn> | undefined;\nlet parseOverride: OverrideRecord<ParseFn> | undefined;\n\nexport function getFormatImpl(): FormatFn {\n  return formatOverride ? formatOverride.impl : baseFormat;\n}\n\nexport function getFormatToPartsImpl(): FormatToPartsFn {\n  return formatToPartsOverride ? formatToPartsOverride.impl : baseFormatToParts;\n}\n\nexport function getParseImpl(): ParseFn {\n  return parseOverride ? parseOverride.impl : baseParse;\n}\n\n// Thrown on a second mod trying to override the same point — see\n// modApi.ts's ModContext.overrideFormat/overrideParse for why this is a\n// hard failure rather than last-write-wins like locale/token\n// registration: two mods silently fighting over how dates get\n// formatted is a correctness bug in whatever app depends on this\n// library, not a cosmetic surprise.\nexport class OverrideConflictError extends Error {\n  constructor(\n    public readonly point: string,\n    public readonly existingOwner: string,\n    public readonly attemptedBy: string\n  ) {\n    super(\n      `temporal-fmt: \"${point}\" is already overridden by mod \"${existingOwner}\" — ` +\n      `mod \"${attemptedBy}\" can't also override it. Only one mod may hold each override ` +\n      `point; if \"${attemptedBy}\" needs \"${existingOwner}\"'s behavior included, that logic ` +\n      `needs to move into whichever mod ends up owning the override, not be layered ` +\n      `through a second overrideFormat()/overrideParse() call.`\n    );\n    this.name = 'OverrideConflictError';\n  }\n}\n\nexport function setFormatOverride(impl: FormatFn, installedBy: string): void {\n  if (formatOverride) throw new OverrideConflictError('format', formatOverride.installedBy, installedBy);\n  formatOverride = { impl, installedBy };\n}\n\n// format() over several values with one format string — the two\n// endpoints of formatRange() today. An installed override can expose a\n// batch form (only the mod sandbox's bridge ever does — see\n// scripts/modSandbox.mjs) as a `formatMany` property on its impl; with\n// one present this collapses N calls into one subprocess round trip,\n// and without one it's just the loop the caller would have written.\n// This is the shape the installed wrapper exposes.\nexport type FormatBatchFn = (\n  values: Array<Parameters<FormatFn>[0]>,\n  formatStr: string,\n  options?: Parameters<FormatFn>[2]\n) => string[];\n\n// What the sandbox bridge attaches as impl.formatMany before the wrapper\n// takes it over: same as FormatBatchFn plus the un-overridden format()\n// as a trailing argument, which the bridge's fallback paths need and\n// can't reach on their own (the wrapper injects it — see modApi.ts).\nexport type BridgeFormatBatchFn = (\n  values: Array<Parameters<FormatFn>[0]>,\n  formatStr: string,\n  options: Parameters<FormatFn>[2] | undefined,\n  original: FormatFn\n) => string[];\n\nexport function callFormatImplBatch(\n  values: Array<Parameters<FormatFn>[0]>,\n  formatStr: string,\n  options?: Parameters<FormatFn>[2]\n): string[] {\n  const impl = getFormatImpl() as FormatFn & { formatMany?: FormatBatchFn };\n  if (typeof impl.formatMany === 'function') return impl.formatMany(values, formatStr, options);\n  return values.map((value) => impl(value, formatStr, options));\n}\n\nexport function setFormatToPartsOverride(impl: FormatToPartsFn, installedBy: string): void {\n  if (formatToPartsOverride) throw new OverrideConflictError('formatToParts', formatToPartsOverride.installedBy, installedBy);\n  formatToPartsOverride = { impl, installedBy };\n}\n\nexport function setParseOverride(impl: ParseFn, installedBy: string): void {\n  if (parseOverride) throw new OverrideConflictError('parse', parseOverride.installedBy, installedBy);\n  parseOverride = { impl, installedBy };\n}\n\n// Test-only escape hatch — vitest runs all suites in one process, so\n// without this, an override installed in one test file's mod-loading\n// test would leak into every test that runs after it.\nexport function _resetOverridesForTesting(): void {\n  formatOverride = undefined;\n  formatToPartsOverride = undefined;\n  parseOverride = undefined;\n}\n\n// Adds a custom token into the real, shared token table format()/parse()\n// both read from — not a private copy scoped to one createFormatter()\n// instance (see extensibility.ts for why that's a dead end: a mod-built\n// Formatter is never wired into the module-level format() everything\n// else calls). tokens.ts's registerToken() does the actual table\n// rebuild; this just re-types CustomToken into the tuple shape TOKENS\n// uses internally.\n//\n// Last-write-wins on name, same as registerLocale, not a hard error\n// like setFormatOverride above. Two independent mods each adding one\n// harmless token (PIRATE, LEET, ...) is a plausible, not-really-a-bug\n// scenario, unlike two mods fighting over the one global format()\n// implementation — and Mod.priority already exists so an author can\n// choose who wins a shared key. A hard error here would make priority\n// meaningless for tokens while every other registration kind honors it.\n// This also means a mod CAN shadow a built-in token name (yyyy, MMM,\n// ...); that's consistent with createFormatter's own merge rule, not a\n// new hole, but it's worth calling out because the blast radius here is\n// every format() call in the process, not one formatter instance.\nexport function registerFormatToken(token: CustomToken): void {\n  registerToken([token.name, token.handler, token.field]);\n}\n\n// Resets the 81 generated override points (see bottom of file) — split\n// from the block above so that block still reads clearly as \"the three\n// hand-written ones,\" and this one can be regenerated wholesale by\n// generate.mjs without touching hand-written code.\n\n\nimport { compileFormat as base_compileFormat } from './format.js';\nimport { compileParser as base_compileParser } from './parse.js';\nimport { parseRelative as base_parseRelative } from './parseRelative.js';\nimport { explainFormat as base_explainFormat, tokenizeFormat as base_tokenizeFormat, listTokens as base_listTokens, tokenInfo as base_tokenInfo, isValidFormat as base_isValidFormat, validateFormat as base_validateFormat, fieldForToken as base_fieldForToken } from './analyze.js';\nimport { monthsInYear as base_monthsInYear, isLeapYear as base_isLeapYear, isLeapMonth as base_isLeapMonth, weekOfYear as base_weekOfYear, weekYear as base_weekYear, getMonth as base_getMonth, getWeekday as base_getWeekday } from './calendarUtils.js';\nimport { isEqual as base_isEqual, isBefore as base_isBefore, isAfter as base_isAfter, clamp as base_clamp, isBetween as base_isBetween, isToday as base_isToday, isTomorrow as base_isTomorrow, isYesterday as base_isYesterday, isSameDay as base_isSameDay, isSameWeek as base_isSameWeek, isSameMonth as base_isSameMonth, isSameQuarter as base_isSameQuarter, isSameYear as base_isSameYear, isWeekday as base_isWeekday } from './comparison.js';\nimport { floor as base_floor, ceil as base_ceil, truncate as base_truncate } from './rounding.js';\nimport { parseRFC3339 as base_parseRFC3339, formatRFC3339 as base_formatRFC3339, parseRFC2822 as base_parseRFC2822, parseHTTPDate as base_parseHTTPDate, fromUnixMicroseconds as base_fromUnixMicroseconds, fromUnixNanoseconds as base_fromUnixNanoseconds, toUnixSeconds as base_toUnixSeconds, toUnixMilliseconds as base_toUnixMilliseconds, toUnixMicroseconds as base_toUnixMicroseconds, toUnixNanoseconds as base_toUnixNanoseconds, parseSQL as base_parseSQL, formatSQL as base_formatSQL } from './serialization.js';\nimport { formatDurationToParts as base_formatDurationToParts, parseDuration as base_parseDuration, parseISODuration as base_parseISODuration, formatISODuration as base_formatISODuration, balanceDuration as base_balanceDuration, compareDuration as base_compareDuration, subtractDuration as base_subtractDuration } from './duration.js';\nimport { getLocale as base_getLocale, hasLocale as base_hasLocale } from './localeRegistry.js';\nimport { createConfig as base_createConfig, mergeWithConfig as base_mergeWithConfig } from './config.js';\nimport { listRegisteredGrammars as base_listRegisteredGrammars } from './relativeGrammar.js';\nimport { interval as base_interval, overlaps as base_overlaps, intersection as base_intersection, union as base_union, mergeIntervals as base_mergeIntervals, formatRangeToParts as base_formatRangeToParts } from './interval.js';\nimport { between as base_between, parseRRule as base_parseRRule, formatRRule as base_formatRRule } from './recurrence.js';\nimport { createBusinessCalendar as base_createBusinessCalendar, subtractBusinessDays as base_subtractBusinessDays } from './businessCalendar.js';\nimport { nextHoliday as base_nextHoliday, previousHoliday as base_previousHoliday } from './holidays.js';\nimport { resolveZoned as base_resolveZoned, getNextTransition as base_getNextTransition, getPreviousTransition as base_getPreviousTransition, possibleInstantsFor as base_possibleInstantsFor } from './timezone.js';\nimport { getAutocompleteData as base_getAutocompleteData, getHoverDocs as base_getHoverDocs, getInlineDiagnostics as base_getInlineDiagnostics, previewFormat as base_previewFormat, getDocUrl as base_getDocUrl } from './ideData.js';\nimport { translateDateFnsFormatString as base_translateDateFnsFormatString } from './codemod.js';\n\n// --- Generated override points below ---\n// Same pattern as format/parse above, generalized: one owner per named\n// point, hard collision (not last-write-wins) because two mods silently\n// fighting over a function's behavior is a correctness bug in whatever\n// depends on this library, not a cosmetic surprise. createOverridable\n// exists so this section doesn't repeat the same five-line shape 126\n// times by hand — the behavior is identical to formatOverride/\n// parseOverride above, just factored into one generic instead of typed\n// out per function.\nfunction createOverridable<Fn>(base: Fn, pointName: string) {\n  let current: OverrideRecord<Fn> | undefined;\n  return {\n    get: (): Fn => (current ? current.impl : base),\n    set: (impl: Fn, installedBy: string): void => {\n      if (current) throw new OverrideConflictError(pointName, current.installedBy, installedBy);\n      current = { impl, installedBy };\n    },\n    /* c8 ignore start @preserve -- reset() is only ever called from\n     * _resetGeneratedOverridesForTesting(), which itself is a\n     * vitest-only escape hatch not exported from dist/index.js (see its\n     * own doc comment below) — so this function has no path reachable\n     * from test/*.test.js, which imports only the public dist/index.js\n     * surface. Covered instead by vitest/modApi.unit.test.ts's afterEach\n     * hook, which calls _resetGeneratedOverridesForTesting() directly\n     * against src/runtime.js on every run. */\n    reset: (): void => { current = undefined; },\n    /* c8 ignore stop @preserve */\n  };\n}\n \n\nconst compileFormatRegistry = createOverridable(base_compileFormat, 'compileFormat');\nconst compileParserRegistry = createOverridable(base_compileParser, 'compileParser');\nconst parseRelativeRegistry = createOverridable(base_parseRelative, 'parseRelative');\nconst explainFormatRegistry = createOverridable(base_explainFormat, 'explainFormat');\nconst tokenizeFormatRegistry = createOverridable(base_tokenizeFormat, 'tokenizeFormat');\nconst listTokensRegistry = createOverridable(base_listTokens, 'listTokens');\nconst tokenInfoRegistry = createOverridable(base_tokenInfo, 'tokenInfo');\nconst isValidFormatRegistry = createOverridable(base_isValidFormat, 'isValidFormat');\nconst validateFormatRegistry = createOverridable(base_validateFormat, 'validateFormat');\nconst fieldForTokenRegistry = createOverridable(base_fieldForToken, 'fieldForToken');\nconst monthsInYearRegistry = createOverridable(base_monthsInYear, 'monthsInYear');\nconst isLeapYearRegistry = createOverridable(base_isLeapYear, 'isLeapYear');\nconst isLeapMonthRegistry = createOverridable(base_isLeapMonth, 'isLeapMonth');\nconst weekOfYearRegistry = createOverridable(base_weekOfYear, 'weekOfYear');\nconst weekYearRegistry = createOverridable(base_weekYear, 'weekYear');\nconst getMonthRegistry = createOverridable(base_getMonth, 'getMonth');\nconst getWeekdayRegistry = createOverridable(base_getWeekday, 'getWeekday');\nconst isEqualRegistry = createOverridable(base_isEqual, 'isEqual');\nconst isBeforeRegistry = createOverridable(base_isBefore, 'isBefore');\nconst isAfterRegistry = createOverridable(base_isAfter, 'isAfter');\nconst clampRegistry = createOverridable(base_clamp, 'clamp');\nconst isBetweenRegistry = createOverridable(base_isBetween, 'isBetween');\nconst isTodayRegistry = createOverridable(base_isToday, 'isToday');\nconst isTomorrowRegistry = createOverridable(base_isTomorrow, 'isTomorrow');\nconst isYesterdayRegistry = createOverridable(base_isYesterday, 'isYesterday');\nconst isSameDayRegistry = createOverridable(base_isSameDay, 'isSameDay');\nconst isSameWeekRegistry = createOverridable(base_isSameWeek, 'isSameWeek');\nconst isSameMonthRegistry = createOverridable(base_isSameMonth, 'isSameMonth');\nconst isSameQuarterRegistry = createOverridable(base_isSameQuarter, 'isSameQuarter');\nconst isSameYearRegistry = createOverridable(base_isSameYear, 'isSameYear');\nconst isWeekdayRegistry = createOverridable(base_isWeekday, 'isWeekday');\nconst floorRegistry = createOverridable(base_floor, 'floor');\nconst ceilRegistry = createOverridable(base_ceil, 'ceil');\nconst truncateRegistry = createOverridable(base_truncate, 'truncate');\nconst parseRFC3339Registry = createOverridable(base_parseRFC3339, 'parseRFC3339');\nconst formatRFC3339Registry = createOverridable(base_formatRFC3339, 'formatRFC3339');\nconst parseRFC2822Registry = createOverridable(base_parseRFC2822, 'parseRFC2822');\nconst parseHTTPDateRegistry = createOverridable(base_parseHTTPDate, 'parseHTTPDate');\nconst fromUnixMicrosecondsRegistry = createOverridable(base_fromUnixMicroseconds, 'fromUnixMicroseconds');\nconst fromUnixNanosecondsRegistry = createOverridable(base_fromUnixNanoseconds, 'fromUnixNanoseconds');\nconst toUnixSecondsRegistry = createOverridable(base_toUnixSeconds, 'toUnixSeconds');\nconst toUnixMillisecondsRegistry = createOverridable(base_toUnixMilliseconds, 'toUnixMilliseconds');\nconst toUnixMicrosecondsRegistry = createOverridable(base_toUnixMicroseconds, 'toUnixMicroseconds');\nconst toUnixNanosecondsRegistry = createOverridable(base_toUnixNanoseconds, 'toUnixNanoseconds');\nconst parseSQLRegistry = createOverridable(base_parseSQL, 'parseSQL');\nconst formatSQLRegistry = createOverridable(base_formatSQL, 'formatSQL');\nconst formatDurationToPartsRegistry = createOverridable(base_formatDurationToParts, 'formatDurationToParts');\nconst parseDurationRegistry = createOverridable(base_parseDuration, 'parseDuration');\nconst parseISODurationRegistry = createOverridable(base_parseISODuration, 'parseISODuration');\nconst formatISODurationRegistry = createOverridable(base_formatISODuration, 'formatISODuration');\nconst balanceDurationRegistry = createOverridable(base_balanceDuration, 'balanceDuration');\nconst compareDurationRegistry = createOverridable(base_compareDuration, 'compareDuration');\nconst subtractDurationRegistry = createOverridable(base_subtractDuration, 'subtractDuration');\nconst getLocaleRegistry = createOverridable(base_getLocale, 'getLocale');\nconst hasLocaleRegistry = createOverridable(base_hasLocale, 'hasLocale');\nconst createConfigRegistry = createOverridable(base_createConfig, 'createConfig');\nconst mergeWithConfigRegistry = createOverridable(base_mergeWithConfig, 'mergeWithConfig');\nconst listRegisteredGrammarsRegistry = createOverridable(base_listRegisteredGrammars, 'listRegisteredGrammars');\nconst intervalRegistry = createOverridable(base_interval, 'interval');\nconst overlapsRegistry = createOverridable(base_overlaps, 'overlaps');\nconst intersectionRegistry = createOverridable(base_intersection, 'intersection');\nconst unionRegistry = createOverridable(base_union, 'union');\nconst mergeIntervalsRegistry = createOverridable(base_mergeIntervals, 'mergeIntervals');\nconst formatRangeToPartsRegistry = createOverridable(base_formatRangeToParts, 'formatRangeToParts');\nconst betweenRegistry = createOverridable(base_between, 'between');\nconst parseRRuleRegistry = createOverridable(base_parseRRule, 'parseRRule');\nconst formatRRuleRegistry = createOverridable(base_formatRRule, 'formatRRule');\nconst createBusinessCalendarRegistry = createOverridable(base_createBusinessCalendar, 'createBusinessCalendar');\nconst subtractBusinessDaysRegistry = createOverridable(base_subtractBusinessDays, 'subtractBusinessDays');\nconst nextHolidayRegistry = createOverridable(base_nextHoliday, 'nextHoliday');\nconst previousHolidayRegistry = createOverridable(base_previousHoliday, 'previousHoliday');\nconst resolveZonedRegistry = createOverridable(base_resolveZoned, 'resolveZoned');\nconst getNextTransitionRegistry = createOverridable(base_getNextTransition, 'getNextTransition');\nconst getPreviousTransitionRegistry = createOverridable(base_getPreviousTransition, 'getPreviousTransition');\nconst possibleInstantsForRegistry = createOverridable(base_possibleInstantsFor, 'possibleInstantsFor');\nconst getAutocompleteDataRegistry = createOverridable(base_getAutocompleteData, 'getAutocompleteData');\nconst getHoverDocsRegistry = createOverridable(base_getHoverDocs, 'getHoverDocs');\nconst getInlineDiagnosticsRegistry = createOverridable(base_getInlineDiagnostics, 'getInlineDiagnostics');\nconst previewFormatRegistry = createOverridable(base_previewFormat, 'previewFormat');\nconst getDocUrlRegistry = createOverridable(base_getDocUrl, 'getDocUrl');\nconst translateDateFnsFormatStringRegistry = createOverridable(base_translateDateFnsFormatString, 'translateDateFnsFormatString');\n\nexport const getCompileFormatImpl = compileFormatRegistry.get;\nexport const setCompileFormatOverride = compileFormatRegistry.set;\nexport const getCompileParserImpl = compileParserRegistry.get;\nexport const setCompileParserOverride = compileParserRegistry.set;\nexport const getParseRelativeImpl = parseRelativeRegistry.get;\nexport const setParseRelativeOverride = parseRelativeRegistry.set;\nexport const getExplainFormatImpl = explainFormatRegistry.get;\nexport const setExplainFormatOverride = explainFormatRegistry.set;\nexport const getTokenizeFormatImpl = tokenizeFormatRegistry.get;\nexport const setTokenizeFormatOverride = tokenizeFormatRegistry.set;\nexport const getListTokensImpl = listTokensRegistry.get;\nexport const setListTokensOverride = listTokensRegistry.set;\nexport const getTokenInfoImpl = tokenInfoRegistry.get;\nexport const setTokenInfoOverride = tokenInfoRegistry.set;\nexport const getIsValidFormatImpl = isValidFormatRegistry.get;\nexport const setIsValidFormatOverride = isValidFormatRegistry.set;\nexport const getValidateFormatImpl = validateFormatRegistry.get;\nexport const setValidateFormatOverride = validateFormatRegistry.set;\nexport const getFieldForTokenImpl = fieldForTokenRegistry.get;\nexport const setFieldForTokenOverride = fieldForTokenRegistry.set;\nexport const getMonthsInYearImpl = monthsInYearRegistry.get;\nexport const setMonthsInYearOverride = monthsInYearRegistry.set;\nexport const getIsLeapYearImpl = isLeapYearRegistry.get;\nexport const setIsLeapYearOverride = isLeapYearRegistry.set;\nexport const getIsLeapMonthImpl = isLeapMonthRegistry.get;\nexport const setIsLeapMonthOverride = isLeapMonthRegistry.set;\nexport const getWeekOfYearImpl = weekOfYearRegistry.get;\nexport const setWeekOfYearOverride = weekOfYearRegistry.set;\nexport const getWeekYearImpl = weekYearRegistry.get;\nexport const setWeekYearOverride = weekYearRegistry.set;\nexport const getGetMonthImpl = getMonthRegistry.get;\nexport const setGetMonthOverride = getMonthRegistry.set;\nexport const getGetWeekdayImpl = getWeekdayRegistry.get;\nexport const setGetWeekdayOverride = getWeekdayRegistry.set;\nexport const getIsEqualImpl = isEqualRegistry.get;\nexport const setIsEqualOverride = isEqualRegistry.set;\nexport const getIsBeforeImpl = isBeforeRegistry.get;\nexport const setIsBeforeOverride = isBeforeRegistry.set;\nexport const getIsAfterImpl = isAfterRegistry.get;\nexport const setIsAfterOverride = isAfterRegistry.set;\nexport const getClampImpl = clampRegistry.get;\nexport const setClampOverride = clampRegistry.set;\nexport const getIsBetweenImpl = isBetweenRegistry.get;\nexport const setIsBetweenOverride = isBetweenRegistry.set;\nexport const getIsTodayImpl = isTodayRegistry.get;\nexport const setIsTodayOverride = isTodayRegistry.set;\nexport const getIsTomorrowImpl = isTomorrowRegistry.get;\nexport const setIsTomorrowOverride = isTomorrowRegistry.set;\nexport const getIsYesterdayImpl = isYesterdayRegistry.get;\nexport const setIsYesterdayOverride = isYesterdayRegistry.set;\nexport const getIsSameDayImpl = isSameDayRegistry.get;\nexport const setIsSameDayOverride = isSameDayRegistry.set;\nexport const getIsSameWeekImpl = isSameWeekRegistry.get;\nexport const setIsSameWeekOverride = isSameWeekRegistry.set;\nexport const getIsSameMonthImpl = isSameMonthRegistry.get;\nexport const setIsSameMonthOverride = isSameMonthRegistry.set;\nexport const getIsSameQuarterImpl = isSameQuarterRegistry.get;\nexport const setIsSameQuarterOverride = isSameQuarterRegistry.set;\nexport const getIsSameYearImpl = isSameYearRegistry.get;\nexport const setIsSameYearOverride = isSameYearRegistry.set;\nexport const getIsWeekdayImpl = isWeekdayRegistry.get;\nexport const setIsWeekdayOverride = isWeekdayRegistry.set;\nexport const getFloorImpl = floorRegistry.get;\nexport const setFloorOverride = floorRegistry.set;\nexport const getCeilImpl = ceilRegistry.get;\nexport const setCeilOverride = ceilRegistry.set;\nexport const getTruncateImpl = truncateRegistry.get;\nexport const setTruncateOverride = truncateRegistry.set;\nexport const getParseRFC3339Impl = parseRFC3339Registry.get;\nexport const setParseRFC3339Override = parseRFC3339Registry.set;\nexport const getFormatRFC3339Impl = formatRFC3339Registry.get;\nexport const setFormatRFC3339Override = formatRFC3339Registry.set;\nexport const getParseRFC2822Impl = parseRFC2822Registry.get;\nexport const setParseRFC2822Override = parseRFC2822Registry.set;\nexport const getParseHTTPDateImpl = parseHTTPDateRegistry.get;\nexport const setParseHTTPDateOverride = parseHTTPDateRegistry.set;\nexport const getFromUnixMicrosecondsImpl = fromUnixMicrosecondsRegistry.get;\nexport const setFromUnixMicrosecondsOverride = fromUnixMicrosecondsRegistry.set;\nexport const getFromUnixNanosecondsImpl = fromUnixNanosecondsRegistry.get;\nexport const setFromUnixNanosecondsOverride = fromUnixNanosecondsRegistry.set;\nexport const getToUnixSecondsImpl = toUnixSecondsRegistry.get;\nexport const setToUnixSecondsOverride = toUnixSecondsRegistry.set;\nexport const getToUnixMillisecondsImpl = toUnixMillisecondsRegistry.get;\nexport const setToUnixMillisecondsOverride = toUnixMillisecondsRegistry.set;\nexport const getToUnixMicrosecondsImpl = toUnixMicrosecondsRegistry.get;\nexport const setToUnixMicrosecondsOverride = toUnixMicrosecondsRegistry.set;\nexport const getToUnixNanosecondsImpl = toUnixNanosecondsRegistry.get;\nexport const setToUnixNanosecondsOverride = toUnixNanosecondsRegistry.set;\nexport const getParseSQLImpl = parseSQLRegistry.get;\nexport const setParseSQLOverride = parseSQLRegistry.set;\nexport const getFormatSQLImpl = formatSQLRegistry.get;\nexport const setFormatSQLOverride = formatSQLRegistry.set;\nexport const getFormatDurationToPartsImpl = formatDurationToPartsRegistry.get;\nexport const setFormatDurationToPartsOverride = formatDurationToPartsRegistry.set;\nexport const getParseDurationImpl = parseDurationRegistry.get;\nexport const setParseDurationOverride = parseDurationRegistry.set;\nexport const getParseISODurationImpl = parseISODurationRegistry.get;\nexport const setParseISODurationOverride = parseISODurationRegistry.set;\nexport const getFormatISODurationImpl = formatISODurationRegistry.get;\nexport const setFormatISODurationOverride = formatISODurationRegistry.set;\nexport const getBalanceDurationImpl = balanceDurationRegistry.get;\nexport const setBalanceDurationOverride = balanceDurationRegistry.set;\nexport const getCompareDurationImpl = compareDurationRegistry.get;\nexport const setCompareDurationOverride = compareDurationRegistry.set;\nexport const getSubtractDurationImpl = subtractDurationRegistry.get;\nexport const setSubtractDurationOverride = subtractDurationRegistry.set;\nexport const getGetLocaleImpl = getLocaleRegistry.get;\nexport const setGetLocaleOverride = getLocaleRegistry.set;\nexport const getHasLocaleImpl = hasLocaleRegistry.get;\nexport const setHasLocaleOverride = hasLocaleRegistry.set;\nexport const getCreateConfigImpl = createConfigRegistry.get;\nexport const setCreateConfigOverride = createConfigRegistry.set;\nexport const getMergeWithConfigImpl = mergeWithConfigRegistry.get;\nexport const setMergeWithConfigOverride = mergeWithConfigRegistry.set;\nexport const getListRegisteredGrammarsImpl = listRegisteredGrammarsRegistry.get;\nexport const setListRegisteredGrammarsOverride = listRegisteredGrammarsRegistry.set;\nexport const getIntervalImpl = intervalRegistry.get;\nexport const setIntervalOverride = intervalRegistry.set;\nexport const getOverlapsImpl = overlapsRegistry.get;\nexport const setOverlapsOverride = overlapsRegistry.set;\nexport const getIntersectionImpl = intersectionRegistry.get;\nexport const setIntersectionOverride = intersectionRegistry.set;\nexport const getUnionImpl = unionRegistry.get;\nexport const setUnionOverride = unionRegistry.set;\nexport const getMergeIntervalsImpl = mergeIntervalsRegistry.get;\nexport const setMergeIntervalsOverride = mergeIntervalsRegistry.set;\nexport const getFormatRangeToPartsImpl = formatRangeToPartsRegistry.get;\nexport const setFormatRangeToPartsOverride = formatRangeToPartsRegistry.set;\nexport const getBetweenImpl = betweenRegistry.get;\nexport const setBetweenOverride = betweenRegistry.set;\nexport const getParseRRuleImpl = parseRRuleRegistry.get;\nexport const setParseRRuleOverride = parseRRuleRegistry.set;\nexport const getFormatRRuleImpl = formatRRuleRegistry.get;\nexport const setFormatRRuleOverride = formatRRuleRegistry.set;\nexport const getCreateBusinessCalendarImpl = createBusinessCalendarRegistry.get;\nexport const setCreateBusinessCalendarOverride = createBusinessCalendarRegistry.set;\nexport const getSubtractBusinessDaysImpl = subtractBusinessDaysRegistry.get;\nexport const setSubtractBusinessDaysOverride = subtractBusinessDaysRegistry.set;\nexport const getNextHolidayImpl = nextHolidayRegistry.get;\nexport const setNextHolidayOverride = nextHolidayRegistry.set;\nexport const getPreviousHolidayImpl = previousHolidayRegistry.get;\nexport const setPreviousHolidayOverride = previousHolidayRegistry.set;\nexport const getResolveZonedImpl = resolveZonedRegistry.get;\nexport const setResolveZonedOverride = resolveZonedRegistry.set;\nexport const getGetNextTransitionImpl = getNextTransitionRegistry.get;\nexport const setGetNextTransitionOverride = getNextTransitionRegistry.set;\nexport const getGetPreviousTransitionImpl = getPreviousTransitionRegistry.get;\nexport const setGetPreviousTransitionOverride = getPreviousTransitionRegistry.set;\nexport const getPossibleInstantsForImpl = possibleInstantsForRegistry.get;\nexport const setPossibleInstantsForOverride = possibleInstantsForRegistry.set;\nexport const getGetAutocompleteDataImpl = getAutocompleteDataRegistry.get;\nexport const setGetAutocompleteDataOverride = getAutocompleteDataRegistry.set;\nexport const getGetHoverDocsImpl = getHoverDocsRegistry.get;\nexport const setGetHoverDocsOverride = getHoverDocsRegistry.set;\nexport const getGetInlineDiagnosticsImpl = getInlineDiagnosticsRegistry.get;\nexport const setGetInlineDiagnosticsOverride = getInlineDiagnosticsRegistry.set;\nexport const getPreviewFormatImpl = previewFormatRegistry.get;\nexport const setPreviewFormatOverride = previewFormatRegistry.set;\nexport const getGetDocUrlImpl = getDocUrlRegistry.get;\nexport const setGetDocUrlOverride = getDocUrlRegistry.set;\nexport const getTranslateDateFnsFormatStringImpl = translateDateFnsFormatStringRegistry.get;\nexport const setTranslateDateFnsFormatStringOverride = translateDateFnsFormatStringRegistry.set;\n\n// Resets the 81 generated override points above — split from\n// _resetOverridesForTesting so that one still reads clearly as \"the\n// three hand-written ones,\" and this one can be regenerated wholesale\n// by generate.mjs without touching hand-written code.\nexport function _resetGeneratedOverridesForTesting(): void {\n  compileFormatRegistry.reset();\n  compileParserRegistry.reset();\n  parseRelativeRegistry.reset();\n  explainFormatRegistry.reset();\n  tokenizeFormatRegistry.reset();\n  listTokensRegistry.reset();\n  tokenInfoRegistry.reset();\n  isValidFormatRegistry.reset();\n  validateFormatRegistry.reset();\n  fieldForTokenRegistry.reset();\n  monthsInYearRegistry.reset();\n  isLeapYearRegistry.reset();\n  isLeapMonthRegistry.reset();\n  weekOfYearRegistry.reset();\n  weekYearRegistry.reset();\n  getMonthRegistry.reset();\n  getWeekdayRegistry.reset();\n  isEqualRegistry.reset();\n  isBeforeRegistry.reset();\n  isAfterRegistry.reset();\n  clampRegistry.reset();\n  isBetweenRegistry.reset();\n  isTodayRegistry.reset();\n  isTomorrowRegistry.reset();\n  isYesterdayRegistry.reset();\n  isSameDayRegistry.reset();\n  isSameWeekRegistry.reset();\n  isSameMonthRegistry.reset();\n  isSameQuarterRegistry.reset();\n  isSameYearRegistry.reset();\n  isWeekdayRegistry.reset();\n  floorRegistry.reset();\n  ceilRegistry.reset();\n  truncateRegistry.reset();\n  parseRFC3339Registry.reset();\n  formatRFC3339Registry.reset();\n  parseRFC2822Registry.reset();\n  parseHTTPDateRegistry.reset();\n  fromUnixMicrosecondsRegistry.reset();\n  fromUnixNanosecondsRegistry.reset();\n  toUnixSecondsRegistry.reset();\n  toUnixMillisecondsRegistry.reset();\n  toUnixMicrosecondsRegistry.reset();\n  toUnixNanosecondsRegistry.reset();\n  parseSQLRegistry.reset();\n  formatSQLRegistry.reset();\n  formatDurationToPartsRegistry.reset();\n  parseDurationRegistry.reset();\n  parseISODurationRegistry.reset();\n  formatISODurationRegistry.reset();\n  balanceDurationRegistry.reset();\n  compareDurationRegistry.reset();\n  subtractDurationRegistry.reset();\n  getLocaleRegistry.reset();\n  hasLocaleRegistry.reset();\n  createConfigRegistry.reset();\n  mergeWithConfigRegistry.reset();\n  listRegisteredGrammarsRegistry.reset();\n  intervalRegistry.reset();\n  overlapsRegistry.reset();\n  intersectionRegistry.reset();\n  unionRegistry.reset();\n  mergeIntervalsRegistry.reset();\n  formatRangeToPartsRegistry.reset();\n  betweenRegistry.reset();\n  parseRRuleRegistry.reset();\n  formatRRuleRegistry.reset();\n  createBusinessCalendarRegistry.reset();\n  subtractBusinessDaysRegistry.reset();\n  nextHolidayRegistry.reset();\n  previousHolidayRegistry.reset();\n  resolveZonedRegistry.reset();\n  getNextTransitionRegistry.reset();\n  getPreviousTransitionRegistry.reset();\n  possibleInstantsForRegistry.reset();\n  getAutocompleteDataRegistry.reset();\n  getHoverDocsRegistry.reset();\n  getInlineDiagnosticsRegistry.reset();\n  previewFormatRegistry.reset();\n  getDocUrlRegistry.reset();\n  translateDateFnsFormatStringRegistry.reset();\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { isGregorianLeapYear, daysFromCivil } from './isoWeek.js';\nimport { normalizeLocaleTag } from './localeVocab.js';\nimport { InvalidLocaleError, InvalidDateError } from './errors.js';\n\n// Reads date fields off a Temporal value in the same minimal-shape style\n// as the rest of the library (TemporalLike) — no Temporal factory needed.\n// Works for PlainDate, PlainDateTime, and ZonedDateTime (since they all\n// expose year/month/day). PlainTime has no date fields; formatDistance()\n// between two PlainTime values isn't really meaningful and isn't\n// supported — it'll throw below when the field read fails.\ninterface DateFieldView {\n  year?: number;\n  month?: number;\n  day?: number;\n  hour?: number;\n  minute?: number;\n  second?: number;\n  millisecond?: number;\n}\n\nfunction readFields(value: unknown, label: string): DateFieldView {\n  if (value === null || typeof value !== 'object') {\n    throw new Error(\n      `temporal-fmt: formatDistance expects Temporal values, got ${label} = ${String(value)}.`\n    );\n  }\n  const obj = value as Record<string, unknown>;\n  // Either year/month/day (a real date) or none of them (a PlainTime);\n  // anything in between would be a malformed Temporal-like.\n  const hasYear = typeof obj.year === 'number';\n  const hasMonth = typeof obj.month === 'number';\n  const hasDay = typeof obj.day === 'number';\n  if (hasYear !== hasMonth || hasMonth !== hasDay) {\n    throw new Error(\n      `temporal-fmt: formatDistance got a ${label} with a partial date (some of year/month/day missing). ` +\n      `Pass a full Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n    );\n  }\n  // Range validation on the date triple. This function accepts plain\n  // field bags (documented duck-typing), so the fields are untrusted\n  // caller data, and every downstream consumer assumed a real calendar\n  // date: a year of 1e9 used to drive a O(|year|) day-accumulation loop\n  // (hundreds of ms per call — a cheap CPU-denial primitive when an app\n  // feeds user-controlled parsed values in), and month 0 / Feb 31 fell\n  // through to either V8-internal Intl errors or silently-wrong\n  // distances. Real Temporal values always pass these checks, so this\n  // only ever fires on hostile/hand-rolled bags.\n  if (hasYear) {\n    const y = obj.year as number;\n    const m = obj.month as number;\n    const d = obj.day as number;\n    if (!Number.isFinite(y) || !Number.isInteger(y) || y < MIN_YEAR || y > MAX_YEAR) {\n      throw new InvalidDateError({\n        input: label,\n        reason: `year ${y} is outside the ${MIN_YEAR}..${MAX_YEAR} range Temporal can represent`,\n      });\n    }\n    if (!Number.isInteger(m) || m < 1 || m > 12) {\n      throw new InvalidDateError({\n        input: label,\n        reason: `month ${m} is not in 1..12`,\n      });\n    }\n    const maxDay = m === 2 && isGregorianLeapYear(y) ? 29 : [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1]!;\n    if (!Number.isInteger(d) || d < 1 || d > maxDay) {\n      throw new InvalidDateError({\n        input: label,\n        reason: `day ${d} is not valid for year ${y}, month ${m} (max ${maxDay})`,\n      });\n    }\n  }\n  return {\n    year: hasYear ? (obj.year as number) : undefined,\n    month: hasMonth ? (obj.month as number) : undefined,\n    day: hasDay ? (obj.day as number) : undefined,\n    hour: typeof obj.hour === 'number' ? (obj.hour as number) : undefined,\n    minute: typeof obj.minute === 'number' ? (obj.minute as number) : undefined,\n    second: typeof obj.second === 'number' ? (obj.second as number) : undefined,\n    millisecond: typeof obj.millisecond === 'number' ? (obj.millisecond as number) : undefined,\n  };\n}\n\n// Temporal's representable ISO year range (PlainDate accepts -271821\n// through 275760). Values beyond this can't come from a real Temporal\n// object, so they're rejected as malformed input rather than walked.\nconst MIN_YEAR = -271_821;\nconst MAX_YEAR = 275_760;\n\n// Reference epoch for ms-since computation. Jan 1, 2000 UTC is the same\n// anchor isoWeek.ts uses for day-of-week arithmetic; reusing it keeps the\n// reasoning localized to one well-known reference date.\nconst REFERENCE_YEAR = 2000;\nconst MS_PER_SECOND = 1000;\nconst MS_PER_MINUTE = 60 * MS_PER_SECOND;\nconst MS_PER_HOUR = 60 * MS_PER_MINUTE;\nconst MS_PER_DAY = 24 * MS_PER_HOUR;\n\nfunction daysSinceReference(year: number, month: number, day: number): number {\n  // O(1): days_from_civil for the target minus days_from_civil for the\n  // reference. The old version accumulated 365/366 per year in a loop —\n  // identical results for every real date, but O(|year − 2000|), which\n  // made hostile field-bag years (1e9+) an accidental CPU-denial\n  // primitive. (Range validation in readFields already rejects years\n  // Temporal can't represent; this closed form makes even the\n  // in-range walk instant.)\n  return daysFromCivil(year, month, day) - daysFromCivil(REFERENCE_YEAR, 1, 1);\n}\n\nfunction toEpochMs(fields: DateFieldView): number {\n  // A PlainDate has no time fields — treat as midnight. A PlainDateTime\n  // has them all. Comparing two PlainDates is a day-resolution diff;\n  // comparing two PlainDateTimes is millisecond-resolution. Mixing the\n  // two (one PlainDate, one PlainDateTime) is allowed and just means the\n  // PlainDate side is treated as midnight, which is what most callers\n  // would intuitively expect (\"distance from this date to this moment\").\n  if (fields.year === undefined || fields.month === undefined || fields.day === undefined) {\n    throw new Error(\n      `temporal-fmt: formatDistance needs a Temporal value with year/month/day fields ` +\n      `(PlainDate, PlainDateTime, or ZonedDateTime). A PlainTime or other shape ` +\n      `has no anchor date to diff against.`\n    );\n  }\n  const days = daysSinceReference(fields.year, fields.month, fields.day);\n  const hour = fields.hour ?? 0;\n  const minute = fields.minute ?? 0;\n  const second = fields.second ?? 0;\n  const millisecond = fields.millisecond ?? 0;\n  return days * MS_PER_DAY + hour * MS_PER_HOUR + minute * MS_PER_MINUTE + second * MS_PER_SECOND + millisecond;\n}\n\n// Unit selection cutoffs. Mirrors the rough thresholds date-fns uses,\n// trimmed to the units Intl.RelativeTimeFormat supports in every engine\n// (it accepts 'second' through 'year'; 'quarter' and 'week' support\n// varies, so we skip 'week' here — going days → months directly at the\n// 30-day boundary is simpler and avoids the engine-support cliff).\n//\n//   |diff| < 60 s   → seconds  (\"30 seconds ago\")\n//   |diff| < 60 min → minutes  (\"12 minutes ago\")\n//   |diff| < 24 h   → hours    (\"3 hours ago\")\n//   |diff| < 30 d   → days     (\"5 days ago\")\n//   |diff| < 365 d  → months   (\"2 months ago\")\n//   otherwise      → years    (\"1 year ago\")\n//\n// 30 days is an approximation of a month — a calendar month is 28-31\n// days, so the boundary is inherently fuzzy. Same with 365 days for a\n// year. Documented as approximations, not exact calendar arithmetic.\n//\n// `cutoffs` on FormatDistanceOptions overrides individual boundaries\n// per call. DEFAULT_CUTOFFS holds the same numbers as the old hardcoded\n// UNIT_CUTOFFS so callers passing nothing see the same output as\n// before — verified byte-for-byte against the pre-change baseline.\nconst DEFAULT_CUTOFFS = {\n  seconds: 60,   // 60 s\n  minutes: 60,   // 60 min\n  hours: 24,     // 24 h\n  days: 30,      // 30 d\n  months: 365,   // 365 d (in days, since the months→years boundary is day-resolution)\n} as const;\n\ntype CutoffKey = keyof typeof DEFAULT_CUTOFFS;\n\n// Cutoffs the caller can override. Each value is in the unit's own\n// native scale (seconds for `seconds`, minutes for `minutes`, etc.) —\n// `months` is the exception: it's the day count that bounds the\n// months→years crossover, since \"months\" itself isn't a fixed number\n// of days. This mirrors how the original hardcoded table expressed\n// the same boundary (30 * MS_PER_DAY for days, 365 * MS_PER_DAY for\n// the months cap) and lets callers say \"treat anything under 90 days\n// as months\" rather than \"anything under 3 months as months\" (which\n// would require picking a definition of \"month\").\nexport interface DistanceCutoffs {\n  seconds?: number;\n  minutes?: number;\n  hours?: number;\n  days?: number;\n  months?: number;\n}\n\n// Convert the user-facing cutoffs (per-unit numbers) into the ms\n// thresholds the matching loop needs. Validates each value is a\n// positive finite number, and that the boundaries are monotonically\n// non-decreasing in equivalent ms — without that, the smallest-bound\n// branch always wins and a later branch becomes unreachable, which\n// is never what the caller intended.\nfunction resolveCutoffs(user?: DistanceCutoffs): Array<{ maxMs: number; unit: Intl.RelativeTimeFormatUnit }> {\n  const merged: Record<CutoffKey, number> = { ...DEFAULT_CUTOFFS, ...user };\n\n  for (const key of Object.keys(merged) as CutoffKey[]) {\n    const value = merged[key];\n    if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n      throw new Error(\n        `temporal-fmt: formatDistance cutoff \"${key}\" must be a positive finite number (got ${String(value)}).`\n      );\n    }\n  }\n\n  const secondsMs = merged.seconds * MS_PER_SECOND;\n  const minutesMs = merged.minutes * MS_PER_MINUTE;\n  const hoursMs = merged.hours * MS_PER_HOUR;\n  const daysMs = merged.days * MS_PER_DAY;\n  // `months` is in days — see DistanceCutoffs comment above.\n  const monthsMs = merged.months * MS_PER_DAY;\n\n  if (!(secondsMs <= minutesMs && minutesMs <= hoursMs && hoursMs <= daysMs && daysMs <= monthsMs)) {\n    throw new Error(\n      `temporal-fmt: formatDistance cutoffs must be monotonically non-decreasing in equivalent ms ` +\n      `(seconds ≤ minutes ≤ hours ≤ days ≤ months). Got: seconds=${merged.seconds}s, ` +\n      `minutes=${merged.minutes}min, hours=${merged.hours}h, days=${merged.days}d, months=${merged.months}d — ` +\n      `pick a sequence where each boundary is at least as large as the one before it.`\n    );\n  }\n\n  return [\n    { maxMs: secondsMs, unit: 'second' },\n    { maxMs: minutesMs, unit: 'minute' },\n    { maxMs: hoursMs, unit: 'hour' },\n    { maxMs: daysMs, unit: 'day' },\n    { maxMs: monthsMs, unit: 'month' },\n  ];\n}\n\nconst rtfCache = new Map<string, Intl.RelativeTimeFormat>();\nconst MAX_RTF_CACHE_SIZE = 100;\n\nfunction getRtf(locale: string, numeric: 'always' | 'auto'): Intl.RelativeTimeFormat {\n  const key = `${canonicalLocaleKey(locale)}|${numeric}`;\n  let rtf = rtfCache.get(key);\n  if (rtf) return rtf;\n  if (rtfCache.size >= MAX_RTF_CACHE_SIZE) {\n    const oldestKey = rtfCache.keys().next().value;\n    if (oldestKey !== undefined) rtfCache.delete(oldestKey);\n  }\n  try {\n    rtf = new Intl.RelativeTimeFormat(normalizeLocaleTag(locale), { numeric });\n  } catch (err) {\n    // Malformed locale tags reach Intl as a bare RangeError; surface the\n    // library's typed error instead. (Every failure mode of these\n    // constructors with a string locale is a RangeError, so converting\n    // unconditionally loses nothing — the original message is preserved\n    // in `reason` either way.)\n    throw new InvalidLocaleError({ actual: locale, reason: (err as Error).message });\n  }\n  rtfCache.set(key, rtf);\n  return rtf;\n}\n\nfunction canonicalLocaleKey(locale: string): string {\n  try {\n    return new Intl.Locale(locale.replace(/_/g, '-')).toString().toLowerCase();\n  } catch {\n    return locale;\n  }\n}\n\nexport interface FormatDistanceOptions extends FormatOptions {\n  /**\n   * 'auto' (default) lets Intl.RelativeTimeFormat use natural forms like\n   * \"yesterday\"/\"tomorrow\"/\"now\" when the rounded value lands on ±1 or 0.\n   * 'always' forces the strict \"1 day ago\"/\"in 1 day\"/\"in 0 seconds\" form.\n   */\n  numeric?: 'always' | 'auto';\n  /**\n   * Override the unit-selection boundaries (seconds→minutes,\n   * minutes→hours, hours→days, days→months, months→years). Any\n   * subset can be supplied; omitted boundaries fall back to the\n   * defaults (60s, 60min, 24h, 30d, 365d). Values are in each\n   * unit's native scale except `months`, which is in days — see\n   * DistanceCutoffs. Throws descriptively on non-monotonic\n   * boundaries or non-positive values, rather than producing\n   * confusing output downstream.\n   */\n  cutoffs?: DistanceCutoffs;\n}\n\n/**\n * Returns a human-readable relative-time string describing `date1`\n * relative to `date2`, e.g. \"3 days ago\", \"in 2 hours\", \"now\". Delegates\n * unit names and pluralization to `Intl.RelativeTimeFormat` so the\n * output localizes the same way the rest of the library's locale-aware\n * tokens do.\n *\n * Convention: the result describes `date1`'s position relative to\n * `date2`. `formatDistance(now, threeDaysAgo)` → `\"3 days ago\"` (the\n * past date is described relative to now). `formatDistance(now, twoHoursFromNow)`\n * → `\"in 2 hours\"`. This matches the natural-language reading \"describe\n * the first date as if standing at the second one.\"\n *\n * Unit-selection cutoffs (seconds → minutes → hours → days → months →\n * years) and the rationale for each are documented in the README under\n * \"formatDistance\".\n *\n * @example\n * formatDistance(threeDaysAgo, today)              // \"3 days ago\"\n * formatDistance(twoHoursFromNow, today)          // \"in 2 hours\"\n * formatDistance(today, today)                      // \"now\"\n * formatDistance(futureDate, today, {locale:'fr-FR'}) // \"dans 2 jours\"\n */\nexport function formatDistance(\n  date1: unknown,\n  date2: unknown,\n  options: FormatDistanceOptions = {},\n): string {\n  const fields1 = readFields(date1, 'date1');\n  const fields2 = readFields(date2, 'date2');\n\n  // diff > 0: date1 is later than date2 → \"in X units\" (date1 is in\n  // the future relative to date2). diff < 0: date1 is earlier than\n  // date2 → \"X units ago\". This convention puts date1 in the\n  // \"described\" role and date2 in the \"reference\" role, matching\n  // natural-language reading: `formatDistance(threeDaysAgo, today)`\n  // = \"describe threeDaysAgo as if standing at today\" = \"3 days ago\".\n  const diffMs = toEpochMs(fields1) - toEpochMs(fields2);\n  const absMs = Math.abs(diffMs);\n\n  const unitCutoffs = resolveCutoffs(options.cutoffs);\n  let unit: Intl.RelativeTimeFormatUnit = 'year';\n  for (const { maxMs, unit: candidateUnit } of unitCutoffs) {\n    if (absMs < maxMs) {\n      unit = candidateUnit;\n      break;\n    }\n  }\n\n  const divisor = unitToMs(unit);\n  const rounded = Math.round(diffMs / divisor);\n\n  const numeric = options.numeric ?? 'auto';\n  const locale = options.locale ?? DEFAULT_LOCALE;\n  const rtf = getRtf(locale, numeric);\n  return rtf.format(rounded, unit);\n}\n\n/**\n * Same as formatDistance(date, now), where \"now\" is read from the system\n * clock at call time. Convenience wrapper for the common \"how long ago\n * was this\" case, so the caller doesn't have to construct a reference\n * value themselves.\n *\n * Unlike formatRelativeToNow() (in relativeTime.ts), which only needs\n * calendar-day resolution, this reads the full wall-clock time (hour\n * through millisecond) off the system clock — formatDistance's unit\n * selection is ms-resolution, so a date-only \"now\" would misclassify\n * anything under 24 hours old (e.g. \"1 hour ago\" reading as \"in 23\n * hours\" against a midnight-truncated reference). See the test file\n * for a regression case covering exactly that.\n *\n * The reference is captured fresh on every call, not memoized — each\n * call reflects \"now\" at the moment it runs, same expectation\n * formatRelativeToNow() already sets.\n *\n * @example\n * formatDistanceToNow(threeHoursAgo)  // \"3 hours ago\"\n * formatDistanceToNow(tomorrow)       // \"in 1 day\" (auto: \"tomorrow\")\n */\nexport function formatDistanceToNow(\n  date: unknown,\n  options: FormatDistanceOptions = {},\n): string {\n  const now = new Date();\n  const nowFields = {\n    year: now.getFullYear(),\n    month: now.getMonth() + 1,\n    day: now.getDate(),\n    hour: now.getHours(),\n    minute: now.getMinutes(),\n    second: now.getSeconds(),\n    millisecond: now.getMilliseconds(),\n  };\n  return formatDistance(date, nowFields, options);\n}\n\nfunction unitToMs(unit: Intl.RelativeTimeFormatUnit): number {\n  switch (unit) {\n    case 'second': return MS_PER_SECOND;\n    case 'minute': return MS_PER_MINUTE;\n    case 'hour': return MS_PER_HOUR;\n    case 'day': return MS_PER_DAY;\n    /* c8 ignore start @preserve -- unreachable: unitToMs is only called\n       with `unit` values produced by formatDistance's cutoff loop above,\n       which only ever yields 'second'/'minute'/'hour'/'day'/'month'\n       (from resolveCutoffs' fixed array) or 'year' (the loop's fallback\n       default). 'week' and 'quarter' were never wired into\n       resolveCutoffs — formatDistance intentionally skips week-\n       resolution output (see the comment above DEFAULT_CUTOFFS) — so\n       neither can reach this switch. */\n    case 'week': return 7 * MS_PER_DAY;\n    /* c8 ignore stop @preserve */\n    case 'month': return 30 * MS_PER_DAY;\n    /* c8 ignore start @preserve -- unreachable, same reason as 'week'\n       above: resolveCutoffs never produces 'quarter'. */\n    case 'quarter': return 91 * MS_PER_DAY;\n    /* c8 ignore stop @preserve */\n    case 'year': return 365 * MS_PER_DAY;\n    /* c8 ignore start @preserve -- unreachable: every unit\n       resolveCutoffs can actually produce ('second' through 'month', or\n       'year' as the loop's fallback default) has an explicit case\n       above, so this exhaustive-switch default can't fire at runtime.\n       It exists so TS accepts the function as total — the compiler\n       can't see through the cutoff-array iteration in formatDistance()\n       to know the input is already narrowed. */\n    default:\n      throw new Error(`temporal-fmt: formatDistance hit unhandled unit \"${String(unit)}\".`);\n    /* c8 ignore stop @preserve */\n  }\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// type guards for Temporal values. the rest of this lib works off the\n// duck-typed TemporalLike shape (year/month/day/hour/...) instead of\n// `instanceof Temporal.X`, because instanceof just breaks across\n// polyfill/native boundaries — a polyfill's Temporal.PlainDate is a\n// completely different constructor from the native one, so\n// `value instanceof Temporal.PlainDate` would silently fail if the\n// caller's using a polyfill while the guard's looking at native\n// Temporal, or the other way around. same reasoning as tokens.ts's\n// intlSupportsNativeTemporal probe — identity checks just don't survive\n// a polyfill/native swap.\n//\n// so instead these guards check structural shape: does it have the\n// type-discriminating method each Temporal type carries. method\n// presence is part of the actual Temporal spec contract — every\n// implementation, native or polyfill, has to expose the same methods on\n// the same types — so it's a stable signal without needing to import a\n// Temporal namespace at all.\n//\n// per-type discriminators (double checked these against\n// @js-temporal/polyfill's actual prototype method list, matches spec):\n//\n//   PlainDate       — toPlainDateTime + withCalendar + year/month/day,\n//                     no hour. (PlainDateTime also has toPlainDateTime's\n//                     sibling toPlainDate/toPlainTime, but carries hour —\n//                     that's what distinguishes them.)\n//   PlainTime       — no toPlainDateTime, no withCalendar. has hour,\n//                     no year/month/day. (only Temporal date/time type\n//                     with neither withCalendar nor any toPlainX method.)\n//   PlainDateTime   — toPlainDate + withPlainTime + year/month/day\n//                     AND hour. (withPlainTime is unique — only\n//                     PlainDateTime and ZonedDateTime carry it;\n//                     ZonedDateTime also carries toInstant, which\n//                     PlainDateTime doesn't.)\n//   ZonedDateTime   — toInstant + withTimeZone. (both unique — only\n//                     ZonedDateTime carries withTimeZone.)\n//   Instant         — toZonedDateTimeISO, no toInstant. (Instant IS the\n//                     instant — toInstant belongs to ZonedDateTime.\n//                     toZonedDateTimeISO exists on both Instant and\n//                     ZonedDateTime per spec, but on ZonedDateTime it's\n//                     not actually exposed on the prototype in either\n//                     native or polyfill — only Instant has it as a real\n//                     method. checked both to confirm.)\n//   PlainYearMonth  — toPlainDate (takes a day arg) + year/month, no\n//                     day. (PlainDate also has a toPlainDate-shaped\n//                     method but carries day; PlainMonthDay also has\n//                     toPlainDate but carries day, not year.)\n//   PlainMonthDay   — toPlainDate + month/day, no year. also lacks\n//                     add/subtract/until/since (calendar arithmetic\n//                     doesn't really make sense on a month-day without\n//                     a year anyway).\n//   Duration        — total + abs + negated. (all three unique to\n//                     Duration, nothing else carries any of them.)\n\n// this shape intentionally mirrors TemporalLike over in tokens.ts, but\n// stays loose enough to also match real Temporal objects (which carry\n// the spec methods the field-only TemporalLike doesn't have)\ninterface TemporalInstance {\n  toInstant?: () => unknown;\n  toPlainDate?: (arg?: unknown) => unknown;\n  toPlainDateTime?: (arg?: unknown) => unknown;\n  toPlainTime?: () => unknown;\n  toPlainYearMonth?: () => unknown;\n  toPlainMonthDay?: () => unknown;\n  toZonedDateTime?: (arg: unknown) => unknown;\n  toZonedDateTimeISO?: (arg: unknown) => unknown;\n  withCalendar?: (cal: unknown) => unknown;\n  withPlainTime?: (t: unknown) => unknown;\n  withTimeZone?: (z: unknown) => unknown;\n  getTimeZoneTransition?: (opts: unknown) => unknown;\n  startOfDay?: () => unknown;\n  sign?: () => number;\n  blank?: () => boolean;\n  total?: (opts: unknown) => number;\n  abs?: () => unknown;\n  negated?: () => unknown;\n  toString?: () => string;\n  // these come from TemporalLike — present on all the date-carrying\n  // Temporal types but absent on PlainTime (no calendar position there)\n  year?: number;\n  month?: number;\n  day?: number;\n  hour?: number;\n  minute?: number;\n  second?: number;\n  calendarId?: string;\n  timeZoneId?: string;\n  // PlainMonthDay stores its month as monthCode (like \"M08\") instead of\n  // a plain numeric month — without a year there's no way to know which\n  // month a calendar-independent numeric month even refers to once\n  // leap-year-aware calendars get involved, so the spec uses monthCode\n  // instead. PlainMonthDay's the only type that has monthCode but not month\n  monthCode?: string;\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null;\n}\n\n// hardening against hostile getters: the guards below read properties\n// (year, hour, Symbol.toStringTag, ...) off whatever value the caller\n// hands us. an object with a throwing getter used to turn isPlainDate(obj)\n// — a function whose entire contract is \"return a boolean\" — into an\n// exception factory instead. every exported guard now goes through this\n// wrapper, so a throw during probing just means \"not one of ours\", not a\n// crash. one shared catch here instead of one per guard also keeps the\n// coverage numbers honest\nfunction guardOrFalse<T>(impl: (value: unknown) => value is T): (value: unknown) => value is T {\n  return (value: unknown): value is T => {\n    try {\n      return impl(value);\n    } catch {\n      return false;\n    }\n  };\n}\n\nfunction hasMethod<T extends keyof TemporalInstance>(\n  v: TemporalInstance,\n  name: T,\n): boolean {\n  return typeof v[name] === 'function';\n}\n\n// Symbol.toStringTag is the spec-mandated brand for Temporal types —\n// every Temporal instance carries a tag like \"Temporal.PlainDate\" via\n// this symbol regardless of native vs polyfill. the per-type guards use\n// this as a fast positive check: a tag match is enough on its own, the\n// structural fallback (field presence + method checks) only kicks in\n// when there's no tag set, which can happen with hand-built mocks or\n// partial implementations\nfunction hasTag(value: unknown, typeName: string): boolean {\n  if (!isObject(value)) return false;\n  const tag = (value as { [Symbol.toStringTag]?: unknown })[Symbol.toStringTag];\n  return tag === `Temporal.${typeName}`;\n}\n\nexport const isPlainDate: (value: unknown) => value is TemporalInstance = guardOrFalse(function isPlainDateImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'PlainDate')) return true;\n  if (!isObject(value)) return false;\n  const v = value as TemporalInstance;\n  return typeof v.year === 'number'\n    && typeof v.month === 'number'\n    && typeof v.day === 'number'\n    && typeof v.hour === 'undefined'\n    && hasMethod(v, 'toPlainDateTime')\n    && hasMethod(v, 'withCalendar');\n});\n\nexport const isPlainTime: (value: unknown) => value is TemporalInstance = guardOrFalse(function isPlainTimeImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'PlainTime')) return true;\n  if (!isObject(value)) return false;\n  const v = value as TemporalInstance;\n  // PlainTime is the only type with hour but no year, and neither\n  // withCalendar nor any toPlainX method. that combo is unique among\n  // all eight types\n  return typeof v.hour === 'number'\n    && typeof v.year === 'undefined'\n    && !hasMethod(v, 'withCalendar')\n    && !hasMethod(v, 'toPlainDate')\n    && !hasMethod(v, 'toPlainDateTime');\n});\n\nexport const isPlainDateTime: (value: unknown) => value is TemporalInstance = guardOrFalse(function isPlainDateTimeImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'PlainDateTime')) return true;\n  if (!isObject(value)) return false;\n  const v = value as TemporalInstance;\n  // withPlainTime shows up on both PlainDateTime and ZonedDateTime, but\n  // ZonedDateTime also has toInstant. so \"has withPlainTime, no\n  // toInstant\" uniquely picks out PlainDateTime\n  return typeof v.year === 'number'\n    && typeof v.month === 'number'\n    && typeof v.day === 'number'\n    && typeof v.hour === 'number'\n    && hasMethod(v, 'withPlainTime')\n    && !hasMethod(v, 'toInstant');\n});\n\nexport const isZonedDateTime: (value: unknown) => value is TemporalInstance = guardOrFalse(function isZonedDateTimeImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'ZonedDateTime')) return true;\n  if (!isObject(value)) return false;\n  const v = value as TemporalInstance;\n  // withTimeZone is unique to ZonedDateTime, nothing else has it\n  return typeof v.year === 'number'\n    && typeof v.month === 'number'\n    && typeof v.day === 'number'\n    && typeof v.hour === 'number'\n    && hasMethod(v, 'withTimeZone')\n    && hasMethod(v, 'toInstant');\n});\n\nexport const isInstant: (value: unknown) => value is TemporalInstance = guardOrFalse(function isInstantImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'Instant')) return true;\n  if (!isObject(value)) return false;\n  // Instant has toZonedDateTimeISO but no toInstant — makes sense, it\n  // IS the instant already. also has no year/month/day/hour fields since\n  // those only mean anything against a calendar + zone, which Instant\n  // alone doesn't carry\n  const v = value as TemporalInstance;\n  return hasMethod(v, 'toZonedDateTimeISO')\n    && !hasMethod(v, 'toInstant')\n    && typeof v.year === 'undefined';\n});\n\nexport const isPlainYearMonth: (value: unknown) => value is TemporalInstance = guardOrFalse(function isPlainYearMonthImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'PlainYearMonth')) return true;\n  if (!isObject(value)) return false;\n  const v = value as TemporalInstance;\n  // has year+month but no day, carries toPlainDate (used to attach a day\n  // later). PlainMonthDay also has toPlainDate but doesn't have year\n  return typeof v.year === 'number'\n    && typeof v.month === 'number'\n    && typeof v.day === 'undefined'\n    && hasMethod(v, 'toPlainDate');\n});\n\nexport const isPlainMonthDay: (value: unknown) => value is TemporalInstance = guardOrFalse(function isPlainMonthDayImpl(value: unknown): value is TemporalInstance {\n  if (hasTag(value, 'PlainMonthDay')) return true;\n  if (!isObject(value)) return false;\n  const v = value as TemporalInstance;\n  // PlainMonthDay has day and monthCode but no year and no numeric month.\n  // monthCode's the discriminator here — every other Temporal type with\n  // a month concept either has month (numeric, calendar-aware) or\n  // doesn't have months at all (PlainTime, Duration)\n  return typeof v.year === 'undefined'\n    && typeof v.month === 'undefined'\n    && typeof v.day === 'number'\n    && typeof v.monthCode === 'string'\n    && hasMethod(v, 'toPlainDate');\n});\n\nexport const isDuration: (value: unknown) => value is Record<string, unknown> = guardOrFalse(function isDurationImpl(value: unknown): value is Record<string, unknown> {\n  if (hasTag(value, 'Duration')) return true;\n  if (!isObject(value)) return false;\n  // total is unique to Duration across the whole Temporal set — nothing\n  // else has it (checked every prototype to confirm). abs and negated\n  // are also Duration-only, checking any one of the three would work;\n  // going with total since it's the most semantically distinctive one —\n  // a Duration-specific operation nothing else would coincidentally need\n  const v = value as TemporalInstance;\n  return hasMethod(v, 'total');\n});\n\n// umbrella guard: is this ANY Temporal namespace member. used by\n// assertTemporal below for the \"this needs to be some Temporal thing\"\n// case. checks two signals in order:\n//   1. Symbol.toStringTag — every Temporal type brands itself as\n//      Temporal.X via this symbol. spec-mandated, present on native\n//      and polyfill instances alike.\n//   2. the discriminating-method fallback — covers whatever future or\n//      partial Temporal implementation doesn't bother setting the tag.\n//      method presence is part of the spec contract, so combined with\n//      equals + with (both on every Temporal instance) it's still a\n//      reliable signal even without the tag being set\nexport const isTemporal: (value: unknown) => value is TemporalInstance = guardOrFalse(function isTemporalImpl(value: unknown): value is TemporalInstance {\n  if (!isObject(value)) return false;\n  const tag = (value as { [Symbol.toStringTag]?: unknown })[Symbol.toStringTag];\n  if (typeof tag === 'string' && tag.startsWith('Temporal.')) return true;\n  const v = value as TemporalInstance;\n  return hasMethod(v, 'toInstant')\n    || hasMethod(v, 'toPlainDate')\n    || hasMethod(v, 'toPlainDateTime')\n    || hasMethod(v, 'toPlainTime')\n    || hasMethod(v, 'toPlainYearMonth')\n    || hasMethod(v, 'toPlainMonthDay')\n    || hasMethod(v, 'toZonedDateTime')\n    || hasMethod(v, 'toZonedDateTimeISO')\n    || hasMethod(v, 'withCalendar')\n    || hasMethod(v, 'withPlainTime')\n    || hasMethod(v, 'withTimeZone')\n    || hasMethod(v, 'total');\n});\n\n// assertion helpers — throw with a real message instead of just\n// returning false. same convention the rest of this lib uses: descriptive\n// thrown errors instead of failing silently. the thrown error includes\n// a valueType hint so the caller can actually see what they passed in\nfunction describeValue(value: unknown): string {\n  if (value === null) return 'null';\n  if (Array.isArray(value)) return 'array';\n  if (typeof value === 'object') {\n    const ctor = (value as { constructor?: { name?: string } }).constructor;\n    if (ctor && typeof ctor.name === 'string' && ctor.name !== 'Object') {\n      return `instance of ${ctor.name}`;\n    }\n    return 'plain object';\n  }\n  return typeof value;\n}\n\nfunction assertImpl(value: unknown, guard: (v: unknown) => boolean, expectedType: string): void {\n  if (!guard(value)) {\n    throw new Error(\n      `temporal-fmt: expected a Temporal.${expectedType}, got ${describeValue(value)}.`\n    );\n  }\n}\n\nexport function assertTemporal(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isTemporal, 'object (Instant, PlainDate, PlainTime, PlainDateTime, ZonedDateTime, Duration, PlainYearMonth, or PlainMonthDay)');\n}\nexport function assertInstant(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isInstant, 'Instant');\n}\nexport function assertPlainDate(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isPlainDate, 'PlainDate');\n}\nexport function assertPlainTime(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isPlainTime, 'PlainTime');\n}\nexport function assertPlainDateTime(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isPlainDateTime, 'PlainDateTime');\n}\nexport function assertZonedDateTime(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isZonedDateTime, 'ZonedDateTime');\n}\nexport function assertPlainYearMonth(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isPlainYearMonth, 'PlainYearMonth');\n}\nexport function assertPlainMonthDay(value: unknown): asserts value is TemporalInstance {\n  assertImpl(value, isPlainMonthDay, 'PlainMonthDay');\n}\nexport function assertDuration(value: unknown): asserts value is Record<string, unknown> {\n  assertImpl(value, isDuration, 'Duration');\n}","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// relative time stuff. formatDistance() over in formatDistance.ts is\n// still the main one, this just adds formatRelative() / formatRelativeToNow()\n// on top.\n//\n// the difference between these that keeps tripping people up:\n//   formatDistance(date1, date2) -> \"3 days ago\" / \"in 2 hours\"\n//     just describes the gap, hands unit picking + pluralization off to Intl\n//   formatRelative(date, baseDate) -> \"yesterday\" / \"tomorrow\" / \"today\" /\n//     \"in 3 days\" / \"last week\"\n//     this one's calendar-relative, not ms-based. so \"in 1 day\" always means\n//     tomorrow even if it's technically only 23 hours from now\n//   formatRelativeToNow(date) -> literally just formatRelative(date, now)\n\nimport { differenceInDays } from './arithmetic.js';\nimport { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { normalizeLocaleTag } from './localeVocab.js';\nimport { InvalidLocaleError } from './errors.js';\n\nexport interface FormatRelativeOptions extends FormatOptions {\n  // 'auto' (default) — Intl picks natural stuff like \"yesterday\"/\"tomorrow\"\n  // when it's ±1 or 0. 'always' forces the stricter \"1 day ago\" style always.\n  numeric?: 'always' | 'auto';\n}\n\nconst rtfCache = new Map<string, Intl.RelativeTimeFormat>();\nconst MAX_RTF_CACHE_SIZE = 100;\n\nfunction getRtf(locale: string, numeric: 'always' | 'auto'): Intl.RelativeTimeFormat {\n  // reusing the same cache shape formatDistance.ts already has\n  const key = `${locale}|${numeric}`;\n  let rtf = rtfCache.get(key);\n  if (rtf) return rtf;\n  if (rtfCache.size >= MAX_RTF_CACHE_SIZE) {\n    const oldestKey = rtfCache.keys().next().value;\n    if (oldestKey !== undefined) rtfCache.delete(oldestKey);\n  }\n  try {\n    rtf = new Intl.RelativeTimeFormat(normalizeLocaleTag(locale), { numeric });\n  } catch (err) {\n    // bad locale tags just throw a plain RangeError from Intl, wrap it in\n    // our own error type instead. every failure here IS a RangeError anyway\n    // so we're not losing anything by converting unconditionally — the\n    // original message still comes through in `reason`\n    throw new InvalidLocaleError({ actual: locale, reason: (err as Error).message });\n  }\n  rtfCache.set(key, rtf);\n  return rtf;\n}\n\n// describes date1 as if you were standing at date2. uses differenceInDays\n// (counts calendar boundaries, not literal 24hr chunks) so something like\n// \"2026-08-04 23:59\" vs \"2026-08-05 00:00\" correctly says \"yesterday\",\n// not \"1 second ago\" which would be technically true but useless\n//\n// differenceInDays(a, b) gives b - a, but we want date1 - date2 here so\n// positive = future relative to date2. hence the argument swap below\nexport function formatRelative(\n  date1: unknown,\n  date2: unknown,\n  options: FormatRelativeOptions = {},\n): string {\n  const locale = options.locale ?? DEFAULT_LOCALE;\n  const numeric = options.numeric ?? 'auto';\n  const rtf = getRtf(locale, numeric);\n  const dayDiff = -differenceInDays(date1, date2);\n  const absDays = Math.abs(dayDiff);\n\n  if (absDays === 0) {\n    return rtf.format(0, 'day'); // shows up as \"now\"\n  }\n  if (absDays < 7) {\n    return rtf.format(dayDiff, 'day');\n  }\n  if (absDays < 30) {\n    return rtf.format(-Math.trunc(-dayDiff / 7), 'week');\n  }\n  if (absDays < 365) {\n    return rtf.format(-Math.trunc(-dayDiff / 30), 'month');\n  }\n  return rtf.format(-Math.trunc(-dayDiff / 365), 'year');\n}\n\nexport function formatRelativeToNow(\n  date: unknown,\n  options: FormatRelativeOptions = {},\n): string {\n  // just uses whatever the system clock says right now as the reference\n  const now = new Date();\n  const nowFields = {\n    year: now.getFullYear(),\n    month: now.getMonth() + 1,\n    day: now.getDate(),\n  };\n  return formatRelative(date, nowFields, options);\n}\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Extensibility. Controlled extensibility via\n// createFormatter({ tokens: ... }) rather than uncontrolled global\n// mutation. Custom tokens are passed at formatter-creation time;\n// built-in behavior stays deterministic regardless of what's registered.\n//\n// The existing registerLocaleVocab() is a global-registration escape\n// hatch for the locale-vocabulary case; createFormatter is the\n// per-formatter alternative for custom tokens.\n\nimport { type FormattedPart, type CompiledFormat } from './format.js';\nimport { TOKENS, type TemporalLike, type FormatOptions, DEFAULT_LOCALE } from './tokens.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\nimport { UnknownTokenError } from './errors.js';\n\nexport type TokenHandler = (t: TemporalLike, locale: string) => string;\nexport type TokenField = keyof TemporalLike;\n\nexport interface CustomToken {\n  name: string;\n  handler: TokenHandler;\n  field: TokenField;\n}\n\nexport interface FormatterOptions {\n  // Custom tokens to add (or override). Built-in tokens with the same\n  // name are replaced by the custom one.\n  tokens?: CustomToken[];\n  // Default locale for this formatter. Callers can still override per-call.\n  defaultLocale?: string;\n}\n\nexport interface Formatter {\n  format(temporal: TemporalLike, formatStr: string, options?: FormatOptions): string;\n  formatToParts(temporal: TemporalLike, formatStr: string, options?: FormatOptions): FormattedPart[];\n  compileFormat(formatStr: string): CompiledFormat;\n}\n\nexport function createFormatter(options: FormatterOptions = {}): Formatter {\n  // Build a merged token table: built-ins plus overrides.\n  const mergedTokens: Array<[string, TokenHandler, TokenField]> = [...TOKENS];\n  const customTokenNames = new Set<string>();\n  for (const custom of options.tokens ?? []) {\n    customTokenNames.add(custom.name);\n  }\n  // Replace existing tokens with the same name; append new ones.\n  for (const custom of options.tokens ?? []) {\n    const existingIdx = mergedTokens.findIndex(([name]) => name === custom.name);\n    if (existingIdx >= 0) {\n      mergedTokens[existingIdx] = [custom.name, custom.handler, custom.field];\n    } else {\n      mergedTokens.push([custom.name, custom.handler, custom.field]);\n    }\n  }\n  // Sort longest-first for the greedy tokenizer.\n  mergedTokens.sort((a, b) => b[0].length - a[0].length);\n  const handlerByToken = new Map(mergedTokens.map(([name, handler, field]) => [name, { handler, field }]));\n  const sortedTokenStrings = mergedTokens.map(([name]) => name);\n\n  function customTokenize(formatStr: string) {\n    const pieces: Array<{ kind: 'token' | 'literal'; value: string }> = [];\n    let i = 0;\n    while (i < formatStr.length) {\n      const ch = formatStr[i];\n      if (ch === \"'\") {\n        // Quoted literal handling — same as tokenize.ts.\n        if (formatStr[i + 1] === \"'\") {\n          appendLiteral(pieces, \"'\");\n          i += 2;\n          continue;\n        }\n        let j = i + 1;\n        let literal = '';\n        let closed = false;\n        while (j < formatStr.length) {\n          if (formatStr[j] === \"'\") {\n            if (formatStr[j + 1] === \"'\") {\n              literal += \"'\";\n              j += 2;\n              continue;\n            }\n            closed = true;\n            j += 1;\n            break;\n          }\n          literal += formatStr[j]!;\n          j += 1;\n        }\n        if (!closed) throw new Error(`temporal-fmt: unterminated quote in format string \"${formatStr}\"`);\n        appendLiteral(pieces, literal);\n        i = j;\n        continue;\n      }\n      const match = sortedTokenStrings.find((tok) => formatStr.startsWith(tok, i));\n      if (match) {\n        // Overlong-run guard, same rule as tokenize.ts: a greedy match of N\n        // chars followed by one more of the same letter (\"MMMMM\", \"ddddd\")\n        // is not a valid token of any width — emitting it as \"token +\n        // literal\" would silently splice an unrelated field onto this one,\n        // exactly the misreading the main tokenizer rejects. Same\n        // UnknownTokenError shape tokenize.ts throws.\n        const runChar = match[match.length - 1];\n        if (formatStr[i + match.length] === runChar) {\n          let end = i + match.length;\n          while (formatStr[end] === runChar) end += 1;\n          throw new UnknownTokenError({\n            token: formatStr.slice(i, end),\n            format: formatStr,\n            message:\n              `temporal-fmt: \"${formatStr.slice(i, end)}\" in format string \"${formatStr}\" isn't a recognized token — ` +\n              `did you mean \"${match}\"?`,\n          });\n        }\n        pieces.push({ kind: 'token', value: match });\n        i += match.length;\n        continue;\n      }\n      appendLiteral(pieces, ch);\n      i += 1;\n    }\n    return pieces;\n  }\n\n  function appendLiteral(pieces: Array<{ kind: 'token' | 'literal'; value: string }>, value: string): void {\n    const last = pieces[pieces.length - 1];\n    if (last && last.kind === 'literal') {\n      last.value += value;\n    } else {\n      pieces.push({ kind: 'literal', value });\n    }\n  }\n\n  const defaultLocale = options.defaultLocale ?? DEFAULT_LOCALE;\n\n  return {\n    format(temporal: TemporalLike, formatStr: string, opts: FormatOptions = {}) {\n      if (formatStr.length > MAX_FORMAT_LENGTH) {\n        throw new Error(`temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters (got ${formatStr.length}).`);\n      }\n      const locale = opts.locale ?? defaultLocale;\n      const pieces = customTokenize(formatStr);\n      let result = '';\n      for (const piece of pieces) {\n        if (piece.kind === 'literal') {\n          result += piece.value;\n          continue;\n        }\n        const handler = handlerByToken.get(piece.value);\n        /* c8 ignore start @preserve -- unreachable: customTokenize only ever produces a\n           `kind: 'token'` piece via sortedTokenStrings.find(...), and\n           handlerByToken is built from that same mergedTokens array, so\n           every token piece is guaranteed a handler entry. Guards against a\n           future customTokenize change that decouples the two lookups. */\n        if (!handler) throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n        /* c8 ignore stop @preserve */\n        if (temporal[handler.field] === undefined) {\n          throw new Error(\n            `temporal-fmt: token \"${piece.value}\" requires \"${String(handler.field)}\", which this Temporal object doesn't have.`\n          );\n        }\n        result += handler.handler(temporal, locale);\n      }\n      return result;\n    },\n    formatToParts(temporal: TemporalLike, formatStr: string, opts: FormatOptions = {}) {\n      if (formatStr.length > MAX_FORMAT_LENGTH) {\n        throw new Error(`temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters (got ${formatStr.length}).`);\n      }\n      const locale = opts.locale ?? defaultLocale;\n      const pieces = customTokenize(formatStr);\n      const out: FormattedPart[] = [];\n      for (const piece of pieces) {\n        if (piece.kind === 'literal') {\n          const last = out[out.length - 1];\n          /* c8 ignore start @preserve -- unreachable: customTokenize's own\n             appendLiteral() already merges adjacent literal chars/quoted\n             spans into a single piece before this loop ever sees them, so\n             two literal pieces are never adjacent here. Kept as a guard\n             against a future customTokenize change that stops merging. */\n          if (last && last.type === 'literal') last.value += piece.value;\n          /* c8 ignore stop @preserve */\n          else out.push({ type: 'literal', value: piece.value });\n          continue;\n        }\n        const handler = handlerByToken.get(piece.value);\n        /* c8 ignore start @preserve -- unreachable: customTokenize only emits\n           kind:'token' pieces found in sortedTokenStrings, the same array\n           handlerByToken is built from, so every token piece is guaranteed\n           a handler entry. Guards against future decoupling of the two. */\n        if (!handler) throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n        /* c8 ignore stop @preserve */\n        if (temporal[handler.field] === undefined) {\n          throw new Error(`temporal-fmt: token \"${piece.value}\" requires \"${String(handler.field)}\".`);\n        }\n        out.push({ type: 'token', value: handler.handler(temporal, locale), token: piece.value });\n      }\n      return out;\n    },\n    compileFormat(formatStr: string): CompiledFormat {\n      if (formatStr.length > MAX_FORMAT_LENGTH) {\n        throw new Error(`temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters (got ${formatStr.length}).`);\n      }\n      const pieces = customTokenize(formatStr);\n      return {\n        formatStr,\n        pieces: pieces.map((p) => p as { kind: 'token' | 'literal'; value: string }),\n        format(temporal: TemporalLike, opts: FormatOptions = {}) {\n          const locale = opts.locale ?? defaultLocale;\n          let result = '';\n          for (const piece of pieces) {\n            if (piece.kind === 'literal') {\n              result += piece.value;\n              continue;\n            }\n            const handler = handlerByToken.get(piece.value);\n            /* c8 ignore start @preserve -- unreachable, see the same guard's comment\n               above in the un-compiled format(). */\n            if (!handler) throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n            /* c8 ignore stop @preserve */\n            if (temporal[handler.field] === undefined) {\n              throw new Error(`temporal-fmt: token \"${piece.value}\" requires \"${String(handler.field)}\".`);\n            }\n            result += handler.handler(temporal, locale);\n          }\n          return result;\n        },\n        formatToParts(temporal: TemporalLike, opts: FormatOptions = {}) {\n          const locale = opts.locale ?? defaultLocale;\n          const out: FormattedPart[] = [];\n          for (const piece of pieces) {\n            if (piece.kind === 'literal') {\n              const last = out[out.length - 1];\n              /* c8 ignore start @preserve -- unreachable, see the same guard's\n                 comment above in the un-compiled formatToParts. */\n              if (last && last.type === 'literal') last.value += piece.value;\n              /* c8 ignore stop @preserve */\n              else out.push({ type: 'literal', value: piece.value });\n              continue;\n            }\n            const handler = handlerByToken.get(piece.value);\n            /* c8 ignore start @preserve -- unreachable, see the same guard's\n               comment above in the un-compiled formatToParts. */\n            if (!handler) throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n            /* c8 ignore stop @preserve */\n            if (temporal[handler.field] === undefined) {\n              throw new Error(`temporal-fmt: token \"${piece.value}\" requires \"${String(handler.field)}\".`);\n            }\n            out.push({ type: 'token', value: handler.handler(temporal, locale), token: piece.value });\n          }\n          return out;\n        },\n      };\n    },\n  };\n}\n\n","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Mod contract. A mod is a plain .mjs file that default-exports one of\n// these — same shape whether it's fixing a locale bug, adding a holiday\n// set, or registering a custom token. The actual file-loading (reading\n// a mods/ folder, dynamic import) is Node-only and lives in\n// scripts/loadMods.mjs, not here — this file only defines the shape a\n// mod has to match, so it stays usable by non-Node consumers of the\n// library too.\n\nimport { registerLocale, type ExtendedLocaleVocab } from './localeRegistry.js';\nimport { registerLocaleVocab, type LocaleVocab } from './localeVocab.js';\nimport { registerRelativeGrammar, type RelativeGrammar } from './relativeGrammar.js';\nimport { createFormatter, type FormatterOptions, type Formatter, type CustomToken } from './extensibility.js';\nimport { createHolidayCalendar, type HolidaySpec, type HolidayCalendar } from './holidays.js';\nimport { getFormatImpl, getParseImpl, setFormatOverride, setParseOverride, registerFormatToken, type FormatBatchFn, type BridgeFormatBatchFn, getCompileFormatImpl, setCompileFormatOverride, getCompileParserImpl, setCompileParserOverride, getParseRelativeImpl, setParseRelativeOverride, getExplainFormatImpl, setExplainFormatOverride, getTokenizeFormatImpl, setTokenizeFormatOverride, getListTokensImpl, setListTokensOverride, getTokenInfoImpl, setTokenInfoOverride, getIsValidFormatImpl, setIsValidFormatOverride, getValidateFormatImpl, setValidateFormatOverride, getFieldForTokenImpl, setFieldForTokenOverride, getMonthsInYearImpl, setMonthsInYearOverride, getIsLeapYearImpl, setIsLeapYearOverride, getIsLeapMonthImpl, setIsLeapMonthOverride, getWeekOfYearImpl, setWeekOfYearOverride, getWeekYearImpl, setWeekYearOverride, getGetMonthImpl, setGetMonthOverride, getGetWeekdayImpl, setGetWeekdayOverride, getIsEqualImpl, setIsEqualOverride, getIsBeforeImpl, setIsBeforeOverride, getIsAfterImpl, setIsAfterOverride, getClampImpl, setClampOverride, getIsBetweenImpl, setIsBetweenOverride, getIsTodayImpl, setIsTodayOverride, getIsTomorrowImpl, setIsTomorrowOverride, getIsYesterdayImpl, setIsYesterdayOverride, getIsSameDayImpl, setIsSameDayOverride, getIsSameWeekImpl, setIsSameWeekOverride, getIsSameMonthImpl, setIsSameMonthOverride, getIsSameQuarterImpl, setIsSameQuarterOverride, getIsSameYearImpl, setIsSameYearOverride, getIsWeekdayImpl, setIsWeekdayOverride, getFloorImpl, setFloorOverride, getCeilImpl, setCeilOverride, getTruncateImpl, setTruncateOverride, getParseRFC3339Impl, setParseRFC3339Override, getFormatRFC3339Impl, setFormatRFC3339Override, getParseRFC2822Impl, setParseRFC2822Override, getParseHTTPDateImpl, setParseHTTPDateOverride, getFromUnixMicrosecondsImpl, setFromUnixMicrosecondsOverride, getFromUnixNanosecondsImpl, setFromUnixNanosecondsOverride, getToUnixSecondsImpl, setToUnixSecondsOverride, getToUnixMillisecondsImpl, setToUnixMillisecondsOverride, getToUnixMicrosecondsImpl, setToUnixMicrosecondsOverride, getToUnixNanosecondsImpl, setToUnixNanosecondsOverride, getParseSQLImpl, setParseSQLOverride, getFormatSQLImpl, setFormatSQLOverride, getFormatDurationToPartsImpl, setFormatDurationToPartsOverride, getParseDurationImpl, setParseDurationOverride, getParseISODurationImpl, setParseISODurationOverride, getFormatISODurationImpl, setFormatISODurationOverride, getBalanceDurationImpl, setBalanceDurationOverride, getCompareDurationImpl, setCompareDurationOverride, getSubtractDurationImpl, setSubtractDurationOverride, getGetLocaleImpl, setGetLocaleOverride, getHasLocaleImpl, setHasLocaleOverride, getCreateConfigImpl, setCreateConfigOverride, getMergeWithConfigImpl, setMergeWithConfigOverride, getListRegisteredGrammarsImpl, setListRegisteredGrammarsOverride, getIntervalImpl, setIntervalOverride, getOverlapsImpl, setOverlapsOverride, getIntersectionImpl, setIntersectionOverride, getUnionImpl, setUnionOverride, getMergeIntervalsImpl, setMergeIntervalsOverride, getFormatRangeToPartsImpl, setFormatRangeToPartsOverride, getBetweenImpl, setBetweenOverride, getParseRRuleImpl, setParseRRuleOverride, getFormatRRuleImpl, setFormatRRuleOverride, getCreateBusinessCalendarImpl, setCreateBusinessCalendarOverride, getSubtractBusinessDaysImpl, setSubtractBusinessDaysOverride, getNextHolidayImpl, setNextHolidayOverride, getPreviousHolidayImpl, setPreviousHolidayOverride, getResolveZonedImpl, setResolveZonedOverride, getGetNextTransitionImpl, setGetNextTransitionOverride, getGetPreviousTransitionImpl, setGetPreviousTransitionOverride, getPossibleInstantsForImpl, setPossibleInstantsForOverride, getGetAutocompleteDataImpl, setGetAutocompleteDataOverride, getGetHoverDocsImpl, setGetHoverDocsOverride, getGetInlineDiagnosticsImpl, setGetInlineDiagnosticsOverride, getPreviewFormatImpl, setPreviewFormatOverride, getGetDocUrlImpl, setGetDocUrlOverride, getTranslateDateFnsFormatStringImpl, setTranslateDateFnsFormatStringOverride } from './runtime.js';\nimport type { compileFormat as compileFormatBase } from './format.js';\nimport type { compileParser as compileParserBase } from './parse.js';\nimport type { parseRelative as parseRelativeBase } from './parseRelative.js';\nimport type { explainFormat as explainFormatBase, tokenizeFormat as tokenizeFormatBase, listTokens as listTokensBase, tokenInfo as tokenInfoBase, isValidFormat as isValidFormatBase, validateFormat as validateFormatBase, fieldForToken as fieldForTokenBase } from './analyze.js';\nimport type { monthsInYear as monthsInYearBase, isLeapYear as isLeapYearBase, isLeapMonth as isLeapMonthBase, weekOfYear as weekOfYearBase, weekYear as weekYearBase, getMonth as getMonthBase, getWeekday as getWeekdayBase } from './calendarUtils.js';\nimport type { isEqual as isEqualBase, isBefore as isBeforeBase, isAfter as isAfterBase, clamp as clampBase, isBetween as isBetweenBase, isToday as isTodayBase, isTomorrow as isTomorrowBase, isYesterday as isYesterdayBase, isSameDay as isSameDayBase, isSameWeek as isSameWeekBase, isSameMonth as isSameMonthBase, isSameQuarter as isSameQuarterBase, isSameYear as isSameYearBase, isWeekday as isWeekdayBase } from './comparison.js';\nimport type { floor as floorBase, ceil as ceilBase, truncate as truncateBase } from './rounding.js';\nimport type { parseRFC3339 as parseRFC3339Base, formatRFC3339 as formatRFC3339Base, parseRFC2822 as parseRFC2822Base, parseHTTPDate as parseHTTPDateBase, fromUnixMicroseconds as fromUnixMicrosecondsBase, fromUnixNanoseconds as fromUnixNanosecondsBase, toUnixSeconds as toUnixSecondsBase, toUnixMilliseconds as toUnixMillisecondsBase, toUnixMicroseconds as toUnixMicrosecondsBase, toUnixNanoseconds as toUnixNanosecondsBase, parseSQL as parseSQLBase, formatSQL as formatSQLBase } from './serialization.js';\nimport type { formatDurationToParts as formatDurationToPartsBase, parseDuration as parseDurationBase, parseISODuration as parseISODurationBase, formatISODuration as formatISODurationBase, balanceDuration as balanceDurationBase, compareDuration as compareDurationBase, subtractDuration as subtractDurationBase } from './duration.js';\nimport type { getLocale as getLocaleBase, hasLocale as hasLocaleBase } from './localeRegistry.js';\nimport type { createConfig as createConfigBase, mergeWithConfig as mergeWithConfigBase } from './config.js';\nimport type { listRegisteredGrammars as listRegisteredGrammarsBase } from './relativeGrammar.js';\nimport type { interval as intervalBase, overlaps as overlapsBase, intersection as intersectionBase, union as unionBase, mergeIntervals as mergeIntervalsBase, formatRangeToParts as formatRangeToPartsBase } from './interval.js';\nimport type { between as betweenBase, parseRRule as parseRRuleBase, formatRRule as formatRRuleBase } from './recurrence.js';\nimport type { createBusinessCalendar as createBusinessCalendarBase, subtractBusinessDays as subtractBusinessDaysBase } from './businessCalendar.js';\nimport type { nextHoliday as nextHolidayBase, previousHoliday as previousHolidayBase } from './holidays.js';\nimport type { resolveZoned as resolveZonedBase, getNextTransition as getNextTransitionBase, getPreviousTransition as getPreviousTransitionBase, possibleInstantsFor as possibleInstantsForBase } from './timezone.js';\nimport type { getAutocompleteData as getAutocompleteDataBase, getHoverDocs as getHoverDocsBase, getInlineDiagnostics as getInlineDiagnosticsBase, previewFormat as previewFormatBase, getDocUrl as getDocUrlBase } from './ideData.js';\nimport type { translateDateFnsFormatString as translateDateFnsFormatStringBase } from './codemod.js';\nimport type { format as FormatFn } from './format.js';\nimport type { parse as ParseFn } from './parse.js';\n\n// The closed set of capabilities a mod may ask for. This list is the one\n// both layers share — the loader validates manifests against it, the\n// sandbox translates entries into permission-model flags, and\n// ctx.hasPermission() answers questions from it — so it lives here, in\n// the library, and the loader re-exports it rather than keeping a second\n// copy that could drift. Membership criterion: each entry maps to a Node\n// permission-model flag that exists on every version this package\n// supports (20 through 26). The permission model cannot restrict network\n// access or environment variables on any of those versions, so \"net\" and\n// \"env\" are not offered — a permission that can't be enforced would be a\n// lie. \"addons\" exists as a flag but is deliberately absent too: native\n// code escapes every other restriction, so there is no meaningful way\n// to grant it \"a little\".\nexport const GRANTABLE_PERMISSIONS = ['fs:read', 'fs:write', 'child-process', 'worker'] as const;\n\n// Deliberately just the public registration functions, re-typed here so\n// a mod only ever touches the library through the same surface any other\n// consumer would. No access to internal token tables, tokenizer state,\n// etc. — a mod that needs more than this is a real feature request for\n// the library itself, not something to route around by reaching into\n// internals that could shift under it without notice.\n//\n// overrideFormat/overrideParse are the one deliberate exception to\n// \"additive only\": they let a mod replace the actual format()/parse()\n// implementation everywhere in the library, not just register new data\n// alongside the existing behavior — see runtime.ts for how that's made\n// consistent across internal call sites, and README -> Mods for why\n// this is capped at one override per point instead of allowing\n// multiple mods to stack silently.\nexport interface ModContext {\n  registerLocale(locale: string, vocab: ExtendedLocaleVocab): void;\n  registerLocaleVocab(locale: string, vocab: LocaleVocab): void;\n  registerRelativeGrammar(grammar: RelativeGrammar): void;\n  // Returns a standalone Formatter with its own token table — the\n  // custom tokens in `options.tokens` are only visible to callers who\n  // hold and call the returned object. This does NOT reach the module-\n  // level format()/parse() every other caller in the process uses; see\n  // extensibility.ts's createFormatter for the full explanation. If you\n  // want a token available to every format() call, not just your own\n  // Formatter instance, use registerFormatToken below instead.\n  createFormatter(options?: FormatterOptions): Formatter;\n  createHolidayCalendar(specs: HolidaySpec[]): HolidayCalendar;\n  // Adds a token into the actual shared table format()/parse() read\n  // from — unlike createFormatter's `tokens` option, which only affects\n  // the one Formatter instance it returns. This is the fix for the\n  // common case createFormatter can't cover: a mod wanting one new\n  // token (say PIRATE) available to every format() call in the process,\n  // not just callers who specifically ask for this mod's own formatter.\n  // Last-write-wins by name — including against a built-in name, same\n  // as createFormatter's own merge rule — so a second mod (or a higher-\n  // `priority` one loading later) registering the same name replaces\n  // this one rather than throwing. That's deliberately different from\n  // overrideFormat/overrideParse below: those guard one exclusive global\n  // slot, tokens are a namespace, and two mods each wanting one harmless\n  // token is a normal thing to happen, not a correctness bug to hard-\n  // error on.\n  registerFormatToken(token: CustomToken): void;\n  // Structured logging, shown in the host's load report instead of\n  // vanishing into stderr the way a mod's own console.log would (a\n  // sandboxed mod's stdout/stderr aren't even the terminal's — see\n  // modWorker.mjs — so console.log from inside register() is invisible\n  // to the person running the CLI unless they go looking). Not for\n  // problems the caller needs to react to — those are reportIssue below\n  // — this is \"here's what I'm doing / noticed,\" visible on request.\n  log(level: 'debug' | 'info' | 'warn' | 'error', message: string, meta?: Record<string, unknown>): void;\n  // Non-fatal problem reporting: a mod that's degrading gracefully (a\n  // locale file with a malformed entry, an optional permission it didn't\n  // get and is working around) can say so here instead of choosing\n  // between throwing (kills the mod for a problem it already handled)\n  // and console.log (invisible, see log() above). Shown next to\n  // permission grants in the load report, so \"this mod loaded but isn't\n  // fully working\" is visible without reading the mod's source.\n  reportIssue(issue: { message: string; severity?: 'warning' | 'error'; detail?: unknown }): void;\n  // Whether this mod's execution context actually has the capability —\n  // under the CLI's sandbox, that's what was granted at load time (an\n  // optional permission the user declined reads as false here, so a mod\n  // can skip its supplementary data instead of crashing on the read).\n  // Outside the sandbox there's nothing to grant: every governable\n  // capability is available, so everything in GRANTABLE_PERMISSIONS\n  // reads as true and anything else as false. \"net\" is false everywhere\n  // because it isn't a capability at all — no permission-model flag backs\n  // it on any supported Node version.\n  //\n  // Typed as the literal union, not a bare `string`, so a typo like\n  // 'fs:reed' is a compile-time error in a TS-authored mod instead of a\n  // capability that silently and permanently reads false — the runtime\n  // check underneath still accepts (and still correctly returns false\n  // for) anything outside the union, since a loose .mjs mod has no\n  // compiler to catch the same mistake and still needs an honest answer.\n  hasPermission(capability: typeof GRANTABLE_PERMISSIONS[number]): boolean;\n  // `impl` receives the current format()/parse() as its first argument\n  // (always the original built-in — only one mod can hold this override\n  // at a time, see below, so there's never a \"previous mod's override\"\n  // to receive instead). Call it to keep the existing behavior for\n  // cases you're not trying to change, or ignore it entirely to replace\n  // the implementation outright.\n  //\n  // Only one mod may hold each override. A second overrideFormat()/\n  // overrideParse() call — from any mod, even one that `requires` the\n  // first — throws immediately. This is a real limitation, not just\n  // strictness for its own sake: there's no mechanism here for two\n  // separate mod files to both wrap the same point in sequence, only\n  // for one mod's own implementation to wrap the original once. If two\n  // mods both need to change format()'s behavior, one of them has to\n  // incorporate the other's fix directly rather than layering through\n  // the override system.\n  overrideFormat(impl: (original: typeof FormatFn, ...args: Parameters<typeof FormatFn>) => ReturnType<typeof FormatFn>): void;\n  overrideParse(impl: (original: typeof ParseFn, ...args: Parameters<typeof ParseFn>) => ReturnType<typeof ParseFn>): void;\n  overrideCompileFormat(impl: (original: typeof compileFormatBase, ...args: Parameters<typeof compileFormatBase>) => ReturnType<typeof compileFormatBase>): void;\n  overrideCompileParser(impl: (original: typeof compileParserBase, ...args: Parameters<typeof compileParserBase>) => ReturnType<typeof compileParserBase>): void;\n  overrideParseRelative(impl: (original: typeof parseRelativeBase, ...args: Parameters<typeof parseRelativeBase>) => ReturnType<typeof parseRelativeBase>): void;\n  overrideExplainFormat(impl: (original: typeof explainFormatBase, ...args: Parameters<typeof explainFormatBase>) => ReturnType<typeof explainFormatBase>): void;\n  overrideTokenizeFormat(impl: (original: typeof tokenizeFormatBase, ...args: Parameters<typeof tokenizeFormatBase>) => ReturnType<typeof tokenizeFormatBase>): void;\n  overrideListTokens(impl: (original: typeof listTokensBase, ...args: Parameters<typeof listTokensBase>) => ReturnType<typeof listTokensBase>): void;\n  overrideTokenInfo(impl: (original: typeof tokenInfoBase, ...args: Parameters<typeof tokenInfoBase>) => ReturnType<typeof tokenInfoBase>): void;\n  overrideIsValidFormat(impl: (original: typeof isValidFormatBase, ...args: Parameters<typeof isValidFormatBase>) => ReturnType<typeof isValidFormatBase>): void;\n  overrideValidateFormat(impl: (original: typeof validateFormatBase, ...args: Parameters<typeof validateFormatBase>) => ReturnType<typeof validateFormatBase>): void;\n  overrideFieldForToken(impl: (original: typeof fieldForTokenBase, ...args: Parameters<typeof fieldForTokenBase>) => ReturnType<typeof fieldForTokenBase>): void;\n  overrideMonthsInYear(impl: (original: typeof monthsInYearBase, ...args: Parameters<typeof monthsInYearBase>) => ReturnType<typeof monthsInYearBase>): void;\n  overrideIsLeapYear(impl: (original: typeof isLeapYearBase, ...args: Parameters<typeof isLeapYearBase>) => ReturnType<typeof isLeapYearBase>): void;\n  overrideIsLeapMonth(impl: (original: typeof isLeapMonthBase, ...args: Parameters<typeof isLeapMonthBase>) => ReturnType<typeof isLeapMonthBase>): void;\n  overrideWeekOfYear(impl: (original: typeof weekOfYearBase, ...args: Parameters<typeof weekOfYearBase>) => ReturnType<typeof weekOfYearBase>): void;\n  overrideWeekYear(impl: (original: typeof weekYearBase, ...args: Parameters<typeof weekYearBase>) => ReturnType<typeof weekYearBase>): void;\n  overrideGetMonth(impl: (original: typeof getMonthBase, ...args: Parameters<typeof getMonthBase>) => ReturnType<typeof getMonthBase>): void;\n  overrideGetWeekday(impl: (original: typeof getWeekdayBase, ...args: Parameters<typeof getWeekdayBase>) => ReturnType<typeof getWeekdayBase>): void;\n  overrideIsEqual(impl: (original: typeof isEqualBase, ...args: Parameters<typeof isEqualBase>) => ReturnType<typeof isEqualBase>): void;\n  overrideIsBefore(impl: (original: typeof isBeforeBase, ...args: Parameters<typeof isBeforeBase>) => ReturnType<typeof isBeforeBase>): void;\n  overrideIsAfter(impl: (original: typeof isAfterBase, ...args: Parameters<typeof isAfterBase>) => ReturnType<typeof isAfterBase>): void;\n  overrideClamp(impl: (original: typeof clampBase, ...args: Parameters<typeof clampBase>) => ReturnType<typeof clampBase>): void;\n  overrideIsBetween(impl: (original: typeof isBetweenBase, ...args: Parameters<typeof isBetweenBase>) => ReturnType<typeof isBetweenBase>): void;\n  overrideIsToday(impl: (original: typeof isTodayBase, ...args: Parameters<typeof isTodayBase>) => ReturnType<typeof isTodayBase>): void;\n  overrideIsTomorrow(impl: (original: typeof isTomorrowBase, ...args: Parameters<typeof isTomorrowBase>) => ReturnType<typeof isTomorrowBase>): void;\n  overrideIsYesterday(impl: (original: typeof isYesterdayBase, ...args: Parameters<typeof isYesterdayBase>) => ReturnType<typeof isYesterdayBase>): void;\n  overrideIsSameDay(impl: (original: typeof isSameDayBase, ...args: Parameters<typeof isSameDayBase>) => ReturnType<typeof isSameDayBase>): void;\n  overrideIsSameWeek(impl: (original: typeof isSameWeekBase, ...args: Parameters<typeof isSameWeekBase>) => ReturnType<typeof isSameWeekBase>): void;\n  overrideIsSameMonth(impl: (original: typeof isSameMonthBase, ...args: Parameters<typeof isSameMonthBase>) => ReturnType<typeof isSameMonthBase>): void;\n  overrideIsSameQuarter(impl: (original: typeof isSameQuarterBase, ...args: Parameters<typeof isSameQuarterBase>) => ReturnType<typeof isSameQuarterBase>): void;\n  overrideIsSameYear(impl: (original: typeof isSameYearBase, ...args: Parameters<typeof isSameYearBase>) => ReturnType<typeof isSameYearBase>): void;\n  overrideIsWeekday(impl: (original: typeof isWeekdayBase, ...args: Parameters<typeof isWeekdayBase>) => ReturnType<typeof isWeekdayBase>): void;\n  overrideFloor(impl: (original: typeof floorBase, ...args: Parameters<typeof floorBase>) => ReturnType<typeof floorBase>): void;\n  overrideCeil(impl: (original: typeof ceilBase, ...args: Parameters<typeof ceilBase>) => ReturnType<typeof ceilBase>): void;\n  overrideTruncate(impl: (original: typeof truncateBase, ...args: Parameters<typeof truncateBase>) => ReturnType<typeof truncateBase>): void;\n  overrideParseRFC3339(impl: (original: typeof parseRFC3339Base, ...args: Parameters<typeof parseRFC3339Base>) => ReturnType<typeof parseRFC3339Base>): void;\n  overrideFormatRFC3339(impl: (original: typeof formatRFC3339Base, ...args: Parameters<typeof formatRFC3339Base>) => ReturnType<typeof formatRFC3339Base>): void;\n  overrideParseRFC2822(impl: (original: typeof parseRFC2822Base, ...args: Parameters<typeof parseRFC2822Base>) => ReturnType<typeof parseRFC2822Base>): void;\n  overrideParseHTTPDate(impl: (original: typeof parseHTTPDateBase, ...args: Parameters<typeof parseHTTPDateBase>) => ReturnType<typeof parseHTTPDateBase>): void;\n  overrideFromUnixMicroseconds(impl: (original: typeof fromUnixMicrosecondsBase, ...args: Parameters<typeof fromUnixMicrosecondsBase>) => ReturnType<typeof fromUnixMicrosecondsBase>): void;\n  overrideFromUnixNanoseconds(impl: (original: typeof fromUnixNanosecondsBase, ...args: Parameters<typeof fromUnixNanosecondsBase>) => ReturnType<typeof fromUnixNanosecondsBase>): void;\n  overrideToUnixSeconds(impl: (original: typeof toUnixSecondsBase, ...args: Parameters<typeof toUnixSecondsBase>) => ReturnType<typeof toUnixSecondsBase>): void;\n  overrideToUnixMilliseconds(impl: (original: typeof toUnixMillisecondsBase, ...args: Parameters<typeof toUnixMillisecondsBase>) => ReturnType<typeof toUnixMillisecondsBase>): void;\n  overrideToUnixMicroseconds(impl: (original: typeof toUnixMicrosecondsBase, ...args: Parameters<typeof toUnixMicrosecondsBase>) => ReturnType<typeof toUnixMicrosecondsBase>): void;\n  overrideToUnixNanoseconds(impl: (original: typeof toUnixNanosecondsBase, ...args: Parameters<typeof toUnixNanosecondsBase>) => ReturnType<typeof toUnixNanosecondsBase>): void;\n  overrideParseSQL(impl: (original: typeof parseSQLBase, ...args: Parameters<typeof parseSQLBase>) => ReturnType<typeof parseSQLBase>): void;\n  overrideFormatSQL(impl: (original: typeof formatSQLBase, ...args: Parameters<typeof formatSQLBase>) => ReturnType<typeof formatSQLBase>): void;\n  overrideFormatDurationToParts(impl: (original: typeof formatDurationToPartsBase, ...args: Parameters<typeof formatDurationToPartsBase>) => ReturnType<typeof formatDurationToPartsBase>): void;\n  overrideParseDuration(impl: (original: typeof parseDurationBase, ...args: Parameters<typeof parseDurationBase>) => ReturnType<typeof parseDurationBase>): void;\n  overrideParseISODuration(impl: (original: typeof parseISODurationBase, ...args: Parameters<typeof parseISODurationBase>) => ReturnType<typeof parseISODurationBase>): void;\n  overrideFormatISODuration(impl: (original: typeof formatISODurationBase, ...args: Parameters<typeof formatISODurationBase>) => ReturnType<typeof formatISODurationBase>): void;\n  overrideBalanceDuration(impl: (original: typeof balanceDurationBase, ...args: Parameters<typeof balanceDurationBase>) => ReturnType<typeof balanceDurationBase>): void;\n  overrideCompareDuration(impl: (original: typeof compareDurationBase, ...args: Parameters<typeof compareDurationBase>) => ReturnType<typeof compareDurationBase>): void;\n  overrideSubtractDuration(impl: (original: typeof subtractDurationBase, ...args: Parameters<typeof subtractDurationBase>) => ReturnType<typeof subtractDurationBase>): void;\n  overrideGetLocale(impl: (original: typeof getLocaleBase, ...args: Parameters<typeof getLocaleBase>) => ReturnType<typeof getLocaleBase>): void;\n  overrideHasLocale(impl: (original: typeof hasLocaleBase, ...args: Parameters<typeof hasLocaleBase>) => ReturnType<typeof hasLocaleBase>): void;\n  overrideCreateConfig(impl: (original: typeof createConfigBase, ...args: Parameters<typeof createConfigBase>) => ReturnType<typeof createConfigBase>): void;\n  overrideMergeWithConfig(impl: (original: typeof mergeWithConfigBase, ...args: Parameters<typeof mergeWithConfigBase>) => ReturnType<typeof mergeWithConfigBase>): void;\n  overrideListRegisteredGrammars(impl: (original: typeof listRegisteredGrammarsBase, ...args: Parameters<typeof listRegisteredGrammarsBase>) => ReturnType<typeof listRegisteredGrammarsBase>): void;\n  overrideInterval(impl: (original: typeof intervalBase, ...args: Parameters<typeof intervalBase>) => ReturnType<typeof intervalBase>): void;\n  overrideOverlaps(impl: (original: typeof overlapsBase, ...args: Parameters<typeof overlapsBase>) => ReturnType<typeof overlapsBase>): void;\n  overrideIntersection(impl: (original: typeof intersectionBase, ...args: Parameters<typeof intersectionBase>) => ReturnType<typeof intersectionBase>): void;\n  overrideUnion(impl: (original: typeof unionBase, ...args: Parameters<typeof unionBase>) => ReturnType<typeof unionBase>): void;\n  overrideMergeIntervals(impl: (original: typeof mergeIntervalsBase, ...args: Parameters<typeof mergeIntervalsBase>) => ReturnType<typeof mergeIntervalsBase>): void;\n  overrideFormatRangeToParts(impl: (original: typeof formatRangeToPartsBase, ...args: Parameters<typeof formatRangeToPartsBase>) => ReturnType<typeof formatRangeToPartsBase>): void;\n  overrideBetween(impl: (original: typeof betweenBase, ...args: Parameters<typeof betweenBase>) => ReturnType<typeof betweenBase>): void;\n  overrideParseRRule(impl: (original: typeof parseRRuleBase, ...args: Parameters<typeof parseRRuleBase>) => ReturnType<typeof parseRRuleBase>): void;\n  overrideFormatRRule(impl: (original: typeof formatRRuleBase, ...args: Parameters<typeof formatRRuleBase>) => ReturnType<typeof formatRRuleBase>): void;\n  overrideCreateBusinessCalendar(impl: (original: typeof createBusinessCalendarBase, ...args: Parameters<typeof createBusinessCalendarBase>) => ReturnType<typeof createBusinessCalendarBase>): void;\n  overrideSubtractBusinessDays(impl: (original: typeof subtractBusinessDaysBase, ...args: Parameters<typeof subtractBusinessDaysBase>) => ReturnType<typeof subtractBusinessDaysBase>): void;\n  overrideNextHoliday(impl: (original: typeof nextHolidayBase, ...args: Parameters<typeof nextHolidayBase>) => ReturnType<typeof nextHolidayBase>): void;\n  overridePreviousHoliday(impl: (original: typeof previousHolidayBase, ...args: Parameters<typeof previousHolidayBase>) => ReturnType<typeof previousHolidayBase>): void;\n  overrideResolveZoned(impl: (original: typeof resolveZonedBase, ...args: Parameters<typeof resolveZonedBase>) => ReturnType<typeof resolveZonedBase>): void;\n  overrideGetNextTransition(impl: (original: typeof getNextTransitionBase, ...args: Parameters<typeof getNextTransitionBase>) => ReturnType<typeof getNextTransitionBase>): void;\n  overrideGetPreviousTransition(impl: (original: typeof getPreviousTransitionBase, ...args: Parameters<typeof getPreviousTransitionBase>) => ReturnType<typeof getPreviousTransitionBase>): void;\n  overridePossibleInstantsFor(impl: (original: typeof possibleInstantsForBase, ...args: Parameters<typeof possibleInstantsForBase>) => ReturnType<typeof possibleInstantsForBase>): void;\n  overrideGetAutocompleteData(impl: (original: typeof getAutocompleteDataBase, ...args: Parameters<typeof getAutocompleteDataBase>) => ReturnType<typeof getAutocompleteDataBase>): void;\n  overrideGetHoverDocs(impl: (original: typeof getHoverDocsBase, ...args: Parameters<typeof getHoverDocsBase>) => ReturnType<typeof getHoverDocsBase>): void;\n  overrideGetInlineDiagnostics(impl: (original: typeof getInlineDiagnosticsBase, ...args: Parameters<typeof getInlineDiagnosticsBase>) => ReturnType<typeof getInlineDiagnosticsBase>): void;\n  overridePreviewFormat(impl: (original: typeof previewFormatBase, ...args: Parameters<typeof previewFormatBase>) => ReturnType<typeof previewFormatBase>): void;\n  overrideGetDocUrl(impl: (original: typeof getDocUrlBase, ...args: Parameters<typeof getDocUrlBase>) => ReturnType<typeof getDocUrlBase>): void;\n  overrideTranslateDateFnsFormatString(impl: (original: typeof translateDateFnsFormatStringBase, ...args: Parameters<typeof translateDateFnsFormatStringBase>) => ReturnType<typeof translateDateFnsFormatStringBase>): void;\n}\n\n// `modName` is threaded through so a conflict error can name which mod\n// owns an existing override, and which mod's overrideFormat()/\n// overrideParse() call is the one being rejected — buildModContext()\n// alone has no way to know who's calling it, only the loader does.\nexport function buildModContextFor(modName: string): ModContext {\n  return {\n    registerLocale,\n    registerLocaleVocab,\n    registerRelativeGrammar,\n    createFormatter,\n    createHolidayCalendar,\n    registerFormatToken,\n    // Base behavior for callers with no load report to attach to (using\n    // buildModContext()/buildModContextFor() directly, outside\n    // scripts/loadMods.mjs): print via globalThis.console if one exists,\n    // so the message isn't just dropped, prefixed with the mod's name\n    // since there's no report entry to already be scoped under one.\n    // Reached through globalThis rather than the bare `console` global —\n    // this module has no lib.dom/lib.node in its tsconfig on purpose\n    // (see the file-top comment: usable by non-Node consumers too), and\n    // a truly console-less runtime just silently drops the line instead\n    // of throwing. The CLI's actual load path always goes through\n    // buildTrackedModContext below, which replaces both of these with\n    // report-collecting versions — this fallback only fires for a mod\n    // loaded some other way.\n    log(level, message, meta) {\n      const c = (globalThis as { console?: { error?: (...args: unknown[]) => void; warn?: (...args: unknown[]) => void; info?: (...args: unknown[]) => void; debug?: (...args: unknown[]) => void } }).console;\n      const write = level === 'error' ? c?.error : level === 'warn' ? c?.warn : level === 'info' ? c?.info : c?.debug;\n      write?.(`[${modName}] ${level}: ${message}${meta ? ` ${JSON.stringify(meta)}` : ''}`);\n    },\n    reportIssue(issue) {\n      const c = (globalThis as { console?: { error?: (...args: unknown[]) => void } }).console;\n      const severity = issue.severity ?? 'warning';\n      c?.error?.(`[${modName}] ${severity}: ${issue.message}${issue.detail !== undefined ? ` ${JSON.stringify(issue.detail)}` : ''}`);\n    },\n    hasPermission(capability) {\n      return (GRANTABLE_PERMISSIONS as readonly string[]).includes(capability);\n    },\n    overrideFormat(impl) {\n      const original = getFormatImpl();\n      const wrapped = (...args: Parameters<typeof FormatFn>) => impl(original, ...args) as ReturnType<typeof FormatFn>;\n      // The sandbox's bridge impl can answer several values in one\n      // subprocess round trip (callFormatImplBatch in runtime.ts). The\n      // batch travels as a property on the wrapper so the built-in\n      // format() it may need to fall back to is in scope where it's\n      // invoked — in-process mods never set one.\n      const batch = (impl as { formatMany?: BridgeFormatBatchFn }).formatMany;\n      if (typeof batch === 'function') {\n        (wrapped as typeof FormatFn & { formatMany?: FormatBatchFn }).formatMany =\n          (values, formatStr, options) => batch(values, formatStr, options, original);\n      }\n      setFormatOverride(wrapped, modName);\n    },\n    overrideParse(impl) {\n      const original = getParseImpl();\n      setParseOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideCompileFormat(impl) {\n      const original = getCompileFormatImpl();\n      setCompileFormatOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideCompileParser(impl) {\n      const original = getCompileParserImpl();\n      setCompileParserOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideParseRelative(impl) {\n      const original = getParseRelativeImpl();\n      setParseRelativeOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideExplainFormat(impl) {\n      const original = getExplainFormatImpl();\n      setExplainFormatOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideTokenizeFormat(impl) {\n      const original = getTokenizeFormatImpl();\n      setTokenizeFormatOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideListTokens(impl) {\n      const original = getListTokensImpl();\n      setListTokensOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideTokenInfo(impl) {\n      const original = getTokenInfoImpl();\n      setTokenInfoOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsValidFormat(impl) {\n      const original = getIsValidFormatImpl();\n      setIsValidFormatOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideValidateFormat(impl) {\n      const original = getValidateFormatImpl();\n      setValidateFormatOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFieldForToken(impl) {\n      const original = getFieldForTokenImpl();\n      setFieldForTokenOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideMonthsInYear(impl) {\n      const original = getMonthsInYearImpl();\n      setMonthsInYearOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsLeapYear(impl) {\n      const original = getIsLeapYearImpl();\n      setIsLeapYearOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsLeapMonth(impl) {\n      const original = getIsLeapMonthImpl();\n      setIsLeapMonthOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideWeekOfYear(impl) {\n      const original = getWeekOfYearImpl();\n      setWeekOfYearOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideWeekYear(impl) {\n      const original = getWeekYearImpl();\n      setWeekYearOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetMonth(impl) {\n      const original = getGetMonthImpl();\n      setGetMonthOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetWeekday(impl) {\n      const original = getGetWeekdayImpl();\n      setGetWeekdayOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsEqual(impl) {\n      const original = getIsEqualImpl();\n      setIsEqualOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsBefore(impl) {\n      const original = getIsBeforeImpl();\n      setIsBeforeOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsAfter(impl) {\n      const original = getIsAfterImpl();\n      setIsAfterOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideClamp(impl) {\n      const original = getClampImpl();\n      setClampOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsBetween(impl) {\n      const original = getIsBetweenImpl();\n      setIsBetweenOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsToday(impl) {\n      const original = getIsTodayImpl();\n      setIsTodayOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsTomorrow(impl) {\n      const original = getIsTomorrowImpl();\n      setIsTomorrowOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsYesterday(impl) {\n      const original = getIsYesterdayImpl();\n      setIsYesterdayOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsSameDay(impl) {\n      const original = getIsSameDayImpl();\n      setIsSameDayOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsSameWeek(impl) {\n      const original = getIsSameWeekImpl();\n      setIsSameWeekOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsSameMonth(impl) {\n      const original = getIsSameMonthImpl();\n      setIsSameMonthOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsSameQuarter(impl) {\n      const original = getIsSameQuarterImpl();\n      setIsSameQuarterOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsSameYear(impl) {\n      const original = getIsSameYearImpl();\n      setIsSameYearOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIsWeekday(impl) {\n      const original = getIsWeekdayImpl();\n      setIsWeekdayOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFloor(impl) {\n      const original = getFloorImpl();\n      setFloorOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideCeil(impl) {\n      const original = getCeilImpl();\n      setCeilOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideTruncate(impl) {\n      const original = getTruncateImpl();\n      setTruncateOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideParseRFC3339(impl) {\n      const original = getParseRFC3339Impl();\n      setParseRFC3339Override((...args) => impl(original, ...args), modName);\n    },\n    overrideFormatRFC3339(impl) {\n      const original = getFormatRFC3339Impl();\n      setFormatRFC3339Override((...args) => impl(original, ...args), modName);\n    },\n    overrideParseRFC2822(impl) {\n      const original = getParseRFC2822Impl();\n      setParseRFC2822Override((...args) => impl(original, ...args), modName);\n    },\n    overrideParseHTTPDate(impl) {\n      const original = getParseHTTPDateImpl();\n      setParseHTTPDateOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFromUnixMicroseconds(impl) {\n      const original = getFromUnixMicrosecondsImpl();\n      setFromUnixMicrosecondsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFromUnixNanoseconds(impl) {\n      const original = getFromUnixNanosecondsImpl();\n      setFromUnixNanosecondsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideToUnixSeconds(impl) {\n      const original = getToUnixSecondsImpl();\n      setToUnixSecondsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideToUnixMilliseconds(impl) {\n      const original = getToUnixMillisecondsImpl();\n      setToUnixMillisecondsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideToUnixMicroseconds(impl) {\n      const original = getToUnixMicrosecondsImpl();\n      setToUnixMicrosecondsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideToUnixNanoseconds(impl) {\n      const original = getToUnixNanosecondsImpl();\n      setToUnixNanosecondsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideParseSQL(impl) {\n      const original = getParseSQLImpl();\n      setParseSQLOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFormatSQL(impl) {\n      const original = getFormatSQLImpl();\n      setFormatSQLOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFormatDurationToParts(impl) {\n      const original = getFormatDurationToPartsImpl();\n      setFormatDurationToPartsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideParseDuration(impl) {\n      const original = getParseDurationImpl();\n      setParseDurationOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideParseISODuration(impl) {\n      const original = getParseISODurationImpl();\n      setParseISODurationOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFormatISODuration(impl) {\n      const original = getFormatISODurationImpl();\n      setFormatISODurationOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideBalanceDuration(impl) {\n      const original = getBalanceDurationImpl();\n      setBalanceDurationOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideCompareDuration(impl) {\n      const original = getCompareDurationImpl();\n      setCompareDurationOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideSubtractDuration(impl) {\n      const original = getSubtractDurationImpl();\n      setSubtractDurationOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetLocale(impl) {\n      const original = getGetLocaleImpl();\n      setGetLocaleOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideHasLocale(impl) {\n      const original = getHasLocaleImpl();\n      setHasLocaleOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideCreateConfig(impl) {\n      const original = getCreateConfigImpl();\n      setCreateConfigOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideMergeWithConfig(impl) {\n      const original = getMergeWithConfigImpl();\n      setMergeWithConfigOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideListRegisteredGrammars(impl) {\n      const original = getListRegisteredGrammarsImpl();\n      setListRegisteredGrammarsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideInterval(impl) {\n      const original = getIntervalImpl();\n      setIntervalOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideOverlaps(impl) {\n      const original = getOverlapsImpl();\n      setOverlapsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideIntersection(impl) {\n      const original = getIntersectionImpl();\n      setIntersectionOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideUnion(impl) {\n      const original = getUnionImpl();\n      setUnionOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideMergeIntervals(impl) {\n      const original = getMergeIntervalsImpl();\n      setMergeIntervalsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFormatRangeToParts(impl) {\n      const original = getFormatRangeToPartsImpl();\n      setFormatRangeToPartsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideBetween(impl) {\n      const original = getBetweenImpl();\n      setBetweenOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideParseRRule(impl) {\n      const original = getParseRRuleImpl();\n      setParseRRuleOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideFormatRRule(impl) {\n      const original = getFormatRRuleImpl();\n      setFormatRRuleOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideCreateBusinessCalendar(impl) {\n      const original = getCreateBusinessCalendarImpl();\n      setCreateBusinessCalendarOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideSubtractBusinessDays(impl) {\n      const original = getSubtractBusinessDaysImpl();\n      setSubtractBusinessDaysOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideNextHoliday(impl) {\n      const original = getNextHolidayImpl();\n      setNextHolidayOverride((...args) => impl(original, ...args), modName);\n    },\n    overridePreviousHoliday(impl) {\n      const original = getPreviousHolidayImpl();\n      setPreviousHolidayOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideResolveZoned(impl) {\n      const original = getResolveZonedImpl();\n      setResolveZonedOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetNextTransition(impl) {\n      const original = getGetNextTransitionImpl();\n      setGetNextTransitionOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetPreviousTransition(impl) {\n      const original = getGetPreviousTransitionImpl();\n      setGetPreviousTransitionOverride((...args) => impl(original, ...args), modName);\n    },\n    overridePossibleInstantsFor(impl) {\n      const original = getPossibleInstantsForImpl();\n      setPossibleInstantsForOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetAutocompleteData(impl) {\n      const original = getGetAutocompleteDataImpl();\n      setGetAutocompleteDataOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetHoverDocs(impl) {\n      const original = getGetHoverDocsImpl();\n      setGetHoverDocsOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetInlineDiagnostics(impl) {\n      const original = getGetInlineDiagnosticsImpl();\n      setGetInlineDiagnosticsOverride((...args) => impl(original, ...args), modName);\n    },\n    overridePreviewFormat(impl) {\n      const original = getPreviewFormatImpl();\n      setPreviewFormatOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideGetDocUrl(impl) {\n      const original = getGetDocUrlImpl();\n      setGetDocUrlOverride((...args) => impl(original, ...args), modName);\n    },\n    overrideTranslateDateFnsFormatString(impl) {\n      const original = getTranslateDateFnsFormatStringImpl();\n      setTranslateDateFnsFormatStringOverride((...args) => impl(original, ...args), modName);\n    },\n  };\n}\n\n// Convenience for callers that don't need per-mod attribution on\n// override conflicts (tests, ad-hoc scripts) — same behavior, generic\n// owner name.\nexport function buildModContext(): ModContext {\n  return buildModContextFor('(unattributed)');\n}\n\nexport interface ModRegistrationKey {\n  // which ModContext method was called\n  kind: 'locale' | 'localeVocab' | 'relativeGrammar' | 'formatterTokens' | 'formatToken' | 'overrideFormat' | 'overrideParse';\n  // the locale tag, grammar language, custom token name, or (for the two\n  // override kinds) just the literal string 'format'/'parse' — there's\n  // only one of each to conflict on, unlike the keyed registrations above\n  key: string;\n}\n\n// One ctx.log() or ctx.reportIssue() call, captured for the load report.\n// Unlike ModRegistrationKey these never conflict with each other — a\n// mod can log or report as many times as it wants — so there's no `key`\n// to collide on, just a stream of events the loader collects and shows.\nexport interface ModDiagnostic {\n  source: 'log' | 'reportIssue';\n  level: 'debug' | 'info' | 'warn' | 'error';\n  message: string;\n  // log()'s optional structured payload. Absent for reportIssue events\n  // (they carry `detail` instead, below).\n  meta?: Record<string, unknown>;\n  // reportIssue()'s optional free-form payload. Absent for log() events.\n  detail?: unknown;\n}\n\n// Wraps a ModContext so the loader can tell which mod touched which\n// registration key — a locale tag, a relative-grammar language, a custom\n// token name, or the format/parse override point. Registration itself\n// stays last-write-wins (unchanged behavior for every other caller of\n// registerLocale/etc.); this only exists to let the loader report \"mods\n// A and B both registered locale 'fr-CA'\" as a conflict, since silently\n// overwriting a mod's locale with another mod's locale is exactly the\n// kind of thing a mod author needs to know happened, even though the\n// registration functions themselves have no opinion on it.\n//\n// overrideFormat/overrideParse are different from the rest: they don't\n// silently overwrite on conflict, setFormatOverride/setParseOverride\n// throw OverrideConflictError immediately (see runtime.ts) rather than\n// letting the loader discover a collision after the fact. They're\n// tracked here anyway so a successful override still shows up in the\n// load report the same way a successful locale registration does.\n//\n// onDiagnostic is separate from onRegister rather than folded into the\n// same callback with a fake ModRegistrationKey: log()/reportIssue()\n// calls don't have a \"key\" two mods could conflict on, they're just a\n// stream of events for this one mod, so giving them their own shape\n// keeps ModRegistrationKey's `key` field meaningful (something that CAN\n// collide) instead of overloading it with something that never does.\n// Optional and defaulted to a no-op so the existing single-argument call\n// shape (tests, buildTrackedModContext(name, onRegister) alone) keeps\n// working unchanged.\nexport function buildTrackedModContext(\n  modName: string,\n  onRegister: (key: ModRegistrationKey) => void,\n  onDiagnostic: (event: ModDiagnostic) => void = () => {}\n): ModContext {\n  const base = buildModContextFor(modName);\n  return {\n    // Everything not called out below (all 81 zero-fan-out override\n    // points from runtime.ts, plus createHolidayCalendar) passes through\n    // untracked — see the comment on createHolidayCalendar's own case\n    // above for why untracked is correct for it, and generate.mjs for\n    // why we don't hand-list 81 identical `overrideXxx(impl) { base.\n    // overrideXxx(impl); onRegister(...) }` pass-throughs here: none of\n    // them have a shared key two mods could conflict on the way a locale\n    // tag or token name does, so there's nothing meaningful to track.\n    ...base,\n    log(level, message, meta) {\n      onDiagnostic({ source: 'log', level, message, meta });\n      base.log(level, message, meta);\n    },\n    reportIssue(issue) {\n      onDiagnostic({\n        source: 'reportIssue',\n        level: issue.severity === 'error' ? 'error' : 'warn',\n        message: issue.message,\n        detail: issue.detail,\n      });\n      base.reportIssue(issue);\n    },\n    registerLocale(locale, vocab) {\n      onRegister({ kind: 'locale', key: locale });\n      base.registerLocale(locale, vocab);\n    },\n    registerLocaleVocab(locale, vocab) {\n      onRegister({ kind: 'localeVocab', key: locale });\n      base.registerLocaleVocab(locale, vocab);\n    },\n    registerRelativeGrammar(grammar) {\n      onRegister({ kind: 'relativeGrammar', key: grammar.language });\n      base.registerRelativeGrammar(grammar);\n    },\n    createFormatter(options) {\n      for (const token of options?.tokens ?? []) {\n        onRegister({ kind: 'formatterTokens', key: token.name });\n      }\n      return base.createFormatter(options);\n    },\n    registerFormatToken(token) {\n      onRegister({ kind: 'formatToken', key: token.name });\n      base.registerFormatToken(token);\n    },\n    createHolidayCalendar(specs) {\n      // Not tracked: createHolidayCalendar returns a fresh, unshared\n      // HolidayCalendar rather than registering into global state, so two\n      // mods calling it can never collide with each other the way a\n      // locale-tag or token-name registration can — there's no shared key\n      // to conflict on.\n      return base.createHolidayCalendar(specs);\n    },\n    overrideFormat(impl) {\n      base.overrideFormat(impl); // throws OverrideConflictError before onRegister if already taken\n      onRegister({ kind: 'overrideFormat', key: 'format' });\n    },\n    overrideParse(impl) {\n      base.overrideParse(impl);\n      onRegister({ kind: 'overrideParse', key: 'parse' });\n    },\n  };\n}\n\nexport interface Mod {\n  name: string;\n  // shown in the loader's report, otherwise unused — mods aren't\n  // version-checked against the host library right now\n  version?: string;\n  // other mods' `name` fields that must load (and register) before this\n  // one. missing or circular dependencies fail just this mod, not the\n  // whole batch — see scripts/loadMods.mjs\n  requires?: string[];\n  // load-order tiebreak within the same dependency layer. higher loads\n  // later, so a higher-priority mod's registrations win over a\n  // lower-priority one's on the same key (locale tag, token name, etc —\n  // registration itself is already last-write-wins, priority just makes\n  // \"which write is last\" something a mod author can control instead of\n  // leaving it to alphabetical filename order). defaults to 0.\n  priority?: number;\n  // Resolved user settings, or {} if this mod declared no config schema\n  // (or can't — a loose .mjs mod has no manifest to declare one in;\n  // only a .tfmod's mod.json can). Untyped here on purpose: the shape\n  // comes from mod.json's \"config\" array, which is data the loader\n  // reads at runtime, not something this type-level interface can see.\n  // A mod author who wants real types for their own settings should\n  // declare their own interface and cast, the same way they'd type\n  // anything else sourced from JSON.\n  register(ctx: ModContext, config: Record<string, unknown>): void | Promise<void>;\n}\n\nexport function isMod(value: unknown): value is Mod {\n  if (typeof value !== 'object' || value === null) return false;\n  const v = value as Record<string, unknown>;\n  if (typeof v.name !== 'string' || v.name.length === 0) return false;\n  if (typeof v.register !== 'function') return false;\n  if (v.requires !== undefined && !(Array.isArray(v.requires) && v.requires.every((r) => typeof r === 'string'))) return false;\n  if (v.priority !== undefined && typeof v.priority !== 'number') return false;\n  return true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAAC;AAAA,EAAA,eAAAC;AAAA,EAAA;AAAA;AAAA;AAAA,cAAAC;AAAA,EAAA,aAAAC;AAAA,EAAA;AAAA,yBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA;AAAA;AAAA,gCAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,oBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,aAAAC;AAAA,EAAA,cAAAC;AAAA,EAAA;AAAA;AAAA;AAAA,+BAAAC;AAAA,EAAA;AAAA;AAAA,2BAAAC;AAAA,EAAA;AAAA,uBAAAC;AAAA,EAAA,mBAAAC;AAAA,EAAA;AAAA,4BAAAC;AAAA,EAAA;AAAA;AAAA,mBAAAC;AAAA,EAAA;AAAA,8BAAAC;AAAA,EAAA;AAAA,6BAAAC;AAAA,EAAA;AAAA,6BAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA,4BAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA,gBAAAC;AAAA,EAAA,yBAAAC;AAAA,EAAA;AAAA;AAAA,+BAAAC;AAAA,EAAA;AAAA;AAAA;AAAA,oBAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA;AAAA,sBAAAC;AAAA,EAAA;AAAA,kBAAAC;AAAA,EAAA;AAAA;AAAA,yBAAAC;AAAA,EAAA,wBAAAC;AAAA,EAAA;AAAA,iBAAAD;AAAA,EAAA,gBAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA,iBAAAC;AAAA,EAAA;AAAA,qBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAAC;AAAA,EAAA,mBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA;AAAA,iBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA;AAAA,qBAAAC;AAAA,EAAA;AAAA,gCAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA;AAAA,wBAAAC;AAAA,EAAA,uBAAAC;AAAA,EAAA;AAAA,sBAAAC;AAAA,EAAA;AAAA,qBAAAC;AAAA,EAAA,gBAAAC;AAAA,EAAA,aAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA;AAAA,0BAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,gBAAAC;AAAA,EAAA;AAAA,6BAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA;AAAA,yBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,sBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAAC;AAAA,EAAA,4BAAAC;AAAA,EAAA;AAAA,0BAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAC;AAAA,EAAA,0BAAAC;AAAA,EAAA,yBAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,iBAAAC;AAAA,EAAA,sBAAAC;AAAA,EAAA;AAAA,sCAAAC;AAAA,EAAA;AAAA,kBAAAC;AAAA,EAAA;AAAA,eAAAC;AAAA,EAAA,sBAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA,gBAAAC;AAAA;AAAA;;;AC4DA,IAAI;AAQJ,IAAM,oBAAuC,CAAC;AAEvC,SAAS,2BAA2B,UAA4B;AACrE,oBAAkB,KAAK,QAAQ;AACjC;AAeO,SAAS,YAAY,UAAoC;AAC9D,qBAAmB;AAMnB,aAAW,YAAY,kBAAmB,UAAS;AACrD;AAEA,SAAS,kBAAiD;AACxD,SAAO,oBAAqB,WAA2D;AACzF;AAEO,SAAS,cAAiC;AAC/C,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AACA,SAAO;AACT;;;AC/BO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,QAAgC;AAC3D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,QAAQ,OAAO;AACpB,SAAK,WAAW,OAAO;AACvB,SAAK,WAAW,OAAO;AACvB,SAAK,SAAS,OAAO;AACrB,SAAK,SAAS,OAAO;AAIrB,UAAM,UAAW,MAAsF;AACvG,QAAI,OAAO,YAAY,YAAY;AACjC,cAAQ,MAAM,KAAK,WAAW;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAqE;AACnE,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AACF;AAOO,IAAM,oBAAN,cAAgC,iBAAiB;AAAA,EACtD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,kBAAkB,OAAO,UAAU,EAAE,uBAAuB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAChH,EAAE,MAAM,uBAAuB,GAAG,KAAK;AAAA,IACzC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,iBAAiB;AAAA,EACtD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,2CAA2C,OAAO,SAAS,sBAAsB,OAAO,MAAM,MAAM,EAAE;AAAA,MAC7I,EAAE,MAAM,iBAAiB,GAAG,KAAK;AAAA,IACnC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,iBAAiB;AAAA,EACvD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,4BAA4B,OAAO,UAAU,EAAE,IAAI,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACnI,EAAE,MAAM,kBAAkB,GAAG,KAAK;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,mBAAN,cAA+B,iBAAiB;AAAA,EACrD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,mCAAmC,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACnH,EAAE,MAAM,gBAAgB,GAAG,KAAK;AAAA,IAClC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,IAAM,mBAAN,cAA+B,iBAAiB;AAAA,EACrD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,mCAAmC,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACnH,EAAE,MAAM,gBAAgB,GAAG,KAAK;AAAA,IAClC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AACA;AAEO,IAAM,qBAAN,cAAiC,iBAAiB;AAAA,EACvD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,WAAW,OAAO,UAAU,EAAE,eAAe,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACjG,EAAE,MAAM,kBAAkB,GAAG,KAAK;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,iBAAiB;AAAA,EACzD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,cAAc,OAAO,UAAU,EAAE,uDAAuD,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAC5I,EAAE,MAAM,qBAAqB,GAAG,KAAK;AAAA,IACvC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,IAAM,uBAAN,cAAmC,iBAAiB;AAAA,EACzD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,aAAa,OAAO,UAAU,EAAE,qBAAqB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACzG,EAAE,MAAM,oBAAoB,GAAG,KAAK;AAAA,IACtC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AACA;AAEO,IAAM,sBAAN,cAAkC,iBAAiB;AAAA,EACxD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,iBAAiB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACjG,EAAE,MAAM,mBAAmB,GAAG,KAAK;AAAA,IACrC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,iBAAiB;AAAA,EACvD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,WAAW,OAAO,UAAU,EAAE,8BAA8B,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAChH,EAAE,MAAM,kBAAkB,GAAG,KAAK;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,iBAAiB;AAAA,EACzD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,sBAAsB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAC1E,EAAE,MAAM,oBAAoB,GAAG,KAAK;AAAA,IACtC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAiBA;AAAA;AAEO,SAAS,iBAAiB,KAAY,SAAgE;AAK3G,QAAM,MAAM,IAAI;AAChB,MAAI,yCAAyC,KAAK,GAAG,GAAG;AACtD,WAAO,IAAI,kBAAkB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC5F;AACA,MAAI,aAAa,KAAK,GAAG,GAAG;AAC1B,WAAO,IAAI,oBAAoB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC9F;AACA,MAAI,SAAS,KAAK,GAAG,KAAK,gDAAgD,KAAK,GAAG,GAAG;AACnF,WAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7F;AACA,MAAI,4BAA4B,KAAK,GAAG,GAAG;AACzC,WAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7F;AACA,MAAI,kFAAkF,KAAK,GAAG,GAAG;AAC/F,WAAO,IAAI,iBAAiB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC3F;AACA,QAAM,WAAW,IAAI,YAAY;AACjC,QAAM,iBAAiB,SAAS,SAAS,QAAQ;AACjD,MACG,mBAAmB,SAAS,SAAS,aAAa,KAAK,SAAS,SAAS,aAAa,MACvF,SAAS,SAAS,iBAAiB,GACnC;AACA,WAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7F;AACA,MAAI,iHAAiH,KAAK,GAAG,GAAG;AAC9H,WAAO,IAAI,kBAAkB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC5F;AACA,SAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAC7F;AACA;;;AC1SA,IAAM,eAAe,oBAAI,IAAyB;AAClD,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAC9B,IAAM,yBAAyB;AAE/B,SAAS,iBAAiB,OAA6B,QAAsB;AAM3E,QAAM,WAA6E;AAAA,IACjF,EAAE,KAAK,aAAa,QAAQ,IAAI,OAAO,mBAAmB;AAAA,IAC1D,EAAE,KAAK,cAAc,QAAQ,IAAI,OAAO,oBAAoB;AAAA,IAC5D,EAAE,KAAK,eAAe,QAAQ,GAAG,OAAO,qBAAqB;AAAA,IAC7D,EAAE,KAAK,gBAAgB,QAAQ,GAAG,OAAO,sBAAsB;AAAA,IAC/D,EAAE,KAAK,aAAa,QAAQ,GAAG,OAAO,wCAAwC;AAAA,EAChF;AAEA,aAAW,EAAE,KAAK,QAAQ,MAAM,KAAK,UAAU;AAC7C,UAAM,QAAQ,MAAM,GAAG;AACvB,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI;AAAA,QACR,iDAAiD,MAAM,gCAAgC,GAAG,MAAM,KAAK;AAAA,MACvG;AAAA,IACF;AACA,QAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,iDAAiD,MAAM,OAAO,GAAG,2BAA2B,OAAO,KAAK;AAAA,MAC1G;AAAA,IACF;AACA,QAAI,MAAM,WAAW,QAAQ;AAC3B,YAAM,IAAI;AAAA,QACR,iDAAiD,MAAM,OAAO,GAAG,uBAAuB,MAAM,iBAAiB,MAAM,MAAM,YAAO,KAAK;AAAA,MACzI;AAAA,IACF;AACA,UAAM,QAAQ,CAAC,OAAO,MAAM;AAC1B,UAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,cAAM,IAAI;AAAA,UACR,iDAAiD,MAAM,OAAO,GAAG,IAAI,CAAC,sCAAsC,OAAO,KAAK,CAAC;AAAA,QAC3H;AAAA,MACF;AACA,UAAI,MAAM,SAAS,wBAAwB;AACzC,cAAM,IAAI;AAAA,UACR,iDAAiD,MAAM,OAAO,GAAG,IAAI,CAAC,2BAA2B,sBAAsB;AAAA,QACzH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAKA,oBAAkB,MAAM,WAAY,cAAc,MAAM;AACxD,oBAAkB,MAAM,YAAa,aAAa,MAAM;AACxD,oBAAkB,MAAM,aAAc,gBAAgB,MAAM;AAC5D,oBAAkB,MAAM,cAAe,eAAe,MAAM;AAQ5D,MAAI,MAAM,UAAW,CAAC,MAAM,MAAM,UAAW,CAAC,GAAG;AAC/C,UAAM,IAAI;AAAA,MACR,iDAAiD,MAAM,+CACzC,MAAM,UAAW,CAAC,CAAC;AAAA,IACnC;AAAA,EACF;AACF;AAOA,IAAM,iBAAoC,CAAC;AAEpC,SAAS,wBAAwB,UAA4B;AAClE,iBAAe,KAAK,QAAQ;AAC9B;AA2BO,SAAS,oBAAoB,QAAgB,OAAmC;AACrF,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;AACrD,UAAM,IAAI,MAAM,6EAA6E,OAAO,MAAM,CAAC,GAAG;AAAA,EAChH;AACA,MAAI,OAAO,SAAS,uBAAuB;AACzC,UAAM,IAAI,WAAW,iEAAiE,qBAAqB,eAAe;AAAA,EAC5H;AACA,mBAAiB,OAAO,MAAM;AAE9B,QAAM,WAAW,kBAAkB,MAAM;AACzC,MAAI,CAAC,aAAa,IAAI,QAAQ,KAAK,aAAa,QAAQ,mBAAmB;AACzE,UAAM,IAAI,WAAW,iDAAiD,iBAAiB,gBAAgB;AAAA,EACzG;AACA,eAAa,IAAI,UAAU;AAAA,IACzB,WAAW,CAAC,GAAG,MAAM,SAAU;AAAA,IAC/B,YAAY,CAAC,GAAG,MAAM,UAAW;AAAA,IACjC,aAAa,CAAC,GAAG,MAAM,WAAY;AAAA,IACnC,cAAc,CAAC,GAAG,MAAM,YAAa;AAAA,IACrC,WAAW,CAAC,GAAG,MAAM,SAAU;AAAA,EACjC,CAAC;AAKD,aAAW,OAAO,QAAQ;AAM1B,aAAW,YAAY,eAAgB,UAAS;AAClD;AAwBO,SAAS,mBAAmB,QAAwB;AACzD,SAAO,OAAO,QAAQ,MAAM,GAAG;AACjC;AAMA,IAAM,oBAAoB,oBAAI,IAAoB;AAClD,IAAM,0BAA0B;AAEzB,SAAS,kBAAkB,QAAwB;AACxD,QAAM,MAAM,kBAAkB,IAAI,MAAM;AACxC,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACJ,MAAI;AAKF,UAAM,IAAI,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC,EAAE,SAAS,EAAE,YAAY;AAAA,EAC1E,QAAQ;AAKN,UAAM;AAAA,EACR;AACA,MAAI,kBAAkB,QAAQ,yBAAyB;AACrD,UAAM,YAAY,kBAAkB,KAAK,EAAE,KAAK,EAAE;AAClD,QAAI,cAAc,OAAW,mBAAkB,OAAO,SAAS;AAAA,EACjE;AACA,oBAAkB,IAAI,QAAQ,GAAG;AACjC,SAAO;AACT;AAQO,SAAS,qBAAqB,QAAsB;AACzD,MAAI;AACF,QAAI,KAAK,OAAO,mBAAmB,MAAM,CAAC;AAAA,EAC5C,QAAQ;AACN,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAEA,IAAM,aAAa,oBAAI,IAAyB;AAChD,IAAM,uBAAuB;AAYtB,SAAS,UAAU,WAAgC,MAAY,MAA4C;AAChH,QAAM,QAAQ,UAAU,cAAc,IAAI;AAC1C,QAAM,QAAQ,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA;AACA,MAAI,UAAU,IAAI;AAChB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,SAAS,qCAAqC,IAAI;AAAA,IACpD,CAAC;AAAA,EACH;AAAA,EACA;AACA,MAAI,QAAQ,MAAM,KAAK,EAAG;AAC1B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAG5B,MAAI,MAAM,SAAS,aAAa,CAAC,KAAK,KAAK,KAAK,KAAK,EAAG,SAAQ,KAAK,QAAQ;AAC7E,MAAI,MAAM,SAAS,aAAa,CAAC,KAAK,KAAK,KAAK,KAAK,EAAG,SAAQ,QAAQ,KAAK;AAC7E,SAAO;AACT;AAQA,SAAS,kBAAkB,OAAiB,OAAe,QAAsB;AAC/E,QAAM,OAAO,oBAAI,IAAoB;AACrC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,CAAE;AAChC,QAAI,UAAU,QAAW;AASvB,YAAM,IAAI;AAAA,QACR,yBAAyB,MAAM,aAAa,KAAK,UAAU,KAAK,QAAQ,CAAC,kBACpE,MAAM,CAAC,CAAC;AAAA,MAEf;AAAA,IACF;AACA,SAAK,IAAI,MAAM,CAAC,GAAI,CAAC;AAAA,EACvB;AACF;AAQO,SAAS,eAAe,QAAyC;AACtE,QAAM,WAAW,kBAAkB,MAAM;AACzC,SAAO,aAAa,IAAI,QAAQ;AAClC;AAEO,SAAS,eAAe,QAA6B;AAG1D,uBAAqB,MAAM;AAC3B,QAAM,WAAW,kBAAkB,MAAM;AAMzC,QAAM,SAAS,aAAa,IAAI,QAAQ;AACxC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AACA,QAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,mBAAmB,MAAM;AAC5C,QAAM,eAAe,IAAI,KAAK,eAAe,YAAY,EAAE,OAAO,QAAQ,UAAU,MAAM,CAAC;AAC3F,QAAM,gBAAgB,IAAI,KAAK,eAAe,YAAY,EAAE,OAAO,SAAS,UAAU,MAAM,CAAC;AAC7F,QAAM,YAAsB,CAAC;AAC7B,QAAM,aAAuB,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,OAAO,IAAI,KAAK,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC;AAC1C,cAAU,KAAK,UAAU,cAAc,MAAM,OAAO,CAAC;AACrD,eAAW,KAAK,UAAU,eAAe,MAAM,OAAO,CAAC;AAAA,EACzD;AACA,oBAAkB,WAAW,cAAc,MAAM;AACjD,oBAAkB,YAAY,aAAa,MAAM;AAEjD,QAAM,iBAAiB,IAAI,KAAK,eAAe,YAAY,EAAE,SAAS,QAAQ,UAAU,MAAM,CAAC;AAC/F,QAAM,kBAAkB,IAAI,KAAK,eAAe,YAAY,EAAE,SAAS,SAAS,UAAU,MAAM,CAAC;AACjG,QAAM,cAAwB,CAAC;AAC/B,QAAM,eAAyB,CAAC;AAEhC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,OAAO,IAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC;AAC9C,gBAAY,KAAK,UAAU,gBAAgB,MAAM,SAAS,CAAC;AAC3D,iBAAa,KAAK,UAAU,iBAAiB,MAAM,SAAS,CAAC;AAAA,EAC/D;AAEA,oBAAkB,aAAa,gBAAgB,MAAM;AACrD,oBAAkB,cAAc,eAAe,MAAM;AAErD,QAAM,eAAe,IAAI,KAAK,eAAe,YAAY,EAAE,MAAM,WAAW,QAAQ,MAAM,UAAU,MAAM,CAAC;AAC3G,QAAM,KAAK,UAAU,cAAc,IAAI,KAAK,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,WAAW;AACjF,QAAM,KAAK,UAAU,cAAc,IAAI,KAAK,KAAK,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,WAAW;AAClF,QAAM,YAAY,CAAC,GAAG,oBAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAEvC,QAAM,QAAqB,EAAE,WAAW,YAAY,aAAa,cAAc,UAAU;AACzF,MAAI,WAAW,QAAQ,sBAAsB;AAC3C,UAAM,YAAY,WAAW,KAAK,EAAE,KAAK,EAAE;AAC3C,QAAI,cAAc,OAAW,YAAW,OAAO,SAAS;AAAA,EAC1D;AACA,aAAW,IAAI,UAAU,KAAK;AAC9B,SAAO;AACT;;;AC7WA,IAAM,2BAA2B,CAAC,GAAG,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAEhF,SAAS,oBAAoB,MAAuB;AAIzD,SAAQ,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ;AAChE;AAEA,SAAS,WAAW,MAAyB;AAC3C,SAAO,oBAAoB,IAAI,IAAI,MAAM;AAC3C;AAEO,SAAS,UAAU,MAAc,OAAe,KAAqB;AAC1E,MAAI,MAAM,yBAAyB,QAAQ,CAAC,IAAK;AACjD,MAAI,QAAQ,KAAK,oBAAoB,IAAI,EAAG,QAAO;AACnD,SAAO;AACT;AAKA,IAAM,iBAAiB;AACvB,IAAM,6BAA6B;AAW5B,SAAS,cAAc,MAAc,OAAe,KAAqB;AAC9E,QAAM,KAAK,SAAS,IAAI,OAAO,IAAI;AACnC,QAAM,MAAM,KAAK,MAAM,KAAK,GAAG;AAC/B,QAAM,MAAM,KAAK,MAAM;AACvB,QAAM,KAAK,QAAQ,IAAI,QAAQ,IAAI,QAAQ;AAC3C,QAAM,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK,CAAC,IAAI,MAAM;AACnD,QAAM,MAAM,MAAM,MAAM,KAAK,MAAM,MAAM,CAAC,IAAI,KAAK,MAAM,MAAM,GAAG,IAAI;AACtE,SAAO,MAAM,SAAS,MAAM;AAC9B;AAQO,SAAS,mBAAmB,MAAc,OAAe,KAAqB;AACnF,QAAM,OAAO,cAAc,MAAM,OAAO,GAAG;AAE3C,WAAU,OAAO,KAAK,IAAK,KAAK,IAAI;AACtC;AAEA,SAAS,gBAAgB,MAAsB;AAK7C,QAAM,OAAO,cAAc,MAAM,GAAG,CAAC,IAAI,cAAc,gBAAgB,GAAG,CAAC;AAC3E,QAAM,gBAAiB,6BAA6B,IAAI,QAAQ,IAAK,KAAK;AAC1E,SAAO,cAAc;AACvB;AAOO,SAAS,mBAAmB,MAAc,OAAe,KAAa,WAAgC;AAI3G,QAAM,MAAM,UAAU,MAAM,OAAO,GAAG;AACtC,QAAM,sBAAsB,OAAO,IAAI;AAEvC,MAAI;AACJ,MAAI;AACJ,MAAI,sBAAsB,GAAG;AAC3B,cAAU,OAAO;AACjB,kBAAc,sBAAsB,WAAW,OAAO;AAAA,EACxD,WAAW,sBAAsB,WAAW,IAAI,GAAG;AACjD,cAAU,OAAO;AACjB,kBAAc,sBAAsB,WAAW,IAAI;AAAA,EACrD,OAAO;AACL,cAAU;AACV,kBAAc;AAAA,EAChB;AAIA,QAAM,UAAU,gBAAgB,OAAO;AACvC,QAAM,mBAAmB,KAAM,IAAI,UAAU,KAAK;AAGlD,QAAM,OAAO,IAAI,KAAK,OAAO,cAAc,oBAAoB,CAAC;AAChE,SAAO,EAAE,SAAS,KAAK;AACzB;;;ACnGA,SAAS,cAAc,GAAiB,UAAkB,QAAyC;AACjG,aAAW,SAAS,QAAQ;AAC1B,QAAI,EAAE,KAAK,MAAM,QAAW;AAC1B,YAAM,IAAI,kBAAkB;AAAA,QAC1B;AAAA,QACA,SACE,wBAAwB,KAAK,eAAe,KAAK;AAAA,MAGrD,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,IAAI,GAAW,KAAqB;AAGlD,QAAM,WAAW,IAAI;AACrB,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE,SAAS,KAAK,GAAG;AACpD,SAAO,WAAW,MAAM,SAAS;AACnC;AAmBA,IAAI,WAAW,SAAS,eAAe,GAAiB,OAAuB;AAC7E,QAAM,eAAe,EAAE,cAAe,OAAa,EAAE,eAAe,KAAK,OAAS,EAAE,cAAc;AAClG,SAAO,IAAI,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK;AAC5C;AAyCO,IAAM,iBAAiB;AAI9B,IAAM,iBAAiB,oBAAI,IAAiC;AAC5D,IAAM,iBAAiB;AAEvB,SAAS,aAAa,QAAgB,SAA0D;AAC9F,QAAM,MAAM,KAAK,UAAU,CAAC,kBAAkB,MAAM,GAAG,OAAO,CAAC;AAC/D,MAAI,YAAY,eAAe,IAAI,GAAG;AACtC,MAAI,WAAW;AACb,WAAO;AAAA,EACT;AACA,MAAI,eAAe,QAAQ,gBAAgB;AAEzC,UAAM,YAAY,eAAe,KAAK,EAAE,KAAK,EAAE;AAC/C,QAAI,cAAc,OAAW,gBAAe,OAAO,SAAS;AAAA,EAC9D;AACA,MAAI;AACF,gBAAY,IAAI,KAAK,eAAe,mBAAmB,MAAM,GAAG,OAAO;AAAA,EACzE,SAAS,KAAK;AAOZ,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAS,IAAc,QAAQ,CAAC;AAAA,EACjF;AACA,iBAAe,IAAI,KAAK,SAAS;AACjC,SAAO;AACT;AAWA,IAAI;AAMJ,2BAA2B,MAAM;AAAE,kBAAgB;AAAW,CAAC;AAE/D,SAAS,6BAAsC;AAC7C,MAAI,kBAAkB,QAAW;AAC/B,oBAAgB;AACd,QAAI;AACF,YAAM,WAAW,YAAY;AAC7B,UAAI,KAAK,eAAe,SAAS,EAAE,KAAK,UAAU,CAAC,EAChD,cAAc,SAAS,UAAU,KAAK,EAAE,MAAM,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC,CAAS;AAKlF,sBAAgB;AAAA,IAElB,QAAQ;AAAA,IAOR;AAAA,EAEJ;AACA,SAAO;AACT;AAcA,IAAM,yBAAyB;AAC/B,IAAM,0BAA0B;AAChC,IAAM,wBAAwB;AAU9B,SAAS,yBAAyB,GAA0B;AAC1D,MAAI,EAAE,SAAS,uBAAwB,QAAO,OAAO,EAAE,IAAI,IAAI;AAC/D,MAAI,EAAE,UAAU,wBAAyB,QAAO,OAAO,EAAE,KAAK,IAAI;AAClE,SAAO,OAAO,EAAE,GAAG,IAAI;AACzB;AAkBA,SAAS,wBACP,UACA,QACA,kBACA,UACQ;AAOR,QAAM,YAAY,aAAa,UAC3B,IAAI,KAAK,KAAK,IAAI,MAAM,SAAS,QAAS,GAAG,CAAC,CAAC,IAC/C,IAAI,KAAK,KAAK,IAAI,MAAM,GAAG,SAAS,SAAU,CAAC;AACnD,QAAM,YAAY,aAAa,QAAQ,EAAE,GAAG,kBAAkB,UAAU,MAAM,CAAC;AAC/E,SAAO,UAAU,WAAW,WAAW,QAAQ;AACjD;AAEA,SAAS,SACP,UACA,QACA,SACA,UACQ;AAyBR,QAAM,WAAW,UAAU;AAC3B,QAAM,mBAA+C;AAAA,IACnD,GAAG;AAAA,IACH,UAAU,YAAY,aAAa,YAAY,WAAW;AAAA,EAC5D;AAaA,QAAM,KAAK,SAAS;AACpB,MAAI,OAAO,OAAO,cAAc,OAAO,OAAO,UAAU,gBAAgB;AACtE,UAAM,IAAI;AAAA,MACR,oCAAoC,QAAQ;AAAA,IAG9C;AAAA,EACF;AAoBA,OACG,aAAa,WAAW,aAAa,cACtC,iBAAiB,aAAa,aAC9B,yBAAyB,QAAQ,GACjC;AACA,WAAO,wBAAwB,UAAU,QAAQ,kBAAkB,QAAQ;AAAA,EAC7E;AAuBA,MAAI,CAAC,2BAA2B,GAAG;AAOjC,QAAI;AACF,aAAO,GAAG,KAAK,UAAU,mBAAmB,MAAM,GAAG,gBAAgB;AAAA,IACvE,SAAS,KAAK;AAGZ,UAAI,eAAe,YAAY;AAC7B,cAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AAAA,MACtE;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAKA,QAAM,EAAE,WAAW,WAAW,IAAI;AAClC,QAAM,UAAU,OAAO,cAAc,cAAc,OAAO,eAAe;AAGzE,QAAM,mBAAmB,UAAU,SAAS,UAAW,IAAI;AAC3D,QAAM,gBAA4C;AAAA,IAChD,GAAG;AAAA,IACH,GAAI,UAAU,EAAE,UAAU,WAAW,IAAI,CAAC;AAAA,EAC5C;AAEA,QAAM,YAAY,aAAa,QAAQ,aAAa;AACpD,QAAM,QAAQ,UAAU,cAAc,gBAAiC;AACvE,QAAM,QAAQ,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,QAAQ;AACxD,MAAI,UAAU,IAAI;AAChB,UAAM,IAAI;AAAA,MACR,yBAAyB,MAAM,kBAAkB,QAAQ;AAAA,IAE3D;AAAA,EACF;AAOA,MAAI,QAAQ,MAAM,KAAK,EAAG;AAC1B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,MAAI,MAAM,SAAS,aAAa,CAAC,KAAK,KAAK,KAAK,KAAK,EAAG,SAAQ,KAAK,QAAQ;AAC7E,MAAI,MAAM,SAAS,aAAa,CAAC,KAAK,KAAK,KAAK,KAAK,EAAG,SAAQ,QAAQ,KAAK;AAC7E,SAAO;AACT;AAWA,SAAS,cAAc,MAAc,QAAwB;AAM3D,QAAM,SAAS,eAAe,MAAM;AACpC,MAAI,QAAQ;AACV,WAAO,OAAO,KAAK,OAAO,UAAU,CAAC,IAAK,OAAO,UAAU,CAAC;AAAA,EAC9D;AACA,QAAM,OAAO,IAAI,KAAK,KAAK,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC;AAChD,QAAM,YAAY,aAAa,QAAQ,EAAE,MAAM,WAAW,QAAQ,MAAM,UAAU,MAAM,CAAC;AACzF,QAAM,OAAO,UAAU,cAAc,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,WAAW;AAS7E,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,yBAAyB,MAAM,+CAA+C;AAAA,EAChG;AAEA,SAAO,KAAK;AACd;AAOA,SAAS,gBACP,UACA,QACA,SACA,UACA,aACA,aACQ;AACR,MAAI,eAAe,gBAAgB,UAAa,eAAe,KAAK,cAAc,YAAY,QAAQ;AACpG,WAAO,YAAY,WAAW;AAAA,EAChC;AACA,SAAO,SAAS,UAAU,QAAQ,SAAS,QAAQ;AACrD;AAaA,SAAS,aAAa,QAAgB,SAA0D;AAC9F,MAAI,WAAW,aAAa,YAAY,OAAO,YAAY,QAAQ,YAAY,QAAQ;AACrF,WAAO;AAAA,EACT;AAQA,MAAI,OAAO,SAAS,GAAG;AACrB,QAAI,YAAY,OAAO;AACrB,aAAO;AAAA,IACT;AACA,UAAM,IAAI;AAAA,MACR,wBAAwB,OAAO,kCAAkC,MAAM;AAAA,IAIzE;AAAA,EACF;AACA,QAAM,OAAO,OAAO,CAAC;AACrB,QAAM,QAAQ,OAAO,MAAM,GAAG,CAAC;AAC/B,QAAM,UAAU,OAAO,MAAM,GAAG,CAAC;AACjC,UAAQ,SAAS;AAAA,IACf,KAAK;AAAA,IAAK,KAAK;AAKb,aAAO,YAAY,OAAO,GAAG,IAAI,GAAG,KAAK,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO;AAAA,IACzE,KAAK;AAAA,IAAM,KAAK;AACd,aAAO,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO;AAAA,IAClC,KAAK;AAAA,IAAO,KAAK;AACf,aAAO,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO;AAAA,EACrC;AACF;AAUO,IAAM,SAA4D;AAAA,EACvE,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,MAAO,CAAC,GAAG,MAAM;AAAA,EACvC,CAAC,MAAM,CAAC,MAAM;AAGZ,QAAI,EAAE,OAAQ,GAAG;AACf,YAAM,IAAI;AAAA,QACR,gEAAgE,EAAE,IAAI;AAAA,MAGxE;AAAA,IACF;AACA,WAAO,IAAI,EAAE,OAAQ,KAAK,CAAC;AAAA,EAC7B,GAAG,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,MAAO,CAAC,GAAG,MAAM;AAAA,EACpC,CAAC,QAAQ,CAAC,GAAG,WAAW;AACtB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,OAAO,OAAO,GAAG,SAAS,QAAQ,WAAW,EAAE,QAAS,CAAC;AAAA,EAC/F,GAAG,OAAO;AAAA,EACV,CAAC,OAAO,CAAC,GAAG,WAAW;AACrB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,OAAO,QAAQ,GAAG,SAAS,QAAQ,YAAY,EAAE,QAAS,CAAC;AAAA,EACjG,GAAG,OAAO;AAAA,EACV,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,OAAQ,CAAC,GAAG,OAAO;AAAA,EACvC,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,KAAM,GAAG,OAAO;AAAA,EACtC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,KAAM,CAAC,GAAG,KAAK;AAAA,EACnC,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,GAAI,GAAG,KAAK;AAAA,EAClC,CAAC,QAAQ,CAAC,GAAG,WAAW;AACtB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,SAAS,OAAO,GAAG,WAAW,QAAQ,aAAa,EAAE,YAAa,CAAC;AAAA,EACzG,GAAG,WAAW;AAAA,EACd,CAAC,OAAO,CAAC,GAAG,WAAW;AACrB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,SAAS,QAAQ,GAAG,WAAW,QAAQ,cAAc,EAAE,YAAa,CAAC;AAAA,EAC3G,GAAG,WAAW;AAAA,EACd,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,MAAO,CAAC,GAAG,MAAM;AAAA,EACrC,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,IAAK,GAAG,MAAM;AAAA,EACpC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,OAAQ,MAAM,IAAI,CAAC,GAAG,MAAM;AAAA,EAChD,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,OAAQ,MAAM,EAAE,GAAG,MAAM;AAAA,EAC/C,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,QAAS,CAAC,GAAG,QAAQ;AAAA,EACzC,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,MAAO,GAAG,QAAQ;AAAA,EACxC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,QAAS,CAAC,GAAG,QAAQ;AAAA,EACzC,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,MAAO,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASxC,CAAC,aAAa,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EACtD,CAAC,YAAY,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EACrD,CAAC,WAAW,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EACpD,CAAC,UAAU,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EACnD,CAAC,SAAS,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EAClD,CAAC,QAAQ,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EACjD,CAAC,OAAO,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EAChD,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA,EAC/C,CAAC,KAAK,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,GAAG,aAAa;AAAA;AAAA;AAAA,EAG9C,CAAC,KAAK,CAAC,GAAG,WAAW,cAAc,EAAE,MAAO,MAAM,GAAG,MAAM;AAAA,EAC3D,CAAC,OAAO,CAAC,MAAM,EAAE,YAAa,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1C,CAAC,OAAO,CAAC,MAAM,aAAa,EAAE,QAAS,KAAK,GAAG,QAAQ;AAAA,EACvD,CAAC,MAAM,CAAC,MAAM,aAAa,EAAE,QAAS,IAAI,GAAG,QAAQ;AAAA,EACrD,CAAC,KAAK,CAAC,MAAM,aAAa,EAAE,QAAS,GAAG,GAAG,QAAQ;AAAA,EACnD,CAAC,MAAM,CAAC,MAAM,aAAa,EAAE,QAAS,IAAI,GAAG,QAAQ;AAAA,EACrD,CAAC,OAAO,CAAC,MAAM,aAAa,EAAE,QAAS,KAAK,GAAG,QAAQ;AAAA,EACvD,CAAC,KAAK,CAAC,MAAM,aAAa,EAAE,QAAS,GAAG,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASnD,CAAC,MAAM,CAAC,MAAM;AACZ,UAAM,MAAM,EAAE;AACd,UAAM,YAAY,MAAM;AAGxB,UAAM,gBAAgB,MAAM;AAC5B,QAAI,iBAAiB,MAAM,iBAAiB,IAAI;AAC9C,aAAO,MAAM;AAAA,IACf;AACA,QAAI,cAAc,EAAG,QAAO,MAAM;AAClC,QAAI,cAAc,EAAG,QAAO,MAAM;AAClC,QAAI,cAAc,EAAG,QAAO,MAAM;AAClC,WAAO,MAAM;AAAA,EACf,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOR,CAAC,KAAK,CAAC,MAAM,OAAO,KAAK,KAAK,EAAE,QAAS,CAAC,CAAC,GAAG,OAAO;AAAA,EACrD,CAAC,OAAO,CAAC,MAAM,MAAM,KAAK,KAAK,EAAE,QAAS,CAAC,GAAG,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASrD,CAAC,MAAM,CAAC,MAAM;AACZ,kBAAc,GAAG,MAAM,QAAQ,SAAS,KAAK;AAC7C,UAAM,EAAE,KAAK,IAAI,mBAAmB,EAAE,MAAO,EAAE,OAAQ,EAAE,KAAM,EAAE,SAAU;AAC3E,WAAO,IAAI,MAAM,CAAC;AAAA,EACpB,GAAG,WAAW;AAAA,EACd,CAAC,QAAQ,CAAC,MAAM;AACd,kBAAc,GAAG,QAAQ,QAAQ,SAAS,KAAK;AAC/C,UAAM,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAO,EAAE,OAAQ,EAAE,KAAM,EAAE,SAAU;AAC9E,WAAO,IAAI,SAAS,CAAC;AAAA,EACvB,GAAG,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUd,CAAC,KAAK,CAAC,MAAM;AACX,kBAAc,GAAG,KAAK,QAAQ,OAAO;AACrC,WAAO,OAAO,UAAU,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI,CAAC;AAAA,EACpD,GAAG,KAAK;AAAA,EACR,CAAC,MAAM,CAAC,MAAM;AACZ,kBAAc,GAAG,MAAM,QAAQ,OAAO;AACtC,WAAO,IAAI,UAAU,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI,GAAG,CAAC;AAAA,EACpD,GAAG,KAAK;AAAA,EACR,CAAC,OAAO,CAAC,MAAM;AACb,kBAAc,GAAG,OAAO,QAAQ,OAAO;AACvC,WAAO,IAAI,UAAU,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI,GAAG,CAAC;AAAA,EACpD,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAMR,CAAC,QAAQ,CAAC,GAAG,WAAW;AACtB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,OAAO,OAAO,GAAG,SAAS,QAAQ,WAAW,EAAE,QAAS,CAAC;AAAA,EAC/F,GAAG,OAAO;AAAA,EACV,CAAC,OAAO,CAAC,GAAG,WAAW;AACrB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,OAAO,QAAQ,GAAG,SAAS,QAAQ,YAAY,EAAE,QAAS,CAAC;AAAA,EACjG,GAAG,OAAO;AAAA;AAAA;AAAA,EAIV,CAAC,QAAQ,CAAC,GAAG,WAAW;AACtB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,SAAS,OAAO,GAAG,WAAW,QAAQ,aAAa,EAAE,YAAa,CAAC;AAAA,EACzG,GAAG,WAAW;AAAA,EACd,CAAC,OAAO,CAAC,GAAG,WAAW;AACrB,UAAM,SAAS,eAAe,MAAM;AACpC,WAAO,gBAAgB,GAAG,QAAQ,EAAE,SAAS,QAAQ,GAAG,WAAW,QAAQ,cAAc,EAAE,YAAa,CAAC;AAAA,EAC3G,GAAG,WAAW;AAAA;AAAA;AAAA,EAId,CAAC,QAAQ,CAAC,GAAG,WAAW;AACtB,WAAO,SAAS,GAAG,QAAQ,EAAE,KAAK,OAAO,GAAG,KAAK;AAAA,EACnD,GAAG,MAAM;AAAA,EACT,CAAC,KAAK,CAAC,GAAG,WAAW;AACnB,WAAO,SAAS,GAAG,QAAQ,EAAE,KAAK,QAAQ,GAAG,KAAK;AAAA,EACpD,GAAG,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,CAAC,QAAQ,CAAC,GAAG,WAAW;AACtB,WAAO,SAAS,GAAG,QAAQ,EAAE,cAAc,cAA4D,GAAG,cAA8C;AAAA,EAC1J,GAAG,YAAY;AAAA,EACf,CAAC,KAAK,CAAC,GAAG,WAAW;AACnB,WAAO,SAAS,GAAG,QAAQ,EAAE,cAAc,QAAsD,GAAG,cAA8C;AAAA,EACpJ,GAAG,YAAY;AAEjB;AAWA,IAAM,mBAAmB,oBAAI,IAAwD;AAUrF,IAAM,mBAAsC,CAAC;AAEtC,SAAS,mBAAmB,UAA4B;AAC7D,mBAAiB,KAAK,QAAQ;AAChC;AAOO,SAAS,qBAAwE;AACtF,QAAM,SAAS,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAU,CAAC;AAC5D,aAAW,CAAC,MAAM,KAAK,KAAK,iBAAkB,QAAO,IAAI,MAAM,KAAK;AACpE,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AAEO,SAAS,cAAc,OAAyD;AACrF,mBAAiB,IAAI,MAAM,CAAC,GAAG,KAAK;AACpC,aAAW,YAAY,iBAAkB,UAAS;AACpD;;;AC7sBA,IAAI,uBAAuB,OAAO,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAExF,mBAAmB,MAAM;AACvB,yBAAuB,mBAAmB,EACvC,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG,EAClB,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACvC,CAAC;AASM,SAAS,kBAAkBC,SAAgC;AAChE,QAAM,SAAyB,CAAC;AAChC,MAAI,IAAI;AAER,SAAO,IAAIA,QAAO,QAAQ;AACxB,UAAM,KAAKA,QAAO,CAAC;AAEnB,QAAI,OAAO,KAAK;AAEd,UAAIA,QAAO,IAAI,CAAC,MAAM,KAAK;AACzB,sBAAc,QAAQ,KAAK,GAAG,IAAI,CAAC;AACnC,aAAK;AACL;AAAA,MACF;AAEA,UAAI,IAAI,IAAI;AACZ,UAAI,UAAU;AACd,UAAI,SAAS;AACb,aAAO,IAAIA,QAAO,QAAQ;AACxB,YAAIA,QAAO,CAAC,MAAM,KAAK;AACrB,cAAIA,QAAO,IAAI,CAAC,MAAM,KAAK;AACzB,uBAAW;AACX,iBAAK;AACL;AAAA,UACF;AACA,mBAAS;AACT,eAAK;AACL;AAAA,QACF;AACA,mBAAWA,QAAO,CAAC;AACnB,aAAK;AAAA,MACP;AAEA,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,kBAAkB;AAAA,UAC1B,QAAAA;AAAA,UACA,SAAS,sDAAsDA,OAAM;AAAA,QACvE,CAAC;AAAA,MACH;AAEA,oBAAc,QAAQ,SAAS,GAAG,CAAC;AACnC,UAAI;AACJ;AAAA,IACF;AAEA,UAAM,QAAQ,qBAAqB,KAAK,CAAC,QAAQA,QAAO,WAAW,KAAK,CAAC,CAAC;AAC1E,QAAI,OAAO;AAOT,YAAM,UAAU,MAAM,MAAM,SAAS,CAAC;AACtC,UAAIA,QAAO,IAAI,MAAM,MAAM,MAAM,SAAS;AACxC,YAAI,MAAM,IAAI,MAAM;AACpB,eAAOA,QAAO,GAAG,MAAM,QAAS,QAAO;AAOvC,cAAM,IAAI,kBAAkB;AAAA,UAC1B,QAAAA;AAAA,UACA,OAAOA,QAAO,MAAM,GAAG,GAAG;AAAA,UAC1B,SACE,kBAAkBA,QAAO,MAAM,GAAG,GAAG,CAAC,uBAAuBA,OAAM,mDAClD,KAAK;AAAA,QAC1B,CAAC;AAAA,MACH;AACA,aAAO,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,OAAO,GAAG,KAAK,IAAI,MAAM,OAAO,CAAC;AAC5E,WAAK,MAAM;AACX;AAAA,IACF;AAGA,kBAAc,QAAQ,IAAI,GAAG,IAAI,CAAC;AAClC,SAAK;AAAA,EACP;AAEA,SAAO;AACT;AAQO,SAAS,SAASA,SAAyB;AAChD,SAAO,kBAAkBA,OAAM,EAAE,IAAI,CAAC,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE;AAC7E;AAIA,SAAS,cAAc,QAAwB,OAAe,OAAe,KAAmB;AAC9F,QAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,MAAI,QAAQ,KAAK,SAAS,aAAa,KAAK,QAAQ,OAAO;AACzD,SAAK,SAAS;AACd,SAAK,MAAM;AAAA,EACb,OAAO;AACL,WAAO,KAAK,EAAE,MAAM,WAAW,OAAO,OAAO,IAAI,CAAC;AAAA,EACpD;AACF;;;ACjJO,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;;;ACgCzB,IAAM,8BAAmD,oBAAI,IAAI;AAAA,EACtE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACxD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAY;AACtC,CAAC;AAED,IAAM,gBAAgB,oBAAI,IAAoC;AAQ9D,IAAM,qBAAqB,oBAAI,IAAoB;AACnD,IAAM,2BAA2B;AAYjC,SAAS,2BAA2B,QAAwB;AAC1D,QAAM,MAAM,kBAAkB,MAAM;AACpC,QAAM,SAAS,mBAAmB,IAAI,GAAG;AACzC,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI;AACJ,MAAI;AACF,eAAW,IAAI,KAAK,aAAa,mBAAmB,MAAM,CAAC,EAAE,gBAAgB,EAAE;AAAA,EACjF,SAAS,KAAK;AACZ,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAS,IAAc,QAAQ,CAAC;AAAA,EACjF;AACA,QAAM,SAAS,4BAA4B,IAAI,QAAQ,IAAI,WAAW;AACtE,MAAI,mBAAmB,QAAQ,0BAA0B;AAEvD,UAAM,YAAY,mBAAmB,KAAK,EAAE,KAAK,EAAE;AACnD,QAAI,cAAc,OAAW,oBAAmB,OAAO,SAAS;AAAA,EAClE;AACA,qBAAmB,IAAI,KAAK,MAAM;AAClC,SAAO;AACT;AAMA,SAAS,uBAAuB,WAA+B,QAAoC;AACjG,MAAI,cAAc,OAAW,QAAO;AACpC,MAAI,cAAc,OAAQ,QAAO,2BAA2B,UAAU,cAAc;AACpF,SAAO;AACT;AAMA,SAAS,YAAY,QAAwC;AAC3D,MAAI,MAAM,cAAc,IAAI,MAAM;AAClC,MAAI,IAAK,QAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,MAAI,WAAW,QAAQ;AACrB,UAAM,CAAC;AACP,aAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC;AAAA,EACxD,OAAO;AAAA,IACL;AACA,UAAM,MAAM,IAAI,KAAK,aAAa,gBAAgB,QAAQ,EAAE,aAAa,MAAM,CAAC;AAChF,UAAM,CAAC;AACP,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAI,OAAO,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC;AAAA,IAC/B;AAAA,EACF;AACA,gBAAc,IAAI,QAAQ,GAAG;AAC7B,SAAO;AACT;AAIO,SAAS,cAAc,GAAW,QAAwB;AAC/D,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,CAAC,4BAA4B,IAAI,MAAM,GAAG;AAC5C,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAQ,qBAAqB,MAAM,kCAAkC,CAAC,GAAG,2BAA2B,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC;AAAA,EACtK;AACA,QAAM,MAAM,YAAY,MAAM;AAC9B,MAAI,SAAS;AACb,aAAW,MAAM,GAAG;AAClB,QAAI,MAAM,OAAO,MAAM,KAAK;AAM1B,gBAAU,IAAI,EAAE,KAAK;AAAA,IACvB,OAAO;AACL,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,qBAAqB,GAAW,QAAwB;AAOtE,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,CAAC,4BAA4B,IAAI,MAAM,GAAG;AAC5C,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAQ,qBAAqB,MAAM,sBAAsB,CAAC;AAAA,EAC3G;AACA,QAAM,MAAM,YAAY,MAAM;AAE9B,QAAM,UAAkC,CAAC;AACzC,aAAW,KAAK,OAAO,KAAK,GAAG,EAAG,SAAQ,IAAI,CAAC,CAAE,IAAI;AACrD,MAAI,SAAS;AACb,aAAW,MAAM,GAAG;AAClB,cAAU,QAAQ,EAAE,KAAK;AAAA,EAC3B;AACA,SAAO;AACT;AA2BO,SAAS,eAAe,GAAW,SAAyC;AACjF,QAAM,SAAS,uBAAuB,QAAQ,iBAAiB,QAAQ,MAAM;AAC7E,MAAI,WAAW,OAAQ,QAAO;AAC9B,SAAO,cAAc,GAAG,MAAM;AAChC;AAMO,SAAS,oBAAoB,GAAW,SAAqE;AAQlH,QAAM,SAAS,uBAAuB,QAAQ,sBAAsB,QAAQ,MAAM;AAClF,MAAI,WAAW,OAAQ,QAAO;AAC9B,SAAO,qBAAqB,GAAG,MAAM;AACvC;;;AC3MA,IAAI,mBAAmB,IAAI,IAAI,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC;AAMrF,IAAM,gBAAgB,oBAAI,IAAqB;AAC/C,IAAM,0BAA0B;AAWhC,mBAAmB,MAAM;AACvB,qBAAmB,IAAI,IAAI,mBAAmB,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC;AAC/F,gBAAc,MAAM;AACtB,CAAC;AAED,SAAS,UAAU,WAA4B;AAC7C,MAAI,SAAS,cAAc,IAAI,SAAS;AACxC,MAAI,OAAQ,QAAO;AACnB,MAAI,cAAc,QAAQ,yBAAyB;AACjD,UAAM,YAAY,cAAc,KAAK,EAAE,KAAK,EAAE;AAC9C,QAAI,cAAc,OAAW,eAAc,OAAO,SAAS;AAAA,EAC7D;AACA,WAAS,SAAS,SAAS;AAQ3B,aAAW,SAAS,OAAQ,QAAO,OAAO,KAAK;AAC/C,SAAO,OAAO,MAAM;AACpB,gBAAc,IAAI,WAAW,MAAM;AACnC,SAAO;AACT;AAaO,SAAS,OAAO,UAAwB,WAAmB,UAAkC,CAAC,GAAW;AAC9G,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AAOA,MAAI,aAAa,QAAQ,aAAa,QAAW;AAC/C,UAAM,IAAI,kBAAkB;AAAA,MAC1B,OAAO,OAAO,QAAQ;AAAA,MACtB,QAAQ,yHAAyH,OAAO,QAAQ,CAAC;AAAA,IACnJ,CAAC;AAAA,EACH;AACA,QAAM,OAAO,WAAW,CAAC;AAEzB,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,SAAS,UAAU,SAAS;AAClC,MAAI,SAAS;AAEb,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,WAAW;AAC5B,gBAAU,MAAM;AAChB;AAAA,IACF;AAEA,UAAM,UAAU,iBAAiB,IAAI,MAAM,KAAK;AAAA,IAChD;AAAA;AAAA;AAAA;AAAA;AAKA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,kBAAkB,EAAE,OAAO,MAAM,OAAO,QAAQ,WAAW,SAAS,gCAAgC,MAAM,KAAK,IAAI,CAAC;AAAA,IAChI;AAAA,IACA;AAEA,QAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,YAAM,IAAI,kBAAkB;AAAA,QAC1B,QAAQ;AAAA,QACR,OAAO,MAAM;AAAA,QACb,SACE,wBAAwB,MAAM,KAAK,eAAe,QAAQ,KAAK;AAAA,MAGnE,CAAC;AAAA,IACH;AAEA,cAAU,QAAQ,GAAG,UAAU,MAAM;AAAA,EACvC;AAKA,SAAO,eAAe,QAAQ,IAAI;AACpC;AAgBO,SAAS,cAAc,UAAwB,WAAmB,UAAkC,CAAC,GAAoB;AAC9H,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,SAAS,UAAU,SAAS;AAClC,QAAM,SAA0B,CAAC;AACjC,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,WAAW;AAK5B,YAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,UAAI,QAAQ,KAAK,SAAS,WAAW;AACnC,aAAK,SAAS,MAAM;AAAA,MACtB,OAAO;AAAA,QACL;AACA,eAAO,KAAK,EAAE,MAAM,WAAW,OAAO,MAAM,MAAM,CAAC;AAAA,MACrD;AACA;AAAA,IACF;AACA,UAAM,UAAU,iBAAiB,IAAI,MAAM,KAAK;AAAA,IAChD;AACA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,kBAAkB,EAAE,OAAO,MAAM,OAAO,QAAQ,WAAW,SAAS,gCAAgC,MAAM,KAAK,IAAI,CAAC;AAAA,IAChI;AAAA,IACA;AACA,QAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,YAAM,IAAI,kBAAkB;AAAA,QAC1B,QAAQ;AAAA,QACR,OAAO,MAAM;AAAA,QACb,SACE,wBAAwB,MAAM,KAAK,eAAe,QAAQ,KAAK;AAAA,MAGnE,CAAC;AAAA,IACH;AAKA,WAAO,KAAK,EAAE,MAAM,SAAS,OAAO,eAAe,QAAQ,GAAG,UAAU,MAAM,GAAG,OAAO,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,EACjH;AACA,SAAO;AACT;AAiBO,SAAS,cAAc,WAAmC;AAC/D,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AAKA,QAAM,SAAS,UAAU,SAAS;AAClC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,UAAwB,UAAkC,CAAC,GAAG;AACnE,YAAM,SAAS,QAAQ,UAAU;AACjC,UAAI,SAAS;AACb,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,SAAS,WAAW;AAC5B,oBAAU,MAAM;AAChB;AAAA,QACF;AACA,cAAM,UAAU,iBAAiB,IAAI,MAAM,KAAK;AAEhD,YAAI,CAAC,QAAS,OAAM,IAAI,kBAAkB,EAAE,OAAO,MAAM,OAAO,QAAQ,WAAW,SAAS,gCAAgC,MAAM,KAAK,IAAI,CAAC;AAC5I,YAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,gBAAM,IAAI,kBAAkB;AAAA,YAC1B,QAAQ;AAAA,YACR,OAAO,MAAM;AAAA,YACb,SACE,wBAAwB,MAAM,KAAK,eAAe,QAAQ,KAAK;AAAA,UAGnE,CAAC;AAAA,QACH;AACA,kBAAU,QAAQ,GAAG,UAAU,MAAM;AAAA,MACvC;AACA,aAAO,eAAe,QAAQ,OAAO;AAAA,IACvC;AAAA,IACA,cAAc,UAAwB,UAAkC,CAAC,GAAG;AAC1E,YAAM,SAAS,QAAQ,UAAU;AACjC,YAAM,MAAuB,CAAC;AAC9B,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,SAAS,WAAW;AAC5B,gBAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAE/B,cAAI,QAAQ,KAAK,SAAS,UAAW,MAAK,SAAS,MAAM;AAAA,cACpD,KAAI,KAAK,EAAE,MAAM,WAAW,OAAO,MAAM,MAAM,CAAC;AACrD;AAAA,QACF;AACA,cAAM,UAAU,iBAAiB,IAAI,MAAM,KAAK;AAEhD,YAAI,CAAC,QAAS,OAAM,IAAI,kBAAkB,EAAE,OAAO,MAAM,OAAO,QAAQ,WAAW,SAAS,gCAAgC,MAAM,KAAK,IAAI,CAAC;AAC5I,YAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,gBAAM,IAAI,kBAAkB;AAAA,YAC1B,QAAQ;AAAA,YACR,OAAO,MAAM;AAAA,YACb,SACE,wBAAwB,MAAM,KAAK,eAAe,QAAQ,KAAK;AAAA,UAGnE,CAAC;AAAA,QACH;AACA,YAAI,KAAK,EAAE,MAAM,SAAS,OAAO,eAAe,QAAQ,GAAG,UAAU,MAAM,GAAG,OAAO,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,MAC9G;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAYO,SAAS,YAAY,OAA2G;AACrI,SAAO,iBAAiB,IAAI,KAAK;AACnC;;;AC1SA,SAAS,aAAa,SAAyB;AAC7C,SAAO,QAAQ,QAAQ,uBAAuB,MAAM;AACtD;AAEA,SAAS,YAAY,QAAkB,kBAAkB,OAAe;AACtE,QAAM,UAAU,OAAO,IAAI,YAAY;AACvC,MAAI,CAAC,gBAAiB,QAAO,MAAM,QAAQ,KAAK,GAAG,CAAC;AAKpD,SAAO,MAAM,QAAQ,IAAI,QAAQ,EAAE,KAAK,GAAG,CAAC;AAC9C;AAOA,SAAS,SAAS,OAAuB;AACvC,SAAO,MAAM,QAAQ,aAAa,CAAC,OAAO,IAAI,GAAG,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,GAAG;AACtF;AAYA,IAAM,kBAAkB;AAqBxB,IAAM,gBAAwC;AAAA,EAC5C,GAAK;AAAA,EACL,IAAK;AAAA,EACL,KAAK;AAAA,EACL,GAAK;AAAA,EACL,IAAK;AAAA,EACL,KAAK;AACP;AAEA,SAAS,sBAA8B;AACrC,SAAO;AACT;AAEA,IAAI;AAKJ,SAAS,kBAA+B;AACtC,MAAI,CAAC,cAAc;AACjB,mBAAe,IAAI,IAAI,KAAK,kBAAkB,UAAU,CAAC;AACzD,iBAAa,IAAI,KAAK;AAAA,EACxB;AACA,SAAO;AACT;AAEA,IAAM,kBAAkB;AAiBjB,SAAS,gBAAgB,KAAsB;AACpD,MAAI,gBAAgB,KAAK,GAAG,KAAK,gBAAgB,EAAE,IAAI,GAAG,EAAG,QAAO;AACpE,MAAI;AACF,gBAAY,EAAE,cAAc,KAAK;AAAA,MAC/B,MAAM;AAAA,MAAM,OAAO;AAAA,MAAG,KAAK;AAAA,MAAG,MAAM;AAAA,MAAG,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAC1D,UAAU;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAsBA,IAAM,oBAA4C;AAAA,EAChD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,GAAG;AAAA;AAAA;AAAA,EAGH,GAAG;AACL;AAMA,IAAM,eAAe;AAOd,IAAM,qBAAqB,oBAAI,IAAI,CAAC,MAAM,MAAM,QAAQ,KAAK,MAAM,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,KAAK,QAAQ,GAAG,CAAC;AAgBxI,IAAM,aAAa;AACnB,IAAM,gBAAgB;AAYtB,IAAM,aAAa;AAUZ,IAAM,uBAAuB,oBAAI,IAAI;AAAA,EAC1C;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAChF;AAAA,EAAa;AAAA,EAAY;AAAA,EAAW;AAAA,EAAU;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAM;AAC9E,CAAC;AAaM,IAAM,yBAAyB,oBAAI,IAAI,CAAC,GAAG,CAAC;AAE5C,SAAS,cAAc,OAAe,QAAgB,WAA4B;AACvF,MAAI,UAAU,QAAQ;AACpB,WAAO,cAAc,UAAa,qBAAqB,IAAI,SAAS,IAAI,aAAa;AAAA,EACvF;AACA,MAAI,UAAU,KAAK;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,kBAAkB,KAAK;AACvC,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,OAAO;AACnB,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,IAAI,KAAK,GAAG;AACjC,UAAM,IAAI,kBAAkB;AAAA,MAC1B;AAAA,MACA,SACE,wBAAwB,KAAK;AAAA,IAEjC,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,eAAe,MAAM;AACnC,UAAQ,OAAO;AAAA,IACb,KAAK;AAAQ,aAAO,YAAY,MAAM,SAAS;AAAA,IAC/C,KAAK;AAAO,aAAO,YAAY,MAAM,UAAU;AAAA,IAC/C,KAAK;AAAQ,aAAO,YAAY,MAAM,WAAW;AAAA,IACjD,KAAK;AAAO,aAAO,YAAY,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjD,KAAK;AAAK,aAAO,YAAY,MAAM,WAAW,IAAI;AAAA,IAClD,KAAK;AAAO,aAAO,oBAAoB;AAAA,IACvC,KAAK;AAAA,IAAK,KAAK;AAAA,IAAM,KAAK;AAAA,IAC1B,KAAK;AAAA,IAAK,KAAK;AAAA,IAAM,KAAK;AACxB,aAAO,cAAc,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAY5B;AACE,YAAM,IAAI,kBAAkB,EAAE,OAAO,SAAS,gCAAgC,KAAK,IAAI,CAAC;AAAA,EAE5F;AACF;AAYO,IAAM,0BAA0B,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAQtE,IAAM,0BAA8F;AAAA,EACzG,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EAClE,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EAClE,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EAClE,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EAClE,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AAAA,EAClE,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,GAAG,EAAE,QAAQ,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC;AACpE;AAqBO,SAAS,qBAAqB,QAAgB,QAA8B;AACjF,QAAM,OAAO,oBAAI,IAAwB;AAEzC,WAAS,MAAM,YAAoB,QAA4B;AAC7D,UAAM,MAAM,GAAG,UAAU,IAAI,MAAM;AACnC,UAAM,SAAS,KAAK,IAAI,GAAG;AAC3B,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAEA,QAAI,eAAe,OAAO,QAAQ;AAChC,YAAM,SAAS,WAAW,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,WAAK,IAAI,KAAK,MAAM;AACpB,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,OAAO,UAAU;AAC/B,UAAM,SAAS,wBAAwB,KAAM;AAAA,IAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wCAAmC,KAAK,oCAAoC;AAAA,IAC9F;AAAA,IACA;AAEA,UAAM,UAAsB,CAAC;AAC7B,eAAW,EAAE,QAAQ,OAAO,KAAAC,MAAK,KAAAC,KAAI,KAAK,QAAQ;AAChD,UAAI,SAAS,QAAQ,OAAO,OAAQ;AACpC,YAAM,QAAQ,OAAO,MAAM,QAAQ,SAAS,KAAK;AACjD,UAAI,UAAU,KAAK,MAAM,CAAC,MAAM,IAAK;AACrC,YAAM,QAAQ,OAAO,KAAK;AAC1B,UAAI,QAAQD,QAAO,QAAQC,KAAK;AAEhC,iBAAW,aAAa,MAAM,aAAa,GAAG,SAAS,KAAK,GAAG;AAC7D,gBAAQ,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC;AAClC,YAAI,QAAQ,WAAW,EAAG;AAAA,MAC5B;AACA,UAAI,QAAQ,WAAW,EAAG;AAAA,IAC5B;AAEA,SAAK,IAAI,KAAK,OAAO;AACrB,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,GAAG,CAAC;AACnB;;;AC9XA,SAASC,cAAa,SAAyB;AAC7C,SAAO,QAAQ,QAAQ,uBAAuB,MAAM;AACtD;AA6CA,IAAM,qBAAqB;AAE3B,SAAS,iBAAiB,SAAyB;AACjD,SAAO,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC;AAClD;AAMA,SAAS,sBAAsB,OAAmC;AAChE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,MAAM,SAAS,UAAW,QAAO,SAAS,KAAK,MAAM,KAAK;AAC9D,SAAO,qBAAqB,IAAI,MAAM,KAAK;AAC7C;AAsBO,SAAS,sBAAsB,QAAiB,QAAkC;AACvF,QAAM,SAAiD,CAAC;AACxD,QAAM,gBAAsF,CAAC;AAC7F,MAAI,SAAS;AACb,MAAI,IAAI;AACR,MAAI,gBAAgB;AAMpB,MAAI,aAAoD,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAEhF,QAAM,WAAW,CAAC,cAAiC;AACjD,QAAI,WAAW,OAAO,WAAW,GAAG;AAIlC,YAAM,OAAO,WAAW,MAAM,CAAC;AAC/B,YAAM,QAAQ,WAAW,OAAO,CAAC;AACjC,gBAAU,MAAM,IAAI,IAAI,cAAc,OAAO,MAAM,CAAC;AACpD,UAAI,sBAAsB,SAAS,EAAG,kBAAiB;AAAA,IACzD,WAAW,WAAW,OAAO,UAAU,GAAG;AAQxC,YAAM,UAAU,IAAI,GAAG;AACvB,YAAM,aAAa,WAAW,OAAO;AACrC,gBAAU,MAAM,OAAO,QAAQ,UAAU,IAAI,aAAa,CAAC;AAM3D,oBAAc,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,YAAY,WAAW;AAAA,QACvB,QAAQ,WAAW;AAAA,MACrB,CAAC;AAGD,UAAI,sBAAsB,SAAS,GAAG;AACpC,yBAAiB,iBAAiB,aAAa,CAAC;AAAA,MAClD;AAAA,IACF;AACA,iBAAa,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,EACvC;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC3C,QAAI,MAAM,SAAS,WAAW;AAC5B,eAAS,KAAK;AACd,gBAAUA,cAAa,MAAM,KAAK;AAClC;AAAA,IACF;AAEA,QAAI,wBAAwB,IAAI,MAAM,KAAK,GAAG;AAI5C,YAAMC,QAAO,IAAI,GAAG;AACpB,aAAO,KAAK,EAAE,MAAAA,OAAM,OAAO,MAAM,MAAM,CAAC;AACxC,iBAAW,MAAM,KAAKA,KAAI;AAC1B,iBAAW,OAAO,KAAK,MAAM,KAAK;AAClC;AAAA,IACF;AAEA,aAAS,KAAK;AACd,UAAM,OAAO,IAAI,GAAG;AACpB,WAAO,KAAK,EAAE,MAAM,OAAO,MAAM,MAAM,CAAC;AACxC,UAAM,YAAY,OAAO,MAAM,CAAC;AAChC,UAAM,YAAY,WAAW,SAAS,UAAU,UAAU,QAAQ;AASlE,QAAI,uBAAuB,IAAI,MAAM,KAAK,KAAK,sBAAsB,SAAS,GAAG;AAC/E,YAAM,IAAI,kBAAkB;AAAA,QAC1B,QACE,UAAU,MAAM,KAAK,0KAEX,MAAM,KAAK;AAAA,MACzB,CAAC;AAAA,IACH;AAOA,QAAI,MAAM,UAAU,UAAU,cAAc,UAAa,sBAAsB,SAAS,GAAG;AACzF,gBAAU,MAAM,IAAI,IAAI,cAAc,MAAM,OAAO,QAAQ,GAAG,CAAC;AAAA,IACjE,OAAO;AACL,gBAAU,MAAM,IAAI,IAAI,cAAc,MAAM,OAAO,QAAQ,SAAS,CAAC;AAAA,IACvE;AAAA,EACF;AACA,WAAS,MAAS;AAElB,MAAI,gBAAgB,oBAAoB;AACtC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QACE,gHACoB,aAAa,MAAM,kBAAkB;AAAA,IAG7D,CAAC;AAAA,EACH;AAQA,SAAO,EAAE,OAAO,IAAI,OAAO,OAAO,MAAM,MAAM,IAAI,GAAG,QAAQ,cAAc;AAC7E;;;ACpMA,IAAM,eAAe,oBAAI,IAA8B;AACvD,IAAMC,kBAAiB;AAUvB,wBAAwB,MAAM;AAAE,eAAa,MAAM;AAAG,CAAC;AAEvD,SAAS,WAAW,WAAmB,QAAkC;AACvE,QAAM,MAAM,KAAK,UAAU,CAAC,kBAAkB,MAAM,GAAG,SAAS,CAAC;AACjE,MAAI,UAAU,aAAa,IAAI,GAAG;AAClC,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AACA,MAAI,aAAa,QAAQA,iBAAgB;AACvC,UAAM,YAAY,aAAa,KAAK,EAAE,KAAK,EAAE;AAC7C,QAAI,cAAc,OAAW,cAAa,OAAO,SAAS;AAAA,EAC5D;AACA,YAAU,sBAAsB,SAAS,SAAS,GAAG,MAAM;AAC3D,eAAa,IAAI,KAAK,OAAO;AAC7B,SAAO;AACT;AAWA,IAAM,gBAAgB,oBAAI,IAAgC;AAC1D,IAAM,0BAA0B;AAEhC,SAAS,gBAAgB,QAAoC;AAK3D,uBAAqB,MAAM;AAI3B,QAAM,kBAAkB,kBAAkB,MAAM;AAChD,MAAI,cAAc,IAAI,eAAe,GAAG;AACtC,WAAO,cAAc,IAAI,eAAe;AAAA,EAC1C;AACA,MAAI,cAAc,QAAQ,yBAAyB;AACjD,UAAM,YAAY,cAAc,KAAK,EAAE,KAAK,EAAE;AAC9C,QAAI,cAAc,OAAW,eAAc,OAAO,SAAS;AAAA,EAC7D;AACA,MAAI;AACJ,QAAM,QAAQ,gBAAgB,MAAM,GAAG;AACvC,QAAM,iBAAiB,MAAM,QAAQ,GAAG;AACxC,QAAM,mBAAmB,mBAAmB,KAAK,KAAK,MAAM,QAAQ,MAAM,iBAAiB,CAAC;AAC5F,MAAI,qBAAqB,MAAM,mBAAmB,IAAI,MAAM,QAAQ;AAClE,UAAM,WAAW,IAAI,KAAK,eAAe,eAAe,EAAE,gBAAgB,EAAE;AAC5E,eAAW,aAAa,YAAY,SAAY;AAAA,EAClD;AACA,gBAAc,IAAI,iBAAiB,QAAQ;AAC3C,SAAO;AACT;AAuCA,SAAS,kBAAkB,KAAa,OAAuB;AAC7D,MAAI,QAAQ,KAAK;AAAA,IACf;AAAA;AAAA;AAAA;AAAA;AAKA,QAAI,UAAU,OAAO,UAAU,QAAQ,UAAU,OAAO;AACtD,YAAM,IAAI;AAAA,QACR,+BAA+B,KAAK;AAAA,MAEtC;AAAA,IACF;AAAA,IACA;AACA,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,IAAI,CAAC;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAKA,MAAI,SAAS,OAAO,SAAS,KAAK;AAChC,UAAM,IAAI,MAAM,yBAAyB,GAAG,gBAAgB,KAAK,wCAAwC;AAAA,EAC3G;AAAA,EACA;AACA,QAAM,OAAO,IAAI,MAAM,CAAC;AACxB,MAAI;AACJ,MAAI;AACJ,MAAI,KAAK,WAAW,GAAG;AAAA,IACrB;AAAA;AAAA;AAAA;AAAA;AAMA,QAAI,UAAU,OAAO,UAAU,KAAK;AAClC,YAAM,IAAI;AAAA,QACR,+BAA+B,KAAK,kBAAkB,GAAG,sCAAiC,GAAG;AAAA,MAC/F;AAAA,IACF;AAAA,IACA;AACA,eAAW;AACX,iBAAa;AAAA,EACf,WAAW,KAAK,WAAW,GAAG;AAAA,IAC5B;AAAA;AAAA;AAIA,QAAI,UAAU,SAAS,UAAU,OAAO;AACtC,YAAM,IAAI;AAAA,QACR,+BAA+B,KAAK,kBAAkB,GAAG,iEAA4D,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;AAAA,MAC/J;AAAA,IACF;AAAA,IACA;AACA,eAAW,KAAK,MAAM,GAAG,CAAC;AAC1B,iBAAa,KAAK,MAAM,GAAG,CAAC;AAAA,EAC9B,WAAW,KAAK,WAAW,KAAK,KAAK,CAAC,MAAM,KAAK;AAAA,IAC/C;AAAA;AAAA;AAIA,QAAI,UAAU,SAAS,UAAU,OAAO;AACtC,YAAM,IAAI;AAAA,QACR,+BAA+B,KAAK,kBAAkB,GAAG,yCAAoC,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AAAA,MACtI;AAAA,IACF;AAAA,IACA;AACA,eAAW,KAAK,MAAM,GAAG,CAAC;AAC1B,iBAAa,KAAK,MAAM,GAAG,CAAC;AAAA,IAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO;AACL,UAAM,IAAI,MAAM,yBAAyB,GAAG,oCAAoC,KAAK,YAAY;AAAA,EACnG;AAAA,EACA;AAEA,QAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAM,UAAU,OAAO,UAAU;AAEjC,MAAI,QAAQ,IAAI;AACd,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS,8BAA8B,KAAK,QAAQ,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AACA,MAAI,UAAU,IAAI;AAChB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS,gCAAgC,OAAO,QAAQ,GAAG;AAAA,IAC7D,CAAC;AAAA,EACH;AAIA,MAAI,SAAS,OAAO,UAAU,MAAM,YAAY,GAAG;AACjD,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS,yBAAyB,GAAG;AAAA,IACvC,CAAC;AAAA,EACH;AACA,MAAI,SAAS,OAAO,UAAU,MAAM,YAAY,GAAG;AACjD,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA,MACR,SAAS,yBAAyB,GAAG;AAAA,IACvC,CAAC;AAAA,EACH;AACA,SAAO,GAAG,IAAI,GAAG,QAAQ,IAAI,UAAU;AACzC;AAEA,SAAS,YAAe,QAAgB,KAAmB,OAAgB;AACzE,EAAC,OAAyC,GAAG,IAAI;AACnD;AAEA,SAAS,WAAW,QAAgB,OAAe,KAAa,QAAgB,WAAyB;AACvG,QAAM,QAAQ,eAAe,MAAM;AACnC,UAAQ,OAAO;AAAA,IACb,KAAK;AAAA,IAAQ,KAAK;AAChB,kBAAY,QAAQ,QAAQ,OAAO,GAAG,CAAC;AACvC;AAAA,IACF,KAAK;AACH,kBAAY,QAAQ,gBAAgB,OAAO,GAAG,CAAC;AAC/C;AAAA,IACF,KAAK;AAAA,IAAM,KAAK;AACd,kBAAY,QAAQ,SAAS,OAAO,GAAG,CAAC;AACxC;AAAA,IACF,KAAK;AACH,kBAAY,QAAQ,SAAS,MAAM,UAAU,QAAQ,GAAG,IAAI,CAAC;AAC7D;AAAA,IACF,KAAK;AACH,kBAAY,QAAQ,SAAS,MAAM,WAAW,QAAQ,GAAG,IAAI,CAAC;AAC9D;AAAA,IACF,KAAK;AAAA,IAAM,KAAK;AACd,kBAAY,QAAQ,OAAO,OAAO,GAAG,CAAC;AACtC;AAAA,IACF,KAAK;AACH,kBAAY,QAAQ,cAAc,GAAG;AACrC,kBAAY,QAAQ,mBAAmB,MAAM,YAAY,QAAQ,GAAG,IAAI,CAAC;AACzE;AAAA,IACF,KAAK;AACH,kBAAY,QAAQ,cAAc,GAAG;AACrC,kBAAY,QAAQ,mBAAmB,MAAM,aAAa,QAAQ,GAAG,IAAI,CAAC;AAC1E;AAAA,IACF,KAAK;AAAA,IAAM,KAAK;AACd,kBAAY,QAAQ,QAAQ,OAAO,GAAG,CAAC;AACvC;AAAA,IACF,KAAK;AAAA,IAAM,KAAK;AACd,kBAAY,QAAQ,UAAU,OAAO,GAAG,CAAC;AACzC;AAAA,IACF,KAAK;AAAA,IAAM,KAAK;AACd,kBAAY,QAAQ,UAAU,OAAO,GAAG,CAAC;AACzC;AAAA,IACF,KAAK;AAAA,IAAM,KAAK;AACd,kBAAY,QAAQ,UAAU,OAAO,GAAG,CAAC;AACzC;AAAA,IACF,KAAK;AAAA,IAAK,KAAK;AAAA,IAAM,KAAK;AAAA,IAAO,KAAK;AAAA,IAAQ,KAAK;AAAA,IACnD,KAAK;AAAA,IAAU,KAAK;AAAA,IAAW,KAAK;AAAA,IAAY,KAAK,aAAa;AAMhE,YAAM,eAAe,OAAO,IAAI,OAAO,GAAG,GAAG,CAAC;AAC9C,kBAAY,QAAQ,eAAe,KAAK,MAAM,eAAe,GAAS,CAAC;AACvE,kBAAY,QAAQ,eAAe,KAAK,MAAM,eAAe,GAAK,IAAI,GAAK;AAC3E,kBAAY,QAAQ,cAAc,eAAe,GAAK;AACtD;AAAA,IACF;AAAA,IACA,KAAK,KAAK;AAIR,YAAM,cAAc,MAAM,UAAU,UAAU,CAAC,MAAM,EAAE,YAAY,MAAM,IAAI,YAAY,CAAC;AAAA,MAC1F;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,UAAI,cAAc,EAAG,OAAM,IAAI,MAAM,qCAAqC,GAAG,iBAAiB,MAAM,IAAI;AAAA,MACxG;AACA,kBAAY,QAAQ,gBAAgB,GAAG;AACvC,kBAAY,QAAQ,QAAQ,gBAAgB,CAAC;AAC7C;AAAA,IACF;AAAA,IACA,KAAK;AACH,kBAAY,QAAQ,cAAc,GAAG;AACrC;AAAA,IACF,KAAK;AAAA,IAAK,KAAK;AAAA,IAAM,KAAK;AAAA,IAC1B,KAAK;AAAA,IAAK,KAAK;AAAA,IAAM,KAAK;AACxB,kBAAY,QAAQ,gBAAgB,kBAAkB,KAAK,KAAK,CAAC;AACjE;AAAA,IACF,KAAK;AACH,kBAAY,QAAQ,WAAW,OAAO,GAAG,CAAC;AAC1C;AAAA,IACF,KAAK;AAGH,kBAAY,QAAQ,WAAW,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC;AACnD;AAAA,EACJ;AACF;AAKA,SAAS,iBAAiB,QAAoB,QAA4B;AASxE,QAAM,WAAW,OAAO,QAAQ,GAAG;AACnC,MAAI,aAAa,IAAI;AACnB,UAAM,iBAAiB,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,KAAM,EAAE;AAC9D,QAAI,eAAe,SAAS,GAAG;AAC7B,aAAO,eAAe,CAAC;AAAA,IACzB;AAAA,EACF;AAKA,SAAO,OAAO,CAAC;AACjB;AAKA,SAAS,YAAY,QAAoC;AACvD,MAAI,OAAO,SAAS,UAAa,OAAO,iBAAiB,QAAW;AAOlE,UAAM,IAAI,kBAAkB;AAAA,MAC1B,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,MAAI,OAAO,SAAS,OAAW,QAAO,OAAO;AAC7C,MAAI,OAAO,iBAAiB,QAAW;AACrC,WAAO,OAAO,gBAAgB,KAAK,MAAO,OAAO,eAAe,OAAO,OAAO;AAAA,EAChF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,QAAgB,WAAmB,QAAoC;AAC1F,MAAI,OAAO,SAAS,UAAa,OAAO,WAAW,QAAW;AAC5D,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,gCAAgC,SAAS;AAAA,IAE7C,CAAC;AAAA,EACH;AACA,MAAI,OAAO,SAAS,QAAW;AAC7B,QAAI,OAAO,iBAAiB,QAAW;AACrC,YAAM,IAAI,kBAAkB;AAAA,QAC1B,QAAQ;AAAA,QACR,SACE,gCAAgC,SAAS;AAAA,MAE7C,CAAC;AAAA,IACH;AACA,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,OAAO,WAAW,QAAW;AAC/B,QAAI,OAAO,SAAS,QAAW;AAC7B,YAAM,IAAI,kBAAkB;AAAA,QAC1B,QAAQ;AAAA,QACR,SACE,gCAAgC,SAAS;AAAA,MAE7C,CAAC;AAAA,IACH;AACA,WAAQ,OAAO,SAAS,MAAO,OAAO,OAAO,KAAK;AAAA,EACpD;AACA,SAAO;AACT;AAwBO,SAAS,MAAM,WAAmB,OAAe,UAAiC,CAAC,GAAwB;AAChH,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AAEA,MAAI,MAAM,SAAS,kBAAkB;AACnC,UAAM,IAAI,kBAAkB;AAAA,MAC1B;AAAA,MACA,SAAS,iDAAiD,gBAAgB,oBAAoB,MAAM,MAAM;AAAA,IAC5G,CAAC;AAAA,EACH;AAMA,MAAI,QAAQ,sBAAsB;AAChC,YAAQ,oBAAoB,OAAO,OAAO;AAAA,EAC5C;AAEA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,WAAW,gBAAgB,MAAM;AACvC,QAAM,UAAU,WAAW,WAAW,MAAM;AAC5C,QAAM,QAAQ,QAAQ,MAAM,KAAK,KAAK;AACtC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,mBAAmB;AAAA,MAC3B;AAAA,MAAO,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMf,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,OAAO,WAAW,GAAG;AAO/B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIR,QAAQ,kBAAkB,SAAS;AAAA,MACnC,SAAS,gCAAgC,SAAS;AAAA,IACpD,CAAC;AAAA,EACH;AAWA,aAAW,EAAE,MAAM,MAAM,KAAK,QAAQ,QAAQ;AAC5C,QAAI,UAAU,SAAS,CAAC,gBAAgB,MAAM,OAAQ,IAAI,CAAE,GAAG;AAC7D,YAAM,IAAI,qBAAqB;AAAA,QAC7B;AAAA,QAAO,QAAQ;AAAA,QAAW,QAAQ,MAAM,OAAQ,IAAI;AAAA,QACpD,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAcA,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,OAAO,QAAQ,eAAe;AACvC,UAAM,YAAY,MAAM,OAAQ,IAAI,SAAS;AAC7C,UAAM,SAAS,qBAAqB,WAAW,IAAI,MAAM;AACzD,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI,mBAAmB;AAAA,QAC3B;AAAA,QAAO,QAAQ;AAAA,QACf,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,QAAI,OAAO,SAAS,GAAG;AAQrB,UAAI,CAAC,QAAQ,SAAS;AACpB,cAAM,IAAI,oBAAoB;AAAA,UAC5B;AAAA,UAAO,QAAQ;AAAA,UACf,SACE,kBAAkB,SAAS,uBAAuB,SAAS,yBACxD,OAAO,MAAM,mCAAmC,IAAI,OAAO,KAAK,EAAE,CAAC,uEACpB,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC;AAAA,QAI/G,CAAC;AAAA,MACH;AACA,YAAM,SAAS,iBAAiB,QAAQ,IAAI,MAAM;AAClD,UAAI,WAAW,QAAQ,CAAC,MAAM,QAAQ,UAAU,IAAI,MAAM,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC;AAAA,IAChF,OAAO;AACL,UAAI,WAAW,QAAQ,CAAC,MAAM,QAAQ,UAAU,IAAI,MAAM,OAAO,OAAO,CAAC,EAAG,GAAG,CAAC,CAAC,CAAC;AAAA,IACpF;AAAA,EACF;AACA,QAAM,SAAiB,CAAC;AAIxB,aAAW,EAAE,MAAM,MAAM,KAAK,QAAQ,QAAQ;AAC5C,UAAM,MAAM,UAAU,IAAI,IAAI,KAAK,MAAM,OAAQ,IAAI;AACrD,eAAW,QAAQ,OAAO,KAAK,QAAQ,SAAS;AAAA,EAClD;AAEA,QAAM,OAAO,YAAY,MAAM;AAC/B,QAAM,OAAO,YAAY,QAAQ,WAAW,MAAM;AAClD,QAAM,EAAE,OAAO,KAAK,QAAQ,QAAQ,aAAa,aAAa,YAAY,YAAY,cAAc,iBAAiB,YAAY,QAAQ,IAAI;AAE7I,QAAM,iBAAiB,SAAS,UAAa,UAAU,UAAa,QAAQ;AAC5E,QAAM,cAAc,SAAS,UAAa,UAAU,UAAa,QAAQ;AACzE,MAAI,kBAAkB,CAAC,aAAa;AAClC,UAAM,IAAI,iBAAiB;AAAA,MACzB,QAAQ;AAAA,MACR,SACE,gCAAgC,SAAS;AAAA,IAE7C,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,SAAS,UAAa,WAAW,UAAa,WAAW,UAAa,gBAAgB;AAEtG,MAAI,eAAe,UAAa,EAAE,eAAe,UAAU;AACzD,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,gCAAgC,SAAS;AAAA,IAE7C,CAAC;AAAA,EACH;AAOA,MAAI,iBAAiB,UAAa,EAAE,eAAe,UAAU;AAC3D,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,gCAAgC,SAAS;AAAA,IAE7C,CAAC;AAAA,EACH;AAEA,MAAI,oBAAoB,UAAa,CAAC,aAAa;AACjD,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,gCAAgC,SAAS;AAAA,IAE7C,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,eAAe,CAAC,SAAS;AAG5B,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SAAS,gCAAgC,SAAS;AAAA,IACpD,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,YAAY;AAC7B,QAAM,aAAa;AAAA,IACjB,MAAM,QAAQ;AAAA,IACd,QAAQ,UAAU;AAAA,IAClB,QAAQ,UAAU;AAAA,IAClB,aAAa,eAAe;AAAA,IAC5B,aAAa,eAAe;AAAA,IAC5B,YAAY,cAAc;AAAA,EAC5B;AAIA,QAAM,gBAAgB,WAAW,EAAE,SAAS,IAAI,CAAC;AAKjD,QAAM,SAAS,EAAE,UAAU,SAAkB;AAE7C,MAAI;AACJ,MAAI;AACF,QAAI,eAAe,QAAW;AAc5B,YAAM,cAAiD,EAAE,UAAU,UAAU,QAAQ,SAAS;AAC9F,eAAS,SAAS,cAAc;AAAA,QAC9B;AAAA,UACE;AAAA,UAAa;AAAA,UAAe;AAAA,UAAW,GAAG;AAAA,UAAY,GAAG;AAAA,UACzD,UAAU;AAAA,UACV,GAAI,iBAAiB,SAAY,EAAE,QAAQ,aAAa,IAAI,CAAC;AAAA,QAC/D;AAAA,QACA;AAAA,MACF;AACA,UAAI,iBAAiB,QAAW;AAe9B,cAAM,MAAM;AACZ,cAAM,mBACJ,IAAI,SAAS,WAAW,QACxB,IAAI,WAAW,WAAW,UAC1B,IAAI,WAAW,WAAW;AAC5B,YAAI,kBAAkB;AAQpB,gBAAM,IAAI,iBAAiB;AAAA,YACzB;AAAA,YAAO,QAAQ;AAAA,YACf,SACE,IAAI,UAAU;AAAA,UAElB,CAAC;AAAA,QACH;AACA,cAAM,eAAe,IAAI;AACzB,YAAI,iBAAiB,cAAc;AACjC,gBAAM,IAAI,mBAAmB;AAAA,YAC3B;AAAA,YAAO,QAAQ;AAAA,YACf,SACE,0BAA0B,UAAU,0BAA0B,YAAY,wDACrB,YAAY,SAAS,YAAY;AAAA,UAC1F,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,WAAW,iBAAiB,QAAW;AAOrC,YAAM,IAAI,mBAAmB;AAAA,QAC3B;AAAA,QAAO,QAAQ;AAAA,QACf,SACE,kBAAkB,SAAS;AAAA,MAG/B,CAAC;AAAA,IACH,WAAW,eAAe,SAAS;AACjC,eAAS,SAAS,cAAc,KAAK,EAAE,MAAa,OAAe,KAAW,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM;AAAA,IACzH,WAAW,aAAa;AACtB,eAAS,SAAS,UAAU,KAAK,EAAE,MAAa,OAAe,KAAW,GAAG,cAAc,GAAG,MAAM;AAAA,IACtG,OAAO;AACL,eAAS,SAAS,UAAU,KAAK,YAAY,MAAM;AAAA,IACrD;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,IAAI,iBAAiB;AAAA,MACzB;AAAA,MAAO,QAAQ;AAAA,MACf,SACE,kBAAkB,KAAK,oDAAoD,SAAS,MAChF,IAAc,OAAO;AAAA,IAC7B,CAAC;AAAA,EACH;AAEA,MAAI,oBAAoB,QAAW;AACjC,UAAM,SAAU,OAAiC;AACjD,QAAI,WAAW,iBAAiB;AAC9B,YAAM,QAAQ,eAAe,MAAM;AACnC,YAAM,IAAI,iBAAiB;AAAA,QACzB;AAAA,QAAO,QAAQ;AAAA,QACf,SACE,kBAAkB,UAAU,uCAAuC,MAAM,YAAY,SAAS,CAAC,CAAC;AAAA,MAEpG,CAAC;AAAA,IACH;AAAA,EACF;AAQA,MAAI,YAAY,UAAa,UAAU,QAAW;AAChD,UAAM,kBAAkB,KAAK,KAAK,QAAQ,CAAC;AAC3C,QAAI,YAAY,iBAAiB;AAC/B,YAAM,IAAI,iBAAiB;AAAA,QACzB,QAAQ;AAAA,QACR,SACE,gCAAgC,SAAS,oDACpC,OAAO,mEAA8D,KAAK,WAC3E,eAAe;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAeO,SAAS,UAAU,WAAmB,OAAe,UAAiC,CAAC,GAAoB;AAChH,MAAI;AACF,WAAO,EAAE,IAAI,MAAM,OAAO,MAAM,WAAW,OAAO,OAAO,EAAE;AAAA,EAC7D,SAAS,KAAK;AAAA,IAgBZ;AACA,QAAI,eAAe,kBAAkB;AACnC,aAAO,EAAE,IAAI,OAAO,OAAO,IAAI;AAAA,IACjC;AACA,WAAO,EAAE,IAAI,OAAO,OAAO,iBAAiB,KAAc,EAAE,OAAO,QAAQ,UAAU,CAAC,EAAE;AAAA,EAC1F;AAAA,EACA;AACF;AAOO,SAAS,SAAS,WAAmB,OAAe,UAAiC,CAAC,GAAwB;AACnH,MAAI;AACF,WAAO,MAAM,WAAW,OAAO,OAAO;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA0BO,SAAS,aAAa,WAAmB,OAAe,UAAiC,CAAC,GAAiB;AAChH,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,MAAI,MAAM,SAAS,kBAAkB;AACnC,UAAM,IAAI,kBAAkB;AAAA,MAC1B;AAAA,MACA,SAAS,iDAAiD,gBAAgB,oBAAoB,MAAM,MAAM;AAAA,IAC5G,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ,sBAAsB;AAChC,YAAQ,oBAAoB,OAAO,OAAO;AAAA,EAC5C;AAEA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAU,WAAW,WAAW,MAAM;AAC5C,QAAM,QAAQ,QAAQ,MAAM,KAAK,KAAK;AACtC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,mBAAmB;AAAA,MAC3B;AAAA,MAAO,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMf,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,MAAI,QAAQ,OAAO,WAAW,GAAG;AAO/B,UAAM,IAAI,mBAAmB;AAAA,MAC3B,QAAQ;AAAA;AAAA;AAAA;AAAA,MAIR,QAAQ,kBAAkB,SAAS;AAAA,MACnC,SAAS,gCAAgC,SAAS;AAAA,IACpD,CAAC;AAAA,EACH;AAIA,aAAW,EAAE,MAAM,MAAM,KAAK,QAAQ,QAAQ;AAC5C,QAAI,UAAU,SAAS,CAAC,gBAAgB,MAAM,OAAQ,IAAI,CAAE,GAAG;AAC7D,YAAM,IAAI,qBAAqB;AAAA,QAC7B;AAAA,QAAO,QAAQ;AAAA,QAAW,QAAQ,MAAM,OAAQ,IAAI;AAAA,QACpD,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAQA,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,OAAO,QAAQ,eAAe;AACvC,UAAM,YAAY,MAAM,OAAQ,IAAI,SAAS;AAC7C,UAAM,SAAS,qBAAqB,WAAW,IAAI,MAAM;AACzD,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI,mBAAmB;AAAA,QAC3B;AAAA,QAAO,QAAQ;AAAA,QACf,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,UAAI,CAAC,QAAQ,SAAS;AACpB,cAAM,IAAI,oBAAoB;AAAA,UAC5B;AAAA,UAAO,QAAQ;AAAA,UACf,SACE,kBAAkB,SAAS,uBAAuB,SAAS,yBACxD,OAAO,MAAM,mCAAmC,IAAI,OAAO,KAAK,EAAE,CAAC,uEACpB,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC;AAAA,QAI/G,CAAC;AAAA,MACH;AACA,YAAM,SAAS,iBAAiB,QAAQ,IAAI,MAAM;AAClD,UAAI,WAAW,QAAQ,CAAC,MAAM,QAAQ,UAAU,IAAI,MAAM,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC;AAAA,IAChF,OAAO;AACL,UAAI,WAAW,QAAQ,CAAC,MAAM,QAAQ,UAAU,IAAI,MAAM,OAAO,OAAO,CAAC,EAAG,GAAG,CAAC,CAAC,CAAC;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,QAAsB,CAAC;AAQ7B,QAAM,UAAW,MAAyF;AAC1G,QAAM,eAAe,SAAS;AAC9B,MAAI,WAAW;AACf,aAAW,EAAE,MAAM,MAAM,KAAK,QAAQ,QAAQ;AAC5C,UAAM,MAAM,UAAU,IAAI,IAAI,KAAK,MAAM,OAAQ,IAAI;AASrD,UAAM,cAAc,CAAC,UAAU,IAAI,IAAI,KAAK,eAAe,IAAI;AAE/D,UAAM,WAAW,cAAc,YAAY,CAAC,KAAK,MAAM,SAAS,KAAK;AACrE,UAAM,KAAK,EAAE,OAAO,KAAK,SAAS,CAAC;AACnC,gBAAY,IAAI;AAAA,EAClB;AACA,SAAO;AACT;AAkBO,SAAS,cAAc,WAAmB,UAAiC,CAAC,GAAmB;AACpG,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI,kBAAkB;AAAA,MAC1B,QAAQ;AAAA,MACR,SACE,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AAKA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAU,WAAW,WAAW,MAAM;AAC5C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,OAAe,OAA8B,CAAC,GAAG;AACrD,aAAO,MAAM,WAAW,OAAO,EAAE,QAAQ,GAAG,KAAK,CAAC;AAAA,IACpD;AAAA,IACA,UAAU,OAAe,OAA8B,CAAC,GAAG;AACzD,aAAO,UAAU,WAAW,OAAO,EAAE,QAAQ,GAAG,KAAK,CAAC;AAAA,IACxD;AAAA,IACA,SAAS,OAAe,OAA8B,CAAC,GAAG;AACxD,aAAO,SAAS,WAAW,OAAO,EAAE,QAAQ,GAAG,KAAK,CAAC;AAAA,IACvD;AAAA,IACA,aAAa,OAAe,OAA8B,CAAC,GAAG;AAC5D,aAAO,aAAa,WAAW,OAAO,EAAE,QAAQ,GAAG,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AACF;;;ACr+BA,IAAM,0BAA0B;AAEhC,IAAM,qBAAwC,CAAC;AAExC,SAAS,wBAAwB,SAAgC;AACtE,MAAI,OAAO,QAAQ,aAAa,YAAY,QAAQ,SAAS,WAAW,GAAG;AACzE,UAAM,IAAI,MAAM,6EAA6E;AAAA,EAC/F;AACA,MAAI,QAAQ,SAAS,SAAS,IAAI;AAChC,UAAM,IAAI,WAAW,0FAA0F,QAAQ,SAAS,MAAM,IAAI;AAAA,EAC5I;AACA,MAAI,CAAC,MAAM,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,SAAS,WAAW,GAAG;AACrE,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AAOA,MAAI,QAAQ,SAAS,SAAS,KAAM;AAClC,UAAM,IAAI,WAAW,4EAA4E,QAAQ,SAAS,MAAM,IAAI;AAAA,EAC9H;AACA,MAAI,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,OAAO,MAAM,UAAU,GAAG;AAC3D,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AAEA,QAAM,cAAc,mBAAmB,UAAU,CAAC,MAAM,EAAE,aAAa,QAAQ,QAAQ;AACvF,MAAI,eAAe,GAAG;AACpB,uBAAmB,WAAW,IAAI;AAAA,EACpC,OAAO;AACL,QAAI,mBAAmB,UAAU,yBAAyB;AACxD,YAAM,IAAI,WAAW,qDAAqD,uBAAuB,iBAAiB;AAAA,IACpH;AACA,uBAAmB,KAAK,OAAO;AAAA,EACjC;AACF;AAIO,SAAS,qBACd,UACA,OACA,WACgB;AAChB,aAAW,WAAW,oBAAoB;AACxC,QAAI,QAAQ,aAAa,SAAU;AACnC,eAAW,WAAW,QAAQ,UAAU;AAMtC,UAAI;AACJ,UAAI;AACF,gBAAQ,QAAQ,KAAK;AAAA,MACvB,QAAQ;AACN;AAAA,MACF;AACA,UAAI,UAAU,KAAM;AACpB,YAAM,WAAW,YAAY;AAC7B,UAAI,MAAM,SAAS;AACjB,cAAM,SAAS,MAAM,QAAQ,SAAS;AACtC,eAAO,SAAS,UAAU,KAAK,QAAQ,EAAE,UAAU,SAAS,CAAC;AAAA,MAC/D;AACA,aAAO,SAAS,UAAU;AAAA,QACxB,EAAE,MAAM,MAAM,QAAQ,UAAU,MAAM,OAAO,MAAM,SAAS,UAAU,OAAO,KAAK,MAAM,OAAO,UAAU,IAAI;AAAA,QAC7G,EAAE,UAAU,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,yBAAmC;AACjD,SAAO,mBAAmB,IAAI,CAAC,MAAM,EAAE,QAAQ;AACjD;;;AC1DA,SAAS,kBAAkB,GAAmB;AAC5C,SAAO,EAAE,YAAY,EAClB,QAAQ,MAAM,IAAI,EAClB,QAAQ,MAAM,IAAI,EAClB,QAAQ,MAAM,IAAI,EAClB,QAAQ,MAAM,IAAI,EAClB,UAAU,KAAK,EACf,QAAQ,oBAAoB,EAAE;AACnC;AAMA,SAAS,YAAY,GAAW,GAAmB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,EAAE,WAAW,EAAG,QAAO,EAAE;AAC7B,MAAI,EAAE,WAAW,EAAG,QAAO,EAAE;AAAA,EAC7B;AACA,MAAI,OAAO,IAAI,MAAM,EAAE,SAAS,CAAC;AACjC,MAAI,OAAO,IAAI,MAAM,EAAE,SAAS,CAAC;AACjC,WAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,IAAK,MAAK,CAAC,IAAI;AAC9C,WAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;AAClC,SAAK,CAAC,IAAI;AACV,aAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;AAClC,YAAM,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI;AACzC,WAAK,CAAC,IAAI,KAAK;AAAA,QACb,KAAK,CAAC,IAAI;AAAA;AAAA,QACV,KAAK,IAAI,CAAC,IAAI;AAAA;AAAA,QACd,KAAK,IAAI,CAAC,IAAI;AAAA;AAAA,MAChB;AAAA,IACF;AACA,KAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI;AAAA,EAC5B;AACA,SAAO,KAAK,EAAE,MAAM;AACtB;AAaA,IAAM,qBAAqB;AAC3B,IAAM,4BAA4B;AAClC,IAAM,qBAAqB;AAkB3B,SAAS,8BAAwC;AAC/C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,IAAS;AAAA,IAAY;AAAA,IACrB;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAChB;AAAA,IAAM;AAAA,IACN;AAAA,IAAO;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAS;AAAA,IAAU;AAAA,IAAQ;AAAA,EAC7D,EAAE,IAAI,iBAAiB;AACzB;AAIA,IAAI;AACJ,SAAS,4BAA+C;AACtD,MAAI,CAAC,uBAAwB,0BAAyB,OAAO,OAAO,4BAA4B,CAAC;AACjG,SAAO;AACT;AAYA,SAAS,oBAAoB,YAAwC;AACnE,QAAM,aAAa,0BAA0B;AAC7C,QAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,MAAI,WAAW,SAAS,6BAA6B,MAAM,SAAS,oBAAoB;AACtF,UAAM,IAAI;AAAA,MACR,iEAAiE,yBAAyB,mBAAmB,kBAAkB;AAAA,IACjI;AAAA,EACF;AACA,MAAI,UAAU;AACd,QAAM,YAAY,MAAM,IAAI,CAAC,SAAS;AAIpC,QAAI,wBAAwB,KAAK,IAAI,EAAG,QAAO;AAE/C,QAAI,WAAW,SAAS,IAAI,EAAG,QAAO;AAEtC,QAAI;AACJ,QAAI,WAAW,qBAAqB;AACpC,eAAW,aAAa,YAAY;AAClC,YAAM,OAAO,YAAY,MAAM,SAAS;AACxC,UAAI,OAAO,UAAU;AACnB,mBAAW;AACX,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,SAAS,UAAa,YAAY,oBAAoB;AACxD,gBAAU;AACV,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,UAAU,UAAU,KAAK,GAAG,IAAI;AACzC;AAaA,SAAS,SAAS,WAAqC;AACrD,MAAI,OAAO,UAAU,SAAS,UAAU;AACtC,UAAM,IAAI,MAAM,6DAA6D;AAAA,EAC/E;AACA,SAAO,UAAU;AACnB;AACA,SAAS,UAAU,WAAqC;AACtD,MAAI,OAAO,UAAU,UAAU,UAAU;AACvC,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,SAAO,UAAU;AACnB;AACA,SAAS,QAAQ,WAAqC;AACpD,MAAI,OAAO,UAAU,QAAQ,UAAU;AACrC,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AACA,SAAO,UAAU;AACnB;AAEA,SAAS,iBAAiB,WAAqC;AAC7D,QAAM,MAAM,UAAU;AACtB,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,gBAAgB,OAAyB;AAChD,QAAM,aAAa,MAAM,IAAI,iBAAiB;AAO9C,QAAM,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAIjE,SAAO,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,uBAAuB,MAAM,CAAC,EAAE,KAAK,GAAG;AAC7E;AAIA,SAAS,eAAe,UAAiI,MAAc,OAAe,KAAsB;AAC1M,SAAO,SAAS,UAAU,KAAK,EAAE,MAAM,OAAO,IAAI,GAAG,EAAE,UAAU,SAAS,CAAC;AAC7E;AAEA,SAAS,QACP,UACA,WACA,MACS;AAIT,QAAM,UAAU,SAAS,UAAU,KAAK;AAAA,IACtC,MAAM,SAAS,SAAS;AAAA,IACxB,OAAO,UAAU,SAAS;AAAA,IAC1B,KAAK,QAAQ,SAAS;AAAA,EACxB,CAAC;AACD,SAAO,QAAQ,IAAI,EAAE,KAAK,CAAC;AAC7B;AAEA,SAAS,SACP,UACA,WACA,OACA,MACS;AACT,QAAM,UAAU,SAAS,UAAU,KAAK;AAAA,IACtC,MAAM,SAAS,SAAS;AAAA,IACxB,OAAO,UAAU,SAAS;AAAA,IAC1B,KAAK,QAAQ,SAAS;AAAA,EACxB,CAAC;AACD,QAAM,WAAmC,CAAC;AAC1C,MAAI,SAAS,MAAO,UAAS,OAAO;AACpC,MAAI,SAAS,OAAQ,UAAS,QAAQ;AACtC,MAAI,SAAS,QAAS,UAAS,SAAS;AACxC,MAAI,SAAS,OAAQ,UAAS,QAAQ;AACtC,SAAO,QAAQ,IAAI,QAAQ;AAC7B;AAkBA,SAAS,cAAc,KAA+B,QAAgB,WAA2B;AAE/F,MAAI,QAAQ,QAAQ;AAClB,QAAI,OAAO,YAAY;AACvB,QAAI,QAAQ,EAAG,SAAQ;AACvB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,QAAQ;AAClB,QAAI,OAAO,YAAY;AACvB,QAAI,QAAQ,EAAG,SAAQ;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,YAAY;AACrB;AAWA,SAAS,wBACP,UAMA,WACA,OACA,KACS;AACT,QAAM,UAAU,SAAS,SAAS;AAClC,QAAM,UAAU,SAAS,UAAU,KAAK;AAAA,IACtC,MAAM;AAAA,IACN,OAAO,UAAU,SAAS;AAAA,IAC1B,KAAK,QAAQ,SAAS;AAAA,EACxB,CAAC;AAUD,MAAI,CAAC,SAAS,UAAU,SAAS;AAC/B,UAAM,IAAI,MAAM,0IAA0I;AAAA,EAC5J;AAGA,MAAI;AACF,UAAM,WAAW,SAAS,UAAU,KAAK,EAAE,MAAM,SAAS,OAAO,IAAI,GAAG,EAAE,UAAU,SAAS,CAAC;AAE9F,QAAI,SAAS,UAAU,QAAQ,UAAU,OAAO,KAAK,GAAG;AAEtD,aAAO;AAAA,IACT;AAEA,WAAO,SAAS,UAAU,KAAK,EAAE,MAAM,UAAU,GAAG,OAAO,IAAI,GAAG,EAAE,UAAU,SAAS,CAAC;AAAA,EAC1F,SAAS,KAAK;AAKZ,QAAI;AACF,aAAO,SAAS,UAAU,KAAK,EAAE,MAAM,UAAU,GAAG,OAAO,IAAI,GAAG,EAAE,UAAU,SAAS,CAAC;AAAA,IAC1F,QAAQ;AACN,YAAM,IAAI;AAAA,QACR,mDAAmD,KAAK,QAAQ,GAAG,2CAChC,OAAO,OAAO,UAAU,CAAC,qBACxC,IAAc,OAAO;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;AAyBA,SAAS,qBAAqB,MAAc,OAAyB;AACnE,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,MAAM,MAAM,UAAU,CAAC,MAAM,kBAAkB,CAAC,MAAM,UAAU;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,MAAI,MAAM,GAAG;AACX,UAAM,IAAI,MAAM,8DAAyD,IAAI,sBAAsB;AAAA,EACrG;AAAA,EACA;AACA,SAAO,MAAM;AACf;AAEA,SAAS,mBAAmB,MAAc,WAAqB,aAAuB,CAAC,GAAW;AAChG,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,UAAU,UAAU,UAAU,CAAC,MAAM,kBAAkB,CAAC,MAAM,UAAU;AAC9E,MAAI,WAAW,EAAG,QAAO,UAAU;AACnC,QAAM,WAAW,WAAW,UAAU,CAAC,MAAM,kBAAkB,CAAC,MAAM,UAAU;AAEhF,MAAI,YAAY,EAAG,QAAO,WAAW;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAKA,QAAM,IAAI,MAAM,4DAAuD,IAAI,sBAAsB;AAAA,EACjG;AAEF;AAMA,IAAM,mBAAmB,CAAC,UAAU,WAAW,aAAa,YAAY,UAAU,YAAY,QAAQ;AACtG,IAAM,iBAAiB,CAAC,WAAW,YAAY,SAAS,SAAS,OAAO,QAAQ,QAAQ,UAAU,aAAa,WAAW,YAAY,UAAU;AAChJ,IAAM,sBAAsB,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAE/G,IAAM,kBAAuC;AAAA,EAC3C,eAAe;AAAA,EACf,UAAU;AAAA;AAAA;AAAA,IAGR;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,eAAe,IAAI,UAAU,SAAS,IAAI,SAAS,GAAG,UAAU,IAAI,SAAS,GAAG,QAAQ,IAAI,SAAS,CAAC;AAAA,IAC9H;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,EAAE;AAAA,IAC/D;AAAA;AAAA;AAAA,IAGA;AAAA,MACE,SAAS,IAAI,OAAO,yBAAyB,gBAAgB,gBAAgB,CAAC,MAAM,GAAG;AAAA,MACvF,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,MAAM,EAAE,CAAC,EAAG,YAAY;AAC9B,cAAM,YAAY,qBAAqB,EAAE,CAAC,GAAI,gBAAgB;AAC9D,cAAM,SAAS,iBAAiB,IAAI,SAAS;AAC7C,eAAO,QAAQ,IAAI,UAAU,IAAI,WAAW,cAAc,KAAK,QAAQ,SAAS,CAAC;AAAA,MACnF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,WAAW,EAAE,CAAC;AACpB,cAAM,QAAQ,EAAE,CAAC;AACjB,cAAM,WAAW,EAAE,CAAC,EAAG,YAAY;AAKnC,cAAM,QAAQ,CAAC,CAAC;AAChB,cAAM,SAAS,WAAW,KAAK,EAAE,CAAC,CAAE;AACpC,YAAI,CAAC,SAAS,CAAC,QAAQ;AACrB,gBAAM,IAAI;AAAA,YACR,mDAAmD,EAAE,CAAC,CAAC,sCAC5C,KAAK,IAAI,QAAQ,UAAU,KAAK,IAAI,QAAQ;AAAA,UACzD;AAAA,QACF;AAMA,YAAI,SAAS,QAAQ;AACnB,gBAAM,IAAI;AAAA,YACR,uEAAuE,EAAE,CAAC,CAAC,kBAClE,QAAQ,uBAAuB,QAAQ;AAAA,UAClD;AAAA,QACF;AACA,cAAM,OAAO,QAAQ,IAAI;AACzB,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,OAAO,OAAO,KAAK,GAAG,QAAQ;AAAA,MAC7E;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,MACE,SAAS,IAAI,OAAO,KAAK,gBAAgB,CAAC,GAAG,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,uDAAuD,GAAG;AAAA,MAC/I,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,QAAQ,mBAAmB,EAAE,CAAC,GAAI,gBAAgB,mBAAmB;AAC3E,cAAM,MAAM,OAAO,EAAE,CAAC,CAAE;AACxB,eAAO,wBAAwB,IAAI,UAAU,IAAI,WAAW,OAAO,GAAG;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACF;AAYA,IAAM,mBAAmB,CAAC,SAAS,UAAU,gBAAa,UAAU,WAAW,aAAU,SAAS;AAClG,IAAM,iBAAiB,CAAC,SAAS,WAAW,SAAS,SAAS,QAAQ,SAAS,SAAS,UAAU,cAAc,WAAW,aAAa,WAAW;AAGnJ,IAAM,sBAAsB,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,KAAK;AAEhH,IAAM,kBAAuC;AAAA,EAC3C,eAAe;AAAA,EACf,UAAU;AAAA,IACR;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,eAAe,IAAI,UAAU,SAAS,IAAI,SAAS,GAAG,UAAU,IAAI,SAAS,GAAG,QAAQ,IAAI,SAAS,CAAC;AAAA,IAC9H;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,EAAE;AAAA,IAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA;AAAA,MACE,SAAS,IAAI;AAAA,QACX,6CAA0C,gBAAgB,gBAAgB,CAAC,MAAM,gBAAgB,gBAAgB,CAAC,wCAAqC,gBAAgB,gBAAgB,CAAC;AAAA,QACxL;AAAA,MACF;AAAA,MACA,SAAS,CAAC,GAAG,QAAQ;AACnB,YAAI;AACJ,YAAI;AACJ,YAAI,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG;AAEhB,oBAAU,EAAE,CAAC;AACb,wBAAc,EAAE,CAAC;AAAA,QACnB,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG;AAEvB,wBAAc,EAAE,CAAC;AACjB,oBAAU,EAAE,CAAC;AAAA,QACf,OAAO;AAEL,oBAAU;AACV,wBAAc,EAAE,CAAC;AAAA,QACnB;AACA,cAAM,MAAM,kBAAkB,OAAO,MAAM,YAAY,SAAS,QAAQ,YAAY,MAAM,SAAS,SAAS;AAC5G,cAAM,YAAY,qBAAqB,aAAa,gBAAgB;AACpE,cAAM,SAAS,iBAAiB,IAAI,SAAS;AAC7C,eAAO,QAAQ,IAAI,UAAU,IAAI,WAAW,cAAc,KAAK,QAAQ,SAAS,CAAC;AAAA,MACnF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,MACE,SAAS,IAAI;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS,CAAC,GAAG,QAAQ;AACnB,YAAI;AACJ,YAAI;AACJ,YAAI;AACJ,YAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG;AAExB,kBAAQ,EAAE,CAAC;AACX,qBAAW,EAAE,CAAC;AACd,iBAAO;AAAA,QACT,OAAO;AAML,kBAAQ,EAAE,CAAC;AACX,qBAAW,EAAE,CAAC;AACd,iBAAO;AAAA,QACT;AACA,cAAM,OAAO,kBAAkB,QAAQ;AACvC,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,OAAO,OAAO,KAAK,GAAG,IAAI;AAAA,MACzE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA;AAAA,MACE,SAAS,IAAI,OAAO,0DAAoD,GAAG;AAAA,MAC3E,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,QAAQ,OAAO,EAAE,CAAC,CAAE;AAC1B,cAAM,OAAO,kBAAkB,EAAE,CAAC,CAAE;AACpC,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,CAAC,OAAO,IAAI;AAAA,MAC3D;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,MACE,SAAS,IAAI,OAAO,kDAA4C,GAAG;AAAA,MACnE,SAAS,CAAC,GAAG,SAAS;AACpB,cAAM,IAAI;AAAA,UACR,oDAAoD,EAAE,CAAC,CAAC,uCAC7C,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,MACE,SAAS,IAAI;AAAA,QACX,6BAA6B,gBAAgB,CAAC,GAAG,gBAAgB,GAAG,mBAAmB,CAAC,CAAC;AAAA,QACzF;AAAA,MACF;AAAA,MACA,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,MAAM,OAAO,EAAE,CAAC,CAAE;AACxB,cAAM,QAAQ,mBAAmB,EAAE,CAAC,GAAI,gBAAgB,mBAAmB;AAC3E,eAAO,wBAAwB,IAAI,UAAU,IAAI,WAAW,OAAO,GAAG;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACF;AAQA,IAAM,kBAAkB,CAAC,SAAS,SAAS,YAAY,SAAS,YAAY,UAAU,UAAU;AAChG,IAAM,gBAAgB,CAAC,WAAW,cAAW,QAAQ,SAAS,OAAO,QAAQ,WAAW,WAAQ,aAAa,WAAW,YAAY,aAAU;AAC9I,IAAM,qBAAqB,CAAC,SAAS,YAAS,QAAQ,QAAQ,OAAO,QAAQ,SAAS,WAAQ,SAAS,QAAQ,QAAQ,SAAM;AAE7H,IAAM,iBAAsC;AAAA,EAC1C,eAAe;AAAA,EACf,UAAU;AAAA,IACR;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,eAAe,IAAI,UAAU,SAAS,IAAI,SAAS,GAAG,UAAU,IAAI,SAAS,GAAG,QAAQ,IAAI,SAAS,CAAC;AAAA,IAC9H;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,EAAE;AAAA,IAC/D;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,MACE,SAAS,IAAI;AAAA,QACX,QAAQ,gBAAgB,eAAe,CAAC,kCAAkC,gBAAgB,eAAe,CAAC;AAAA,QAC1G;AAAA,MACF;AAAA,MACA,SAAS,CAAC,GAAG,QAAQ;AACnB,YAAI;AACJ,YAAI;AACJ,YAAI,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG;AAChB,wBAAc,EAAE,CAAC;AACjB,gBAAM,EAAE,CAAC,EAAG,YAAY,MAAM,aAAa,SAAS;AAAA,QACtD,OAAO;AACL,gBAAM;AACN,wBAAc,EAAE,CAAC;AAAA,QACnB;AACA,cAAM,YAAY,qBAAqB,aAAa,eAAe;AACnE,cAAM,SAAS,iBAAiB,IAAI,SAAS;AAC7C,eAAO,QAAQ,IAAI,UAAU,IAAI,WAAW,cAAc,KAAK,QAAQ,SAAS,CAAC;AAAA,MACnF;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI,OAAO,qEAAkE,GAAG;AAAA,MACzF,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,QAAQ,OAAO,EAAE,CAAC,CAAE;AAC1B,cAAM,OAAO,kBAAkB,EAAE,CAAC,CAAE;AACpC,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,CAAC,OAAO,IAAI;AAAA,MAC3D;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI,OAAO,6DAA0D,GAAG;AAAA,MACjF,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,QAAQ,OAAO,EAAE,CAAC,CAAE;AAC1B,cAAM,OAAO,kBAAkB,EAAE,CAAC,CAAE;AACpC,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,OAAO,IAAI;AAAA,MAC1D;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI,OAAO,qDAAkD,GAAG;AAAA,MACzE,SAAS,CAAC,GAAG,SAAS;AACpB,cAAM,IAAI;AAAA,UACR,6DAA0D,EAAE,CAAC,CAAC,iDAC5C,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI;AAAA,QACX,mBAAmB,gBAAgB,CAAC,GAAG,eAAe,GAAG,kBAAkB,CAAC,CAAC;AAAA,QAC7E;AAAA,MACF;AAAA,MACA,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,MAAM,OAAO,EAAE,CAAC,CAAE;AACxB,cAAM,QAAQ,mBAAmB,EAAE,CAAC,GAAI,eAAe,kBAAkB;AACzE,eAAO,wBAAwB,IAAI,UAAU,IAAI,WAAW,OAAO,GAAG;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACF;AAWA,IAAM,kBAAkB,CAAC,UAAU,YAAY,YAAY,cAAc,WAAW,WAAW,SAAS;AACxG,IAAM,gBAAgB,CAAC,UAAU,WAAW,WAAQ,SAAS,OAAO,QAAQ,QAAQ,UAAU,aAAa,WAAW,YAAY,UAAU;AAC5I,IAAM,qBAAqB,CAAC,OAAO,OAAO,UAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAE9G,IAAM,iBAAsC;AAAA,EAC1C,eAAe;AAAA,EACf,UAAU;AAAA,IACR;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,eAAe,IAAI,UAAU,SAAS,IAAI,SAAS,GAAG,UAAU,IAAI,SAAS,GAAG,QAAQ,IAAI,SAAS,CAAC;AAAA,IAC9H;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,SAAS,CAAC,IAAI,QAAQ,QAAQ,IAAI,UAAU,IAAI,WAAW,EAAE;AAAA,IAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,MACE,SAAS,IAAI,OAAO,8CAA2C,gBAAgB,eAAe,CAAC,MAAM,GAAG;AAAA,MACxG,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,MAAM,kBAAkB,EAAE,CAAC,CAAE;AACnC,cAAM,MAAiC,QAAQ,cAAc,QAAQ,cAAe,SAAS,QAAQ,WAAW,SAAS;AACzH,cAAM,YAAY,qBAAqB,EAAE,CAAC,GAAI,eAAe;AAC7D,cAAM,SAAS,iBAAiB,IAAI,SAAS;AAC7C,eAAO,QAAQ,IAAI,UAAU,IAAI,WAAW,cAAc,KAAK,QAAQ,SAAS,CAAC;AAAA,MACnF;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI,OAAO,oFAAoF,GAAG;AAAA,MAC3G,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,QAAQ,OAAO,EAAE,CAAC,CAAE;AAC1B,cAAM,OAAO,kBAAkB,EAAE,CAAC,CAAE;AACpC,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,CAAC,OAAO,IAAI;AAAA,MAC3D;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI,OAAO,mFAAmF,GAAG;AAAA,MAC1G,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,QAAQ,OAAO,EAAE,CAAC,CAAE;AAC1B,cAAM,OAAO,kBAAkB,EAAE,CAAC,CAAE;AACpC,eAAO,SAAS,IAAI,UAAU,IAAI,WAAW,OAAO,IAAI;AAAA,MAC1D;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI,OAAO,6EAA6E,GAAG;AAAA,MACpG,SAAS,CAAC,GAAG,SAAS;AACpB,cAAM,IAAI;AAAA,UACR,wDAAwD,EAAE,CAAC,CAAC,wDAC5C,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,MACE,SAAS,IAAI;AAAA,QACX,uBAAuB,gBAAgB,CAAC,GAAG,eAAe,GAAG,oBAAoB,SAAS,MAAM,CAAC,CAAC;AAAA,QAClG;AAAA,MACF;AAAA,MACA,SAAS,CAAC,GAAG,QAAQ;AACnB,cAAM,MAAM,OAAO,EAAE,CAAC,CAAE;AACxB,cAAM,QAAQ,mBAAmB,EAAE,CAAC,GAAI,eAAe,kBAAkB;AACzE,eAAO,wBAAwB,IAAI,UAAU,IAAI,WAAW,OAAO,GAAG;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,WAAgD;AAAA,EACpD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAOA,SAAS,iBAAiB,QAAiD;AACzE,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI;AAGF,UAAM,MAAM,IAAI,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC;AACrD,UAAM,OAAO,IAAI,SAAS,YAAY;AACtC,WAAO,SAAS,IAAI,KAAK;AAAA,EAC3B,QAAQ;AAIN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,WAAW,QAAoC;AACtD,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI;AACF,WAAO,IAAI,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC,EAAE,SAAS,YAAY;AAAA,EACzE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,SAAS,kBAAkB,MAAiD;AAC1E,QAAM,IAAI,kBAAkB,IAAI;AAGhC,MAAI,MAAM,SAAS,MAAM,UAAU,MAAM,WAAW,MAAM,OAAQ,QAAO;AAEzE,MAAI,MAAM,MAAO,QAAO;AACxB,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,MAAO,QAAO;AACxB,MAAI,MAAM,SAAS,MAAM,SAAO,QAAO;AAEvC,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,MAAM,UAAW,QAAO;AAC5B,MAAI,MAAM,OAAQ,QAAO;AACzB,MAAI,MAAM,QAAQ,MAAM,QAAS,QAAO;AAExC,MAAI,MAAM,SAAS,MAAM,QAAS,QAAO;AACzC,MAAI,MAAM,WAAW,MAAM,SAAU,QAAO;AAC5C,MAAI,MAAM,WAAW,MAAM,UAAW,QAAO;AAE7C,MAAI,MAAM,UAAU,MAAM,SAAU,QAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,QAAM,IAAI,MAAM,6EAAwE,IAAI,IAAI;AAAA,EAChG;AAEF;AAoEO,SAAS,cACd,OACA,eACA,UAAgC,CAAC,GACxB;AACT,QAAM,YAAY;AAClB,QAAM,WAAW,YAAY;AAU7B,QAAM,WAAW,SAAS,IAAI,KAAK,EAAE,QAAQ,QAAQ,GAAG;AACxD,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,MAAI,QAAQ,SAAS,2BAA2B;AAC9C,UAAM,IAAI;AAAA,MACR,2DAA2D,yBAAyB;AAAA,IACtF;AAAA,EACF;AAMA,QAAM,aAAa,kBAAkB,OAAO;AAE5C,QAAM,UAAU,iBAAiB,QAAQ,MAAM;AAC/C,QAAM,MAAsB,EAAE,UAAU,UAAU;AASlD,QAAM,aAAa,qBAAqB,WAAW,QAAQ,MAAM,GAAG,SAAS;AAAA,IAC3E,MAAM,UAAU;AAAA,IAChB,OAAO,UAAU;AAAA,IACjB,KAAK,UAAU;AAAA,IACf,WAAW,UAAU;AAAA,EACvB,CAAC;AACD,MAAI,eAAe,MAAM;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,CAAC,SAA4C;AAC5D,eAAW,WAAW,QAAQ,UAAU;AACtC,YAAM,QAAQ,KAAK,MAAM,QAAQ,OAAO;AACxC,UAAI,OAAO;AACT,eAAO,QAAQ,QAAQ,OAAO,GAAG;AAAA,MACnC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,SAAS,UAAU;AACvC,MAAI,gBAAgB,UAAU;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,OAAO;AAOjB,QAAI,YAAY,iBAAiB;AAC/B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,YAAY,oBAAoB,UAAU;AAChD,QAAI,cAAc,QAAW;AAC3B,YAAM,cAAc,SAAS,SAAS;AACtC,UAAI,gBAAgB,UAAU;AAC5B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,kDAAkD,OAAO,QACzD,QAAQ;AAAA,EACV;AACF;AAOA,IAAM,WAAW,uBAAO,sCAAsC;;;ACxgC9D,IAAM,aAA6C;AAAA,EACjD,MAAM,CAAC,aAAa,iBAAiB,iBAAiB,gBAAgB;AAAA,EACtE,OAAO,CAAC,aAAa,iBAAiB,iBAAiB,kBAAkB,eAAe;AAAA,EACxF,KAAK,CAAC,aAAa,iBAAiB,iBAAiB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpE,MAAM,CAAC,aAAa,iBAAiB,eAAe;AAAA,EACpD,QAAQ,CAAC,aAAa,iBAAiB,eAAe;AAAA,EACtD,QAAQ,CAAC,aAAa,iBAAiB,eAAe;AAAA,EACtD,aAAa,CAAC,aAAa,iBAAiB,eAAe;AAAA,EAC3D,WAAW,CAAC,aAAa,iBAAiB,eAAe;AAAA,EACzD,YAAY,CAAC,eAAe;AAAA,EAC5B,QAAQ,CAAC,eAAe;AAC1B;AAIO,IAAM,iBAAgD;AAAA,EAC3D,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC5G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC5G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAK,eAAe;AAAA,EACjD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAK,eAAe;AAAA,EACjD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC5G,gBAAgB,WAAW;AAAA,IAAW,eAAe;AAAA,EACvD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC5G,gBAAgB,WAAW;AAAA,IAAW,eAAe;AAAA,EACvD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAa,eAAe;AAAA,EACzD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAY,eAAe;AAAA,EACxD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAQ,eAAe;AAAA,EACpD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAK,eAAe;AAAA,EACjD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAM,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAW,eAAe;AAAA,EACvD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAW,eAAe;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAIA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW,IAAI,OAAO,CAAC,MAAM,MAAM,eAAe;AAAA,IAAG,eAAe;AAAA,EACtF;AAAA,EACA,IAAI;AAAA,IACF,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW,IAAI,OAAO,CAAC,MAAM,MAAM,eAAe;AAAA,IAAG,eAAe;AAAA,EACtF;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAO,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW,IAAI,OAAO,CAAC,MAAM,MAAM,eAAe;AAAA,IAAG,eAAe;AAAA,EACtF;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAO,eAAe;AAAA,EACnD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAW,eAAe;AAAA,EACvD;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAW,eAAe;AAAA,EACvD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAM,mBAAmB;AAAA,IAC7G,gBAAgB,WAAW;AAAA,IAAM,eAAe;AAAA,EAClD;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAY,eAAe;AAAA,EACxD;AAAA,EACA,GAAG;AAAA,IACD,SAAS;AAAA,IACT,eAAe;AAAA,IAAM,cAAc;AAAA,IAAO,iBAAiB;AAAA,IAAM,mBAAmB;AAAA,IAAO,mBAAmB;AAAA,IAC9G,gBAAgB,WAAW;AAAA,IAAY,eAAe;AAAA,EACxD;AAEF;AAEO,IAAM,kBAA4B,OAAO,KAAK,cAAc;;;AC3U5D,SAAS,eAAe,WAA4B;AACzD,SAAO,SAAS,SAAS;AAC3B;AAKO,SAAS,aAA+D;AAC7E,SAAO,OAAO,IAAI,CAAC,CAAC,IAAI,OAAO,EAAE,MAAM,UAAU,eAAe,IAAI,EAAG,EAAE;AAC3E;AAKO,SAAS,UAAU,MAAyC;AACjE,SAAO,eAAe,IAAI;AAC5B;AAkDO,SAAS,cAAc,WAAmC;AAC/D,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI;AAAA,MACR,yDAAyD,iBAAiB,oBAClE,UAAU,MAAM;AAAA,IAC1B;AAAA,EACF;AACA,QAAM,SAAS,kBAAkB,SAAS;AAC1C,QAAM,SAA0B,CAAC;AACjC,QAAM,iBAAiB,oBAAI,IAAY;AACvC,QAAM,qBAAqB,oBAAI,IAAkB;AACjD,MAAI,YAAY;AAChB,MAAI,kBAAkB;AACtB,MAAI,oBAAoB;AACxB,MAAI,oBAAoB;AACxB,MAAI,gBAAgB;AACpB,QAAM,WAAqD,CAAC;AAQ5D,QAAM,cAAwB,CAAC;AAC/B,QAAM,WAAW,MAAM;AACrB,QAAI,YAAY,UAAU,GAAG;AAC3B,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,qCAAqC,YAAY,KAAK,EAAE,CAAC;AAAA,MACpE,CAAC;AAAA,IACH;AACA,gBAAY,SAAS;AAAA,EACvB;AAEA,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,WAAW;AAC5B,eAAS;AACT;AAAA,IACF;AACA,UAAM,WAAW,eAAe,MAAM,KAAK;AAM3C,QAAI,CAAC,UAAU;AACb,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,UAAU,MAAM,KAAK;AAAA,MAChC,CAAC;AACD;AAAA,IACF;AAEA,WAAO,KAAK,EAAE,MAAM,MAAM,OAAO,UAAU,MAAM,OAAO,SAAS,CAAC;AAMlE,UAAM,UAAU,YAAY,MAAM,KAAK;AACvC,QAAI,SAAS;AACX,qBAAe,IAAI,QAAQ,KAAe;AAAA,IAC5C;AAIA,QAAI,OAAO,WAAW,GAAG;AACvB,iBAAW,KAAK,SAAS,eAAgB,oBAAmB,IAAI,CAAC;AAAA,IACnE,OAAO;AACL,YAAM,kBAAkB,oBAAI,IAAkB;AAC9C,iBAAW,KAAK,oBAAoB;AAClC,YAAI,SAAS,eAAe,SAAS,CAAC,EAAG,iBAAgB,IAAI,CAAC;AAAA,MAChE;AACA,yBAAmB,MAAM;AACzB,iBAAW,KAAK,gBAAiB,oBAAmB,IAAI,CAAC;AAAA,IAC3D;AAEA,QAAI,CAAC,SAAS,cAAc;AAC1B,kBAAY;AACZ,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,UAAU,MAAM,KAAK;AAAA,MAChC,CAAC;AAAA,IACH;AACA,QAAI,SAAS,gBAAiB,mBAAkB;AAChD,QAAI,SAAS,kBAAmB,qBAAoB;AACpD,QAAI,SAAS,kBAAmB,qBAAoB;AACpD,QAAI,CAAC,SAAS,cAAe,iBAAgB;AAM7C,QAAI,wBAAwB,IAAI,MAAM,KAAK,GAAG;AAC5C,kBAAY,KAAK,MAAM,KAAK;AAAA,IAC9B,OAAO;AACL,eAAS;AAAA,IACX;AAAA,EACF;AACA,WAAS;AAKT,QAAM,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAC3C,QAAM,YAAY,WAAW,KAAK,CAAC,MAAM,MAAM,QAAQ,MAAM,GAAG;AAChE,QAAM,YAAY,WAAW,KAAK,CAAC,MAAM,MAAM,QAAQ,MAAM,GAAG;AAChE,QAAM,aAAa,WAAW,KAAK,CAAC,MAAM,MAAM,GAAG;AACnD,MAAI,aAAa,CAAC,YAAY;AAC5B,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,MAAI,aAAa,WAAW;AAC1B,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,WAAW,KAAK,CAAC,MAAM,MAAM,OAAO,MAAM,QAAQ,MAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,MAAM,KAAK;AACzH,QAAM,SAAS,WAAW,KAAK,CAAC,MAAM,MAAM,KAAK;AACjD,MAAI,aAAa,QAAQ;AACvB,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,MAAI,aAAa,CAAC,eAAe,IAAI,MAAM,GAAG;AAC5C,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,CAAC,GAAG,cAAc,EAAE,KAAK;AAAA,IACzC,iBAAiB,CAAC,GAAG,kBAAkB,EAAE,KAAK;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,WAAW,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,uBAAuB;AAAA,IAClE,eAAe,iBAAiB;AAAA,IAChC;AAAA,EACF;AACF;AAOO,SAAS,cAAc,WAA2B;AACvD,QAAM,WAAW,cAAc,SAAS;AACxC,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,mBAAmB,SAAS,GAAG;AAC1C,QAAM,KAAK,WAAW,SAAS,OAAO,MAAM,IAAI;AAChD,aAAW,KAAK,SAAS,QAAQ;AAC/B,UAAM,KAAK,KAAK,EAAE,IAAI,KAAK,EAAE,QAAQ,WAAM,EAAE,SAAS,OAAO,EAAE;AAAA,EACjE;AACA,MAAI,SAAS,eAAe,SAAS,GAAG;AACtC,UAAM,KAAK,oBAAoB,SAAS,eAAe,KAAK,IAAI,CAAC,EAAE;AAAA,EACrE;AACA,MAAI,SAAS,gBAAgB,SAAS,GAAG;AACvC,UAAM,KAAK,8BAA8B,SAAS,gBAAgB,KAAK,IAAI,CAAC,EAAE;AAAA,EAChF;AACA,QAAM,KAAK,cAAc,SAAS,YAAY,QAAQ,IAAI,EAAE;AAC5D,QAAM,KAAK,qBAAqB,SAAS,kBAAkB,QAAQ,IAAI,EAAE;AACzE,QAAM,KAAK,uBAAuB,SAAS,oBAAoB,QAAQ,IAAI,EAAE;AAC7E,QAAM,KAAK,uBAAuB,SAAS,oBAAoB,QAAQ,IAAI,EAAE;AAC7E,QAAM,KAAK,cAAc,SAAS,YAAY,QAAQ,IAAI,EAAE;AAC5D,QAAM,KAAK,oBAAoB,SAAS,gBAAgB,QAAQ,IAAI,EAAE;AACtE,MAAI,SAAS,SAAS,SAAS,GAAG;AAChC,UAAM,KAAK,WAAW;AACtB,eAAW,KAAK,SAAS,UAAU;AACjC,YAAM,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE;AAAA,IACzC;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAQO,SAAS,cAAc,WAA4B;AACxD,MAAI,UAAU,SAAS,kBAAmB,QAAO;AACjD,MAAI;AACF,aAAS,SAAS;AAClB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,eAAe,WAAmC;AAChE,QAAM,WAAW,cAAc,SAAS;AACxC,SAAO;AACT;AAkBO,SAAS,cAAc,OAA+C;AAC3E,SAAO,YAAY,KAAK,GAAG;AAC7B;;;AC7RA,SAASC,eAAc,MAAqB,QAA0C;AACpF,aAAW,KAAK,QAAQ;AACtB,QAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,YAAM,IAAI;AAAA,QACR,2CAA2C,OAAO,CAAC,CAAC;AAAA,MAEtD;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,YAAY,MAA6B;AACvD,EAAAA,eAAc,MAAM,CAAC,QAAQ,OAAO,CAAC;AACrC,QAAM,EAAE,MAAM,MAAM,IAAI;AAIxB,QAAM,UAAU,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC/D,MAAI,UAAU,KAAK,oBAAoB,IAAK,EAAG,QAAO;AACtD,SAAO,QAAS,QAAS,CAAG;AAC9B;AAEO,SAASC,YAAW,MAAgC;AACzD,EAAAD,eAAc,MAAM,CAAC,MAAM,CAAC;AAC5B,SAAO,oBAAoB,KAAK,IAAK,IAAI,MAAM;AACjD;AAEO,SAAS,aAAa,OAA0B;AAMrD,SAAO;AACT;AAEO,SAAS,WAAW,MAA8B;AACvD,EAAAA,eAAc,MAAM,CAAC,MAAM,CAAC;AAC5B,SAAO,oBAAoB,KAAK,IAAK;AACvC;AAOO,SAAS,YAAY,OAA+B;AACzD,SAAO;AACT;AAEO,SAAS,gBAAgB,MAA6B;AAC3D,EAAAA,eAAc,MAAM,CAAC,QAAQ,SAAS,KAAK,CAAC;AAC5C,SAAO,UAAU,KAAK,MAAO,KAAK,OAAQ,KAAK,GAAI;AACrD;AAOO,SAAS,WAAW,MAA6B;AACtD,EAAAA,eAAc,MAAM,CAAC,QAAQ,SAAS,OAAO,WAAW,CAAC;AACzD,SAAO,mBAAmB,KAAK,MAAO,KAAK,OAAQ,KAAK,KAAM,KAAK,SAAU,EAAE;AACjF;AAEO,SAAS,SAAS,MAA6B;AACpD,EAAAA,eAAc,MAAM,CAAC,QAAQ,SAAS,OAAO,WAAW,CAAC;AACzD,SAAO,mBAAmB,KAAK,MAAO,KAAK,OAAQ,KAAK,KAAM,KAAK,SAAU,EAAE;AACjF;AAaA,SAAS,mBAAmB,YAA0B;AACpD,MAAI,CAAC,OAAO,UAAU,UAAU,KAAK,aAAa,KAAK,aAAa,IAAI;AACtE,UAAM,IAAI;AAAA,MACR,8EAA8E,UAAU;AAAA,IAC1F;AAAA,EACF;AACF;AAEO,SAAS,WAAW,MAAqB,UAA0B,CAAC,GAAW;AACpF,EAAAA,eAAc,MAAM,CAAC,OAAO,CAAC;AAC7B,QAAM,aAAa,QAAQ,cAAc;AACzC,qBAAmB,UAAU;AAC7B,MAAI,eAAe,GAAG;AAEpB,WAAO,KAAK,KAAK,KAAK,QAAS,CAAC;AAAA,EAClC;AAQA,QAAM,WAAY,KAAK,QAAS,aAAa,MAAM,KAAM;AACzD,SAAO,KAAK,KAAK,UAAU,CAAC;AAC9B;AAOO,SAAS,SAAS,MAA6B;AACpD,EAAAA,eAAc,MAAM,CAAC,OAAO,CAAC;AAC7B,SAAO,KAAK;AACd;AAEO,SAAS,WAAW,MAA6B;AACtD,EAAAA,eAAc,MAAM,CAAC,WAAW,CAAC;AACjC,SAAO,KAAK;AACd;AAaA,SAAS,YAAY,MAA4B;AAC/C,SAAO,SAAS,SAAS,SAAS,WAAW,SAAS;AACxD;AAOA,SAAS,mBAAmB,MAA2B;AACrD,MAAI,OAAO,KAAK,cAAc,SAAU;AAAA,EACxC;AAAA;AAAA;AAAA;AAIA,MAAI,OAAO,KAAK,SAAS,YAAY,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,QAAQ,SAAU;AAAA,EACrG;AAKA,OAAK,YAAY,mBAAmB,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG;AACrE;AAEO,SAAS,QAAQ,OAAgB,MAAkC;AACxE,QAAM,OAAO,gBAAgB,KAAK;AAClC,QAAM,SAAwB,EAAE,GAAG,KAAK;AACxC,MAAI,SAAS,QAAQ;AACnB,WAAO,QAAQ;AACf,WAAO,MAAM;AAAA,EACf,WAAW,SAAS,SAAS;AAC3B,WAAO,MAAM;AAAA,EACf;AACA,qBAAmB,MAAM;AACzB,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,OAAO;AACd,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,WAAO,cAAc;AAAA,EACvB,WAAW,SAAS,QAAQ;AAC1B,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,WAAO,cAAc;AAAA,EACvB,WAAW,SAAS,UAAU;AAC5B,WAAO,SAAS;AAChB,WAAO,cAAc;AAAA,EACvB,WAAW,SAAS,UAAU;AAC5B,WAAO,cAAc;AAAA,EACvB;AACA,SAAO;AACT;AAEO,SAAS,MAAM,OAAgB,MAAkC;AACtE,QAAM,OAAO,gBAAgB,KAAK;AAClC,QAAM,SAAwB,EAAE,GAAG,KAAK;AACxC,MAAI,SAAS,QAAQ;AACnB,WAAO,QAAQ;AACf,WAAO,MAAM,YAAY,EAAE,MAAM,OAAO,MAAO,OAAO,GAAG,CAAC;AAAA,EAC5D,WAAW,SAAS,SAAS;AAC3B,WAAO,MAAM,YAAY,EAAE,MAAM,OAAO,MAAO,OAAO,OAAO,MAAO,CAAC;AAAA,EACvE;AACA,qBAAmB,MAAM;AACzB,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,OAAO;AACd,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,WAAO,cAAc;AAAA,EACvB,WAAW,SAAS,QAAQ;AAC1B,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,WAAO,cAAc;AAAA,EACvB,WAAW,SAAS,UAAU;AAC5B,WAAO,SAAS;AAChB,WAAO,cAAc;AAAA,EACvB,WAAW,SAAS,UAAU;AAC5B,WAAO,cAAc;AAAA,EACvB;AACA,SAAO;AACT;AAKO,SAAS,gBAAgB,OAA+B;AAC7D,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,IAAI,MAAM,8DAA8D,OAAO,KAAK,CAAC,GAAG;AAAA,EAChG;AAKA,QAAM,IAAI;AACV,QAAM,MAAqB,CAAC;AAC5B,MAAI,OAAO,EAAE,SAAS,SAAU,KAAI,OAAO,EAAE;AAC7C,MAAI,OAAO,EAAE,UAAU,SAAU,KAAI,QAAQ,EAAE;AAC/C,MAAI,OAAO,EAAE,QAAQ,SAAU,KAAI,MAAM,EAAE;AAC3C,MAAI,OAAO,EAAE,SAAS,SAAU,KAAI,OAAO,EAAE;AAC7C,MAAI,OAAO,EAAE,WAAW,SAAU,KAAI,SAAS,EAAE;AACjD,MAAI,OAAO,EAAE,WAAW,SAAU,KAAI,SAAS,EAAE;AACjD,MAAI,OAAO,EAAE,gBAAgB,SAAU,KAAI,cAAc,EAAE;AAC3D,MAAI,OAAO,EAAE,cAAc,SAAU,KAAI,YAAY,EAAE;AACvD,MAAI,OAAO,EAAE,eAAe,SAAU,KAAI,aAAa,EAAE;AACzD,MAAI,IAAI,SAAS,UAAa,IAAI,UAAU,UAAa,IAAI,QAAQ,QAAW;AAC9E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACtQA,SAAS,eAAe,MAAiC;AAiBvD,QAAM,OAAO,cAAc,KAAK,MAAO,KAAK,OAAQ,KAAK,GAAI;AAE7D,QAAME,eAAc;AACpB,QAAMC,iBAAgB;AACtB,QAAMC,iBAAgB;AAEtB,SAAO,OAAO,SACT,KAAK,QAAQ,KAAKF,gBAClB,KAAK,UAAU,KAAKC,kBACpB,KAAK,UAAU,KAAKC,kBACpB,KAAK,eAAe;AAC3B;AAEA,SAAS,oBAAoB,OAAmC;AAC9D,QAAM,IAAI,gBAAgB,KAAK;AAC/B,SAAO;AACT;AAKO,SAAS,QAAQ,GAAY,GAAoB;AACtD,QAAM,KAAK,oBAAoB,CAAC;AAChC,QAAM,KAAK,oBAAoB,CAAC;AAChC,QAAM,KAAK,eAAe,EAAE;AAC5B,QAAM,KAAK,eAAe,EAAE;AAC5B,MAAI,KAAK,GAAI,QAAO;AACpB,MAAI,KAAK,GAAI,QAAO;AACpB,SAAO;AACT;AAEO,SAAS,QAAQ,GAAY,GAAqB;AACvD,SAAO,QAAQ,GAAG,CAAC,MAAM;AAC3B;AAEO,SAAS,SAAS,GAAY,GAAqB;AACxD,SAAO,QAAQ,GAAG,CAAC,IAAI;AACzB;AAEO,SAAS,QAAQ,GAAY,GAAqB;AACvD,SAAO,QAAQ,GAAG,CAAC,IAAI;AACzB;AAEO,SAAS,IAAI,QAA4B;AAC9C,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAG;AACjD,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,MAAI,OAAO,OAAO,CAAC;AACnB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,EAAG,QAAO,OAAO,CAAC;AAAA,EACnD;AACA,SAAO;AACT;AAEO,SAAS,IAAI,QAA4B;AAC9C,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAG;AACjD,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,MAAI,OAAO,OAAO,CAAC;AACnB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,EAAG,QAAO,OAAO,CAAC;AAAA,EACnD;AACA,SAAO;AACT;AAEO,SAAS,MAAM,OAAgB,IAAa,IAAsB;AACvE,MAAI,QAAQ,OAAO,EAAE,IAAI,EAAG,QAAO;AACnC,MAAI,QAAQ,OAAO,EAAE,IAAI,EAAG,QAAO;AACnC,SAAO;AACT;AAEO,SAAS,UAAU,OAAgB,IAAa,IAAsB;AAC3E,SAAO,QAAQ,OAAO,EAAE,KAAK,KAAK,QAAQ,OAAO,EAAE,KAAK;AAC1D;AAOA,SAAS,iBAAiB,OAA8D;AACtF,QAAM,IAAI,gBAAgB,KAAK;AAC/B,SAAO,EAAE,MAAM,EAAE,MAAO,OAAO,EAAE,OAAQ,KAAK,EAAE,IAAK;AACvD;AAEA,SAAS,oBAAkE;AACzE,QAAM,MAAM,oBAAI,KAAK;AACrB,SAAO,EAAE,MAAM,IAAI,YAAY,GAAG,OAAO,IAAI,SAAS,IAAI,GAAG,KAAK,IAAI,QAAQ,EAAE;AAClF;AAEA,SAAS,sBAAsB,GAAiD,GAA0D;AACxI,SAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE;AACjE;AAEO,SAAS,UAAU,OAAgB,WAA6B;AACrE,SAAO,sBAAsB,iBAAiB,KAAK,GAAG,iBAAiB,SAAS,CAAC;AACnF;AAEO,SAAS,QAAQ,OAAyB;AAC/C,SAAO,sBAAsB,iBAAiB,KAAK,GAAG,kBAAkB,CAAC;AAC3E;AAEA,SAAS,uBAAqE;AAC5E,QAAM,IAAI,oBAAI,KAAK;AACnB,IAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC;AACzB,SAAO,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,EAAE,SAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,EAAE;AAC5E;AAEA,SAAS,wBAAsE;AAC7E,QAAM,IAAI,oBAAI,KAAK;AACnB,IAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC;AACzB,SAAO,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,EAAE,SAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,EAAE;AAC5E;AAEO,SAAS,WAAW,OAAyB;AAClD,SAAO,sBAAsB,iBAAiB,KAAK,GAAG,qBAAqB,CAAC;AAC9E;AAEO,SAAS,YAAY,OAAyB;AACnD,SAAO,sBAAsB,iBAAiB,KAAK,GAAG,sBAAsB,CAAC;AAC/E;AAEA,SAAS,SAAS,OAAe,QAAgB,MAAc,OAAe,QAAgB,MAAuB;AAanH,QAAM,YAAY,CAAC,GAAW,GAAW,MAAsB;AAI7D,WAAO,cAAc,GAAG,GAAG,CAAC;AAAA,EAC9B;AACA,QAAM,IAAI,UAAU,OAAO,QAAQ,IAAI;AACvC,QAAM,IAAI,UAAU,OAAO,QAAQ,IAAI;AACvC,MAAI,KAAK,IAAI,IAAI,CAAC,KAAK,EAAG,QAAO;AAIjC,QAAMC,aAAY,CAAC,GAAW,GAAW,MAAsB;AAK7D,WAAO,mBAAmB,GAAG,GAAG,CAAC;AAAA,EACnC;AACA,QAAM,KAAK,KAAKA,WAAU,OAAO,QAAQ,IAAI,IAAI;AACjD,QAAM,KAAK,KAAKA,WAAU,OAAO,QAAQ,IAAI,IAAI;AACjD,SAAO,OAAO;AAChB;AAEO,SAAS,WAAW,OAAgB,WAA6B;AACtE,QAAM,IAAI,iBAAiB,KAAK;AAChC,QAAM,IAAI,iBAAiB,SAAS;AACpC,SAAO,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;AAChE;AAEO,SAAS,YAAY,OAAgB,WAA6B;AACvE,QAAM,IAAI,iBAAiB,KAAK;AAChC,QAAM,IAAI,iBAAiB,SAAS;AACpC,SAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE;AAC5C;AAEO,SAAS,cAAc,OAAgB,WAA6B;AACzE,QAAM,IAAI,iBAAiB,KAAK;AAChC,QAAM,IAAI,iBAAiB,SAAS;AACpC,SAAO,EAAE,SAAS,EAAE,QAAQ,KAAK,KAAK,EAAE,QAAQ,CAAC,MAAM,KAAK,KAAK,EAAE,QAAQ,CAAC;AAC9E;AAEO,SAAS,WAAW,OAAgB,WAA6B;AACtE,SAAO,iBAAiB,KAAK,EAAE,SAAS,iBAAiB,SAAS,EAAE;AACtE;AAQO,SAAS,UAAU,OAAyB;AACjD,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,IAAI,MAAM,4DAA4D,OAAO,KAAK,CAAC,GAAG;AAAA,EAC9F;AACA,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,cAAc,UAAU;AACnC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,cAAc,KAAK,EAAE,cAAc;AAC9C;AAEO,SAAS,UAAU,OAAyB;AACjD,SAAO,CAAC,UAAU,KAAK;AACzB;;;ACxNA,IAAM,cAA4C;AAAA,EAChD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,SAAS,UAAU,IAAY,MAAoB,WAA2B;AAW5E,QAAM,UAAU,KAAK;AACrB,MAAI;AACJ,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAW,gBAAU,KAAK,MAAM,OAAO;AAAG;AAAA,IAC/C,KAAK;AAAS,gBAAU,KAAK,MAAM,OAAO;AAAG;AAAA,IAC7C,KAAK;AAAQ,gBAAU,KAAK,KAAK,OAAO;AAAG;AAAA,IAC3C,KAAK;AAAS,gBAAU,KAAK,MAAM,OAAO;AAAG;AAAA,EAC/C;AACA,SAAO,UAAU;AACnB;AAEA,SAAS,KAAK,GAA8B;AAM1C,QAAM,OAAO,cAAc,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI;AACpD,SAAO,OAAO,YAAY,OACrB,EAAE,QAAQ,KAAK,YAAY,QAC3B,EAAE,UAAU,KAAK,YAAY,UAC7B,EAAE,UAAU,KAAK,YAAY,UAC7B,EAAE,eAAe;AACxB;AAEA,SAAS,OAAO,IAAY,MAA4C;AAGtE,QAAMC,cAAa,YAAY;AAC/B,QAAM,YAAY,KAAK,MAAM,KAAKA,WAAU;AAC5C,MAAI,YAAY,KAAK,YAAYA;AASjC,MAAI,YAAY,EAAG,cAAaA;AAChC,QAAM,OAAO,KAAK,MAAM,YAAY,YAAY,IAAI;AACpD,QAAM,SAAS,KAAK,MAAO,YAAY,YAAY,OAAQ,YAAY,MAAM;AAC7E,QAAM,SAAS,KAAK,MAAO,YAAY,YAAY,SAAU,YAAY,MAAM;AAC/E,QAAM,cAAc,YAAY,YAAY;AAM5C,QAAM,IAAI,YAAY;AACtB,QAAM,MAAM,KAAK,OAAO,KAAK,IAAI,IAAI,IAAI,UAAU,MAAM;AACzD,QAAM,MAAM,IAAI,MAAM;AACtB,QAAM,MAAM,KAAK,OAAO,MAAM,KAAK,MAAM,MAAM,IAAI,IAAI,KAAK,MAAM,MAAM,KAAK,IAAI,KAAK,MAAM,MAAM,MAAM,KAAK,GAAG;AAChH,QAAM,KAAK,MAAM,MAAM;AACvB,QAAM,MAAM,OAAO,MAAM,MAAM,KAAK,MAAM,MAAM,CAAC,IAAI,KAAK,MAAM,MAAM,GAAG;AACzE,QAAM,KAAK,KAAK,OAAO,IAAI,MAAM,KAAK,GAAG;AACzC,QAAM,IAAI,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK,CAAC,IAAI;AACjD,QAAM,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK;AAClC,QAAM,OAAO,KAAK,IAAI,KAAK,IAAI;AAC/B,SAAO,EAAE,GAAG,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,QAAQ,QAAQ,YAAY;AAC9E;AA4BO,SAAS,MAAM,OAAgB,SAA0C;AAC9E,QAAM,OAAO,gBAAgB,KAAK;AAClC,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,aAAa,QAAQ,qBAAqB,KAAK,YAAY,QAAQ,IAAI;AAC7E,MAAI,aAAa,GAAG;AAClB,UAAM,IAAI,MAAM,oEAAoE,QAAQ,iBAAiB,IAAI;AAAA,EACnH;AACA,QAAM,KAAK,KAAK,IAAI;AACpB,QAAM,UAAU,UAAU,IAAI,MAAM,SAAS;AAC7C,SAAO,OAAO,SAAS,IAAI;AAC7B;AAEO,SAAS,MAAM,OAAgB,MAAoB,oBAA4B,GAAsB;AAC1G,SAAO,MAAM,OAAO,EAAE,MAAM,MAAM,SAAS,kBAAkB,CAAC;AAChE;AAEO,SAAS,KAAK,OAAgB,MAAoB,oBAA4B,GAAsB;AACzG,SAAO,MAAM,OAAO,EAAE,MAAM,MAAM,QAAQ,kBAAkB,CAAC;AAC/D;AAEO,SAAS,SAAS,OAAgB,MAAoB,oBAA4B,GAAsB;AAC7G,SAAO,MAAM,OAAO,EAAE,MAAM,MAAM,SAAS,kBAAkB,CAAC;AAChE;AAgCO,SAAS,UAAU,GAAW,OAAe,OAAuB;AACzE,MAAI,OAAO,UAAU,CAAC,EAAG,QAAO,OAAO,CAAC,IAAI;AAC5C,QAAM,SAAS,IAAI,OAAO,KAAK;AAC/B,MAAI,OAAO,cAAc,MAAM,EAAG,QAAO,OAAO,MAAM;AACtD,QAAM,IAAI,qBAAqB;AAAA,IAC7B,QAAQ,UAAU,KAAK,MAAM,CAAC;AAAA,EAChC,CAAC;AACH;AAIA,IAAM,sBAAoD;AAAA,EACxD,OAAO;AAAA;AAAA,EACP,QAAQ;AAAA;AAAA,EACR,OAAO;AAAA;AAAA,EACP,MAAM,SAAU;AAAA,EAChB,OAAO,QAAS;AAAA,EAChB,SAAS,MAAM;AAAA,EACf,SAAS;AAAA,EACT,cAAc;AAAA,EACd,cAAc;AAAA,EACd,aAAa;AACf;AAQA,SAAS,gBAAgB,MAA6B;AACpD,SAAO,SAAS,WAAW,SAAS,YAAY,SAAS;AAC3D;AAEO,SAAS,cAAc,UAA0B,SAIrC;AACjB,QAAM,OAAO,QAAQ,QAAQ;AAO7B,QAAM,iBAAiB,QAAQ,qBAAqB;AACpD,MAAI,OAAO,mBAAmB,YAAY,CAAC,OAAO,UAAU,cAAc,KAAK,iBAAiB,GAAG;AACjG,UAAM,IAAI,qBAAqB;AAAA,MAC7B,QACE,4EAA4E,OAAO,cAAc,CAAC,OACjG,OAAO,UAAU,cAAc,IAAI,KAAK;AAAA,IAC7C,CAAC;AAAA,EACH;AACA,QAAM,YAAY,OAAO,cAAc;AACvC,MAAI,gBAAgB,QAAQ,IAAI,GAAG;AACjC,UAAM,IAAI;AAAA,MACR,qCAAqC,QAAQ,IAAI;AAAA,IAEnD;AAAA,EACF;AAGA,MAAI,UAAU;AACd,aAAW,KAAK,CAAC,QAAQ,SAAS,WAAW,WAAW,gBAAgB,gBAAgB,aAAa,GAAqB;AACxH,UAAM,IAAI,SAAS,CAAC,KAAK;AACzB,eAAW,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC;AAAA,EACnD;AAUA,QAAM,SAAS,YAAY,oBAAoB,QAAQ,IAAI;AAC3D,QAAM,OAAO,UAAU,KAAK,CAAC,KAAK;AAClC,QAAM,MAAM,UAAU,KAAK,CAAC,UAAU;AACtC,QAAM,UAAU,MAAM;AACtB,QAAM,YAAY,MAAM;AACxB,MAAI;AACJ,UAAQ,MAAM;AAAA,IACZ,KAAK;AAKH,gBAAU,YAAY,MAAM,SAAS,UAAU,KAAK;AACpD;AAAA;AAAA;AAAA;AAAA,IAIF,KAAK;AAAS,gBAAU,OAAO,MAAM,YAAY,KAAK,UAAU,KAAK;AAAS;AAAA,IAC9E,KAAK;AAAQ,gBAAU,OAAO,MAAM,YAAY,KAAK,UAAU,KAAK;AAAS;AAAA,IAC7E,KAAK;AAAS,gBAAU;AAAS;AAAA,EACnC;AACA,QAAM,aAAa,OAAO,UAAU;AAKpC,QAAM,SAAyB,EAAE,GAAG,SAAS;AAC7C,MAAI,YAAY;AAIhB,QAAM,eAA+B,CAAC,QAAQ,SAAS,WAAW,WAAW,gBAAgB,gBAAgB,aAAa;AAC1H,QAAM,WAAW,aAAa,QAAQ,QAAQ,IAAI;AAOlD,WAAS,IAAI,WAAW,GAAG,IAAI,aAAa,QAAQ,KAAK;AACvD,WAAO,aAAa,CAAC,CAAE,IAAI;AAAA,EAC7B;AAGA,WAAS,IAAI,GAAG,KAAK,UAAU,KAAK;AAClC,UAAM,IAAI,aAAa,CAAC;AACxB,UAAM,SAAS,oBAAoB,CAAC;AAOpC,QAAI,WAAW,GAAI;AACnB,UAAM,QAAQ,YAAY;AAC1B,iBAAa,QAAQ;AAMrB,WAAO,CAAC,IAAI,OAAO,KAAK;AAAA,EAC1B;AACA,SAAO;AACT;;;AC9PO,SAAS,SAAS,OAAwB;AAC/C,QAAM,WAAW,YAAY;AAK7B,MAAI;AACF,QAAI,sBAAsB,KAAK,KAAK,KAAK,eAAe,KAAK,KAAK,GAAG;AAEnE,UAAI,QAAQ,KAAK,KAAK,KAAK,oBAAoB,KAAK,KAAK,GAAG;AAM1D,YAAI,MAAM;AACV,YAAI,QAAQ,KAAK,GAAG,GAAG;AACrB,gBAAM,IAAI,MAAM,GAAG,EAAE,IAAI;AAAA,QAC3B,OAAO;AACL,gBAAM,cAAc,sBAAsB,KAAK,GAAG;AAClD,cAAI,aAAa;AACf,kBAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC;AAAA,UAChC;AAAA,QACF;AACA,eAAO,SAAS,cAAc,KAAK,KAA+D,EAAE,UAAU,SAAS,CAAC;AAAA,MAC1H;AACA,aAAO,SAAS,cAAc,KAAK,OAAiE,EAAE,UAAU,SAAS,CAAC;AAAA,IAC5H;AACA,QAAI,qBAAqB,KAAK,KAAK,GAAG;AACpC,aAAO,SAAS,UAAU,KAAK,OAAiE,EAAE,UAAU,SAAS,CAAC;AAAA,IACxH;AACA,QAAI,eAAe,KAAK,KAAK,GAAG;AAC9B,aAAO,SAAS,UAAU,KAAK,KAA+D;AAAA,IAChG;AACA,UAAM,IAAI,MAAM,2BAA2B,KAAK,0CAA0C;AAAA,EAC5F,SAAS,KAAK;AACZ,UAAM,IAAI,iBAAiB,EAAE,OAAO,QAAS,IAAc,QAAQ,CAAC;AAAA,EACtE;AACF;AAEO,SAAS,UAAU,OAAwB;AAGhD,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,aAAa,YAAY;AACrC,UAAM,IAAI,kBAAkB,EAAE,QAAQ,6DAA6D,OAAO,KAAK,IAAI,CAAC;AAAA,EACtH;AACA,SAAO,EAAE,SAAS;AACpB;AAOO,SAAS,aAAa,OAAwB;AAenD,QAAM,KAAK;AACX,QAAM,IAAI,GAAG,KAAK,KAAK;AACvB,MAAI,CAAC,GAAG;AACN,UAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,4CAA4C,CAAC;AAAA,EAC5F;AAEA,QAAM,MAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,QAAQ,SAAS,aAAa;AACrE,SAAO,SAAS,GAAG;AACrB;AAEO,SAAS,cAAc,OAAwB;AAIpD,QAAM,IAAI,UAAU,KAAK;AACzB,MAAI,CAAC,8FAA8F,KAAK,CAAC,GAAG;AAC1G,UAAM,IAAI,kBAAkB,EAAE,OAAO,GAAG,QAAQ,kDAAkD,CAAC;AAAA,EACrG;AACA,SAAO;AACT;AASO,SAAS,aAAa,OAAwB;AAQnD,QAAM,gBACJ;AACF,MAAI,CAAC,cAAc,KAAK,MAAM,KAAK,CAAC,GAAG;AACrC,UAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,4BAA4B,CAAC;AAAA,EAC5E;AACA,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,MAAI,OAAO,MAAM,EAAE,GAAG;AACpB,UAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,4BAA4B,CAAC;AAAA,EAC5E;AACA,SAAO,eAAe,EAAE,sBAAsB,EAAE;AAClD;AAEO,SAAS,cAAc,OAAwB;AAIpD,QAAM,IAAI;AACV,MAAI;AACJ,MAAI,OAAO,GAAG,wBAAwB,YAAY;AAChD,SAAK,EAAE,oBAAoB;AAAA,EAC7B,WAAW,OAAO,GAAG,sBAAsB,UAAU;AAEnD,SAAK,EAAE;AAAA,EACT,WAAW,OAAO,GAAG,cAAc,YAAY;AAE7C,UAAM,OAAO,EAAE,UAAU;AACzB,QAAI,OAAQ,KAAwC,sBAAsB,UAAU;AAClF,WAAM,KAAuC;AAAA,IAC/C;AAAA,EACF;AACA,MAAI,OAAO,QAAW;AACpB,UAAM,IAAI,kBAAkB,EAAE,QAAQ,sGAAsG,OAAO,KAAK,IAAI,CAAC;AAAA,EAC/J;AACA,SAAO,oBAAoB,EAAE;AAC/B;AAEA,SAAS,oBAAoB,IAAoB;AAI/C,MAAI;AACF,UAAM,MAAM,IAAI,KAAK,eAAe,SAAS;AAAA,MAC3C,SAAS;AAAA,MAAS,KAAK;AAAA,MAAW,OAAO;AAAA,MAAS,MAAM;AAAA,MACxD,MAAM;AAAA,MAAW,QAAQ;AAAA,MAAW,QAAQ;AAAA,MAC5C,UAAU;AAAA,MAAO,cAAc;AAAA,MAC/B,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,QAAQ,IAAI,cAAc,IAAI,KAAK,EAAE,CAAC;AAK5C,UAAM,MAAM,CAAC,MAAc,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS;AAErE,UAAM,QAAQ,IAAI,cAAc;AAGhC,UAAM,UAAU,OAAO,MAAM,2BAA2B;AACxD,QAAI;AACJ,QAAI,SAAS;AACX,YAAM,OAAO,QAAQ,CAAC;AACtB,YAAM,QAAQ,QAAQ,CAAC,EAAG,SAAS,GAAG,GAAG;AACzC,YAAM,WAAW,QAAQ,CAAC,KAAK,KAAK,SAAS,GAAG,GAAG;AACnD,WAAK,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO;AAAA,MAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,OAAO;AACL,WAAK;AAAA,IACP;AAAA,IACA;AACA,QAAI,OAAO,IAAI,MAAM;AAAA,IACrB;AAAA;AAAA;AAAA;AAAA;AAKA,QAAI,SAAS,KAAM,QAAO;AAAA,IAC1B;AACA,WAAO,GAAG,IAAI,SAAS,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE;AAAA,IACtH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMF,QAAQ;AAEN,UAAM,IAAI,IAAI,KAAK,EAAE;AACrB,UAAM,OAAO,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC7D,UAAM,SAAS,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAClG,UAAM,KAAK,KAAK,EAAE,UAAU,CAAC;AAC7B,UAAM,KAAK,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACjD,UAAM,MAAM,OAAO,EAAE,YAAY,CAAC;AAClC,UAAM,OAAO,EAAE,eAAe;AAC9B,UAAM,KAAK,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,UAAM,KAAK,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,UAAM,KAAK,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,WAAO,GAAG,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAAA,EACtD;AAAA,EACA;AACF;AAOO,SAAS,cAAc,OAAwB;AACpD,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,KAAK,KAAK,MAAM,OAAO;AAC7B,MAAI,OAAO,MAAM,EAAE,GAAG;AACpB,UAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,wBAAwB,CAAC;AAAA,EACxE;AACA,SAAO,eAAe,EAAE,sBAAsB,EAAE;AAClD;AAEO,SAAS,eAAe,OAAwB;AAErD,QAAM,UAAW,OAA+D,YAAY,KACtF;AACN,QAAM,KAAK,OAAO,YAAY,YAAY,YAAY,QAAQ,uBAAuB,UAChF,QAA0C,qBAC1C,MAAM;AAAE,UAAM,IAAI,kBAAkB,EAAE,QAAQ,6DAA6D,OAAO,KAAK,IAAI,CAAC;AAAA,EAAG,GAAG;AACvI,QAAM,IAAI,IAAI,KAAK,EAAE;AACrB,QAAM,OAAO,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC7D,QAAM,SAAS,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAClG,QAAM,KAAK,KAAK,EAAE,UAAU,CAAC;AAC7B,QAAM,KAAK,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACjD,QAAM,MAAM,OAAO,EAAE,YAAY,CAAC;AAClC,QAAM,OAAO,EAAE,eAAe;AAC9B,QAAM,KAAK,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,QAAM,KAAK,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,QAAM,KAAK,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,SAAO,GAAG,EAAE,KAAK,EAAE,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AACtD;AAOA,SAAS,WAAW,OAAyE;AAC3F,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,cAAc,YAAY;AACtC,UAAM,OAAO,EAAE,UAAU;AAIzB,QAAI,OAAQ,KAAuC,qBAAqB,UAAU;AAChF,aAAO,EAAE,mBAAmB,KAAK,mBAAmB,kBAAmB,KAAsC,iBAAiB;AAAA,IAChI;AACA,WAAO,EAAE,mBAAmB,KAAK,mBAAmB,kBAAkB,OAAO,KAAK,iBAAiB,IAAI,SAAW;AAAA,EACpH;AAMA,MAAI,OAAO,GAAG,qBAAqB,UAAU;AAC3C,WAAO,EAAE,mBAAmB,OAAO,EAAE,mBAAmB,QAAU,GAAG,kBAAkB,EAAE,iBAAiB;AAAA,EAC5G;AACA,MAAI,OAAO,GAAG,sBAAsB,UAAU;AAC5C,WAAO,EAAE,mBAAmB,EAAE,mBAAmB,kBAAkB,OAAO,EAAE,iBAAiB,IAAI,SAAW;AAAA,EAC9G;AACA,QAAM,IAAI,kBAAkB,EAAE,QAAQ,6CAA6C,OAAO,KAAK,IAAI,CAAC;AACtG;AAEA,SAAS,iBAA4D;AACnE,QAAM,IAAI,YAAY,EAAE;AACxB,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,yEAAyE;AACjG,SAAO;AACT;AAEO,SAAS,cAAc,OAAwB;AACpD,SAAO,WAAW,KAAK,EAAE,oBAAoB;AAC/C;AAEO,SAAS,gBAAgB,SAA0B;AACxD,SAAO,eAAe,EAAE,sBAAsB,UAAU,GAAI;AAC9D;AAEO,SAAS,qBAAqB,IAAqB;AACxD,SAAO,eAAe,EAAE,sBAAsB,EAAE;AAClD;AAEO,SAAS,qBAAqB,SAAqB;AAGxD,SAAO,eAAe,EAAE,qBAAqB,OAAO,OAAE,IAAI,KAAM;AAClE;AAEO,SAAS,oBAAoB,IAAqB;AACvD,SAAO,eAAe,EAAE,qBAAqB,EAAE;AACjD;AAEO,SAAS,mBAAmB,OAAwB;AACzD,SAAO,WAAW,KAAK,EAAE;AAC3B;AAEO,SAAS,mBAAmB,OAAwB;AACzD,QAAM,EAAE,iBAAiB,IAAI,WAAW,KAAK;AAC7C,SAAO,OAAO,mBAAmB,KAAM;AACzC;AAEO,SAAS,kBAAkB,OAAwB;AACxD,SAAO,WAAW,KAAK,EAAE;AAC3B;AAOO,SAAS,SAAS,OAAwB;AAC/C,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,YAAY,aAAa;AAC/B,MAAI,sBAAsB,KAAK,OAAO,GAAG;AACvC,WAAO,UAAU,cAAc,OAAO;AAAA,EACxC;AACA,MAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,WAAO,UAAU,uBAAuB,OAAO;AAAA,EACjD;AACA,MAAI,uCAAuC,KAAK,OAAO,GAAG;AACxD,WAAO,SAAS,OAAO;AAAA,EACzB;AACA,QAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,wCAAwC,CAAC;AACxF;AAEO,SAAS,UAAU,OAAwB;AAEhD,QAAM,IAAI;AACV,QAAM,aAAa,cAAc;AACjC,MAAI,OAAO,GAAG,SAAS,UAAU;AAC/B,WAAO,WAAW,OAAuC,qBAAqB;AAAA,EAChF;AACA,SAAO,WAAW,OAAuC,YAAY;AACvE;;;AC9WA,IAAM,iBAA4C;AAAA,EAChD,GAAG,EAAE,cAAc,QAAQ,YAAY,SAAS,eAAe,MAAM,aAAa,OAAO,OAAO,SAAS,UAAU,OAAO;AAAA,EAC1H,GAAG,EAAE,cAAc,SAAS,YAAY,UAAU,eAAe,MAAM,aAAa,OAAO,OAAO,UAAU,UAAU,QAAQ;AAAA,EAC9H,GAAG,EAAE,cAAc,QAAQ,YAAY,SAAS,eAAe,MAAM,aAAa,OAAO,OAAO,SAAS,UAAU,OAAO;AAAA,EAC1H,GAAG,EAAE,cAAc,OAAO,YAAY,QAAQ,eAAe,KAAK,aAAa,KAAK,OAAO,QAAQ,UAAU,MAAM;AAAA,EACnH,GAAG,EAAE,cAAc,QAAQ,YAAY,SAAS,eAAe,KAAK,aAAa,KAAK,OAAO,SAAS,UAAU,OAAO;AAAA,EACvH,GAAG,EAAE,cAAc,UAAU,YAAY,WAAW,eAAe,KAAK,aAAa,KAAK,OAAO,WAAW,UAAU,SAAS;AAAA,EAC/H,GAAG,EAAE,cAAc,UAAU,YAAY,WAAW,eAAe,KAAK,aAAa,KAAK,OAAO,WAAW,UAAU,SAAS;AAAA,EAC/H,GAAG,EAAE,cAAc,eAAe,YAAY,gBAAgB,eAAe,MAAM,aAAa,MAAM,OAAO,gBAAgB,UAAU,cAAc;AACvJ;AAOA,IAAM,yBAAyB,OAAO,KAAK,cAAc,EACtD,QAAQ,CAAC,WAAW,CAAC,SAAS,SAAS,QAAQ,SAAS,QAAQ,MAAM,CAAC,EACvE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAUrC,SAAS,iBAAiBC,SAAyB;AACjD,QAAM,SAAkB,CAAC;AACzB,MAAI,IAAI;AACR,SAAO,IAAIA,QAAO,QAAQ;AACxB,UAAM,KAAKA,QAAO,CAAC;AACnB,QAAI,OAAO,KAAK;AACd,UAAIA,QAAO,IAAI,CAAC,MAAM,KAAK;AACzB,QAAAC,eAAc,QAAQ,GAAG;AACzB,aAAK;AACL;AAAA,MACF;AACA,UAAI,IAAI,IAAI;AACZ,UAAI,UAAU;AACd,UAAI,SAAS;AACb,aAAO,IAAID,QAAO,QAAQ;AACxB,YAAIA,QAAO,CAAC,MAAM,KAAK;AACrB,cAAIA,QAAO,IAAI,CAAC,MAAM,KAAK;AACzB,uBAAW;AACX,iBAAK;AACL;AAAA,UACF;AACA,mBAAS;AACT,eAAK;AACL;AAAA,QACF;AACA,mBAAWA,QAAO,CAAC;AACnB,aAAK;AAAA,MACP;AACA,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,+DAA+DA,OAAM,GAAG;AAAA,MAC1F;AACA,MAAAC,eAAc,QAAQ,OAAO;AAC7B,UAAI;AACJ;AAAA,IACF;AACA,UAAM,QAAQ,uBAAuB,KAAK,CAAC,QAAQD,QAAO,WAAW,KAAK,CAAC,CAAC;AAC5E,QAAI,OAAO;AAET,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,OAAO,MAAM,WAAW,IAAI,YAAY,MAAM,WAAW,IAAI,UAAU;AAC7E,aAAO,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,MAAM,KAAK,CAAC;AACvD,WAAK,MAAM;AACX;AAAA,IACF;AACA,IAAAC,eAAc,QAAQ,EAAE;AACxB,SAAK;AAAA,EACP;AACA,SAAO;AACT;AAEA,SAASA,eAAc,QAAiB,OAAqB;AAC3D,QAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,MAAI,QAAQ,KAAK,SAAS,WAAW;AACnC,SAAK,SAAS;AAAA,EAChB,OAAO;AACL,WAAO,KAAK,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,EACxC;AACF;AAOA,SAAS,SAAS,UAAmC,OAAwB;AAC3E,QAAM,QAAQ,SAAS,KAAK;AAC5B,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAIhE,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,OAAO,SAAS,OAAO,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR,iCAAiC,KAAK,iCAAiC,OAAO,KAAK,CAAC;AAAA,IACtF;AAAA,EACF;AACA,SAAO;AACT;AAQA,IAAM,qBAAqB,oBAAI,IAA+B;AAC9D,IAAM,gCAAgC;AAEtC,SAAS,iBAAiB,QAAgB,UAAkB,aAAkD;AAC5G,QAAM,MAAM,GAAG,kBAAkB,MAAM,CAAC,IAAI,QAAQ,IAAI,WAAW;AACnE,QAAM,SAAS,mBAAmB,IAAI,GAAG;AACzC,MAAI,OAAQ,QAAO;AACnB,MAAI,mBAAmB,QAAQ,+BAA+B;AAC5D,UAAM,YAAY,mBAAmB,KAAK,EAAE,KAAK,EAAE;AACnD,QAAI,cAAc,OAAW,oBAAmB,OAAO,SAAS;AAAA,EAClE;AACA,MAAI;AACJ,MAAI;AACF,gBAAY,IAAI,KAAK,aAAa,mBAAmB,MAAM,GAAG;AAAA,MAC5D,OAAO;AAAA,MACP,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AAMZ,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAS,IAAc,QAAQ,CAAC;AAAA,EACjF;AACA,qBAAmB,IAAI,KAAK,SAAS;AACrC,SAAO;AACT;AAqCO,SAAS,eACd,UACA,WACA,UAAiC,CAAC,GAC1B;AACR,SAAO,qBAAqB,UAAU,WAAW,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE;AACvF;AAkBO,SAAS,qBACd,UACA,WACA,UAAiC,CAAC,GACT;AACzB,MAAI,UAAU,SAAS,mBAAmB;AACxC,UAAM,IAAI;AAAA,MACR,kEAAkE,iBAAiB,oBAC3E,UAAU,MAAM;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ,mBAAmB;AAO9C,QAAM,SAAS,QAAQ;AACvB,QAAM,UAAU,WAAW;AAE3B,QAAM,SAAS,iBAAiB,SAAS;AACzC,QAAM,MAA+B,CAAC;AAEtC,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,WAAW;AAC5B,UAAI,KAAK,EAAE,MAAM,WAAW,OAAO,MAAM,MAAM,CAAC;AAChD;AAAA,IACF;AAEA,UAAM,OAAO,eAAe,MAAM,IAAI;AAOtC,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,yCAAyC,MAAM,KAAK,GAAG;AAAA,IACzE;AAGA,UAAM,QAAQ,SAAS,UAAU,KAAK,KAAK;AAC3C,QAAI,UAAU,KAAK,CAAC,YAAY;AAM9B,UAAI,KAAK,EAAE,MAAM,SAAS,OAAO,IAAI,OAAO,MAAM,MAAM,CAAC;AACzD;AAAA,IACF;AAEA,QAAI,MAAM,SAAS,WAAW;AAC5B,UAAI,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,KAAK,GAAG,OAAO,MAAM,MAAM,CAAC;AACpE;AAAA,IACF;AAEA,QAAI,SAAS;AAKX,YAAM,cAAc,MAAM,SAAS,UAAU,UAAU;AACvD,YAAM,YAAY,iBAAiB,QAAS,KAAK,UAAU,WAAW;AACtE,UAAI,KAAK,EAAE,MAAM,SAAS,OAAO,UAAU,OAAO,KAAK,GAAG,OAAO,MAAM,MAAM,CAAC;AAC9E;AAAA,IACF;AAMA,QAAI,MAAM,SAAS,SAAS;AAC1B,UAAI,KAAK,EAAE,MAAM,SAAS,OAAO,SAAS,UAAU,KAAK,UAAU,KAAK,KAAK,gBAAgB,KAAK,cAAc,OAAO,MAAM,MAAM,CAAC;AAAA,IACtI,OAAO;AACL,UAAI,KAAK,EAAE,MAAM,SAAS,OAAO,QAAQ,OAAO,UAAU,KAAK,UAAU,KAAK,KAAK,eAAe,KAAK,aAAa,OAAO,MAAM,MAAM,CAAC;AAAA,IAC1I;AAAA,EACF;AAEA,SAAO;AACT;;;ACjSO,SAAS,sBACd,UACA,WACA,UAAgD,CAAC,GACjC;AAChB,SAAO,qBAAqB,UAAU,WAAW,OAAO,EAAE;AAAA,IAAI,CAAC,MAC7D,EAAE,SAAS,UAAU,EAAE,MAAM,SAAkB,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM,IAAI,EAAE,MAAM,WAAoB,OAAO,EAAE,MAAM;AAAA,EAC/H;AACF;AAKO,SAAS,iBAAiB,OAA+B;AAM9D,QAAM,KAAK;AACX,QAAM,IAAI,GAAG,KAAK,KAAK;AACvB,MAAI,CAAC,GAAG;AACN,UAAM,IAAI,qBAAqB,EAAE,OAAO,QAAQ,+EAA+E,CAAC;AAAA,EAClI;AAEA,MAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,MAAS,GAAG;AAC5C,UAAM,IAAI,qBAAqB,EAAE,OAAO,QAAQ,uDAAuD,CAAC;AAAA,EAC1G;AACA,QAAM,QAAQ,CAAC,MAAkC,MAAM,SAAY,IAAI,OAAO,CAAC;AAG/E,QAAM,SAAS,CAAC,MAAsB,EAAE,CAAC,MAAM,OAAO,MAAM,IAAI,CAAC,IAAI;AACrE,SAAO;AAAA,IACL,OAAO,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IACzB,QAAQ,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IAC1B,OAAO,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IACzB,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IACxB,OAAO,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IACzB,SAAS,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IAC3B,SAAS,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,EAC7B;AACF;AAEO,SAAS,kBAAkB,UAAkC;AAOlE,QAAM,YAAY,SAAS,SAAS,KAAK,MAAM,SAAS,UAAU,KAAK,MAAM,SAAS,SAAS,KAAK,MAC9F,SAAS,QAAQ,KAAK,MAAM,SAAS,SAAS,KAAK,MAAM,SAAS,WAAW,KAAK,MAClF,SAAS,WAAW,KAAK;AAC/B,QAAM,OAAO,WAAW,MAAM;AAC9B,QAAM,QAAQ,KAAK,IAAI,SAAS,SAAS,CAAC;AAC1C,QAAM,SAAS,KAAK,IAAI,SAAS,UAAU,CAAC;AAC5C,QAAM,QAAQ,KAAK,IAAI,SAAS,SAAS,CAAC;AAC1C,QAAM,OAAO,KAAK,IAAI,SAAS,QAAQ,CAAC;AACxC,QAAM,QAAQ,KAAK,IAAI,SAAS,SAAS,CAAC;AAC1C,QAAM,UAAU,KAAK,IAAI,SAAS,WAAW,CAAC;AAC9C,QAAM,UAAU,KAAK,IAAI,SAAS,WAAW,CAAC;AAC9C,QAAM,QAAkB,CAAC,GAAG,IAAI,GAAG;AACnC,MAAI,MAAO,OAAM,KAAK,GAAG,KAAK,GAAG;AACjC,MAAI,OAAQ,OAAM,KAAK,GAAG,MAAM,GAAG;AACnC,MAAI,MAAO,OAAM,KAAK,GAAG,KAAK,GAAG;AACjC,MAAI,KAAM,OAAM,KAAK,GAAG,IAAI,GAAG;AAC/B,MAAI,SAAS,WAAW,SAAS;AAC/B,UAAM,KAAK,GAAG;AACd,QAAI,MAAO,OAAM,KAAK,GAAG,KAAK,GAAG;AACjC,QAAI,QAAS,OAAM,KAAK,GAAG,OAAO,GAAG;AACrC,QAAI,QAAS,OAAM,KAAK,GAAG,OAAO,GAAG;AAAA,EACvC;AAGA,MAAI,MAAM,WAAW,EAAG,OAAM,KAAK,IAAI;AACvC,SAAO,MAAM,KAAK,EAAE;AACtB;AAIA,SAAS,uBAAuB,WAAqD;AACnF,QAAMC,0BAAyB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,EACnE,QAAQ,CAAC,WAAW,CAAC,SAAS,SAAS,QAAQ,SAAS,QAAQ,MAAM,CAAC,EACvE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACrC,QAAM,SAA2C,CAAC;AAClD,MAAI,IAAI;AACR,SAAO,IAAI,UAAU,QAAQ;AAC3B,UAAM,KAAK,UAAU,CAAC;AACtB,QAAI,OAAO,KAAK;AACd,UAAI,UAAU,IAAI,CAAC,MAAM,KAAK;AAC5B,QAAAC,eAAc,QAAQ,GAAG;AACzB,aAAK;AACL;AAAA,MACF;AACA,UAAI,IAAI,IAAI;AACZ,UAAI,UAAU;AACd,UAAI,SAAS;AACb,aAAO,IAAI,UAAU,QAAQ;AAC3B,YAAI,UAAU,CAAC,MAAM,KAAK;AACxB,cAAI,UAAU,IAAI,CAAC,MAAM,KAAK;AAC5B,uBAAW;AACX,iBAAK;AACL;AAAA,UACF;AACA,mBAAS;AACT,eAAK;AACL;AAAA,QACF;AACA,mBAAW,UAAU,CAAC;AACtB,aAAK;AAAA,MACP;AACA,UAAI,CAAC,OAAQ,OAAM,IAAI,kBAAkB,EAAE,QAAQ,WAAW,QAAQ,qBAAqB,CAAC;AAC5F,MAAAA,eAAc,QAAQ,OAAO;AAC7B,UAAI;AACJ;AAAA,IACF;AACA,UAAM,QAAQD,wBAAuB,KAAK,CAAC,QAAQ,UAAU,WAAW,KAAK,CAAC,CAAC;AAC/E,QAAI,OAAO;AACT,aAAO,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,MAAM,MAAM,CAAC,EAAE,CAAC;AAC3D,WAAK,MAAM;AACX;AAAA,IACF;AACA,IAAAC,eAAc,QAAQ,EAAE;AACxB,SAAK;AAAA,EACP;AACA,SAAO;AACT;AAEA,SAASA,eAAc,QAA0C,OAAqB;AACpF,QAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,MAAI,QAAQ,KAAK,SAAS,WAAW;AACnC,SAAK,SAAS;AAAA,EAChB,OAAO;AACL,WAAO,KAAK,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,EACxC;AACF;AAgCO,SAAS,cAAc,OAAe,WAAmB,UAA+B,CAAC,GAAmB;AAGjH,QAAM,SAAS,uBAAuB,SAAS;AAC/C,QAAM,SAAyB,CAAC;AAChC,QAAM,aAAwF,CAAC;AAC/F,MAAI,QAAQ;AACZ,aAAW,OAAO,QAAQ;AACxB,QAAI,IAAI,SAAS,WAAW;AAC1B,eAAS,IAAI,MAAM,QAAQ,uBAAuB,MAAM;AAAA,IAC1D,OAAO;AACL,YAAM,OAAO,IAAI;AACjB,YAAM,OAAO,IAAI,MAAM,WAAW,IAAI,YAAY,IAAI,MAAM,WAAW,IAAI,UAAU;AAAA,MAErF;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,YAAM,MACJ,SAAS,MAAM,UACb,SAAS,MAAM,WACf,SAAS,MAAM,UACf,SAAS,MAAM,SACf,SAAS,MAAM,UACf,SAAS,MAAM,YACf,SAAS,MAAM,YACf,SAAS,MAAM,iBACf;AAEJ,UAAI,QAAQ,MAAM;AAChB,cAAM,IAAI,kBAAkB,EAAE,QAAQ,WAAW,OAAO,IAAI,OAAO,QAAQ,yBAAyB,CAAC;AAAA,MACvG;AAAA,MACA;AAIA,UAAI,SAAS,WAAW;AACtB,iBAAS;AAAA,MACX,OAAO;AAGL,iBAAS;AAAA,MACX;AACA,iBAAW,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,IACrC;AAAA,EACF;AACA,QAAM,KAAK,IAAI,OAAO,IAAI,KAAK,KAAK,GAAG;AACvC,QAAM,IAAI,GAAG,KAAK,KAAK;AACvB,MAAI,CAAC,GAAG;AACN,UAAM,IAAI,kBAAkB,EAAE,OAAO,QAAQ,WAAW,QAAQ,iCAAiC,CAAC;AAAA,EACpG;AACA,aAAW,QAAQ,CAAC,MAAM,MAAM;AAC9B,UAAM,MAAM,EAAE,IAAI,CAAC;AACnB,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,YAAM,IAAI,qBAAqB,EAAE,OAAO,QAAQ,aAAa,KAAK,IAAI,aAAa,GAAG,8BAA8B,CAAC;AAAA,IACvH;AACA,WAAO,KAAK,IAAI,IAAI;AAAA,EACtB,CAAC;AACD,SAAO;AACT;AAMO,SAAS,gBAAgB,UAA0C;AACxE,QAAM,SAAgD;AAAA,IACpD,CAAC,QAAQ,SAAU,WAAc;AAAA,IACjC,CAAC,SAAS,QAAS,WAAc;AAAA,IACjC,CAAC,WAAW,MAAM,WAAc;AAAA,IAChC,CAAC,WAAW,WAAc;AAAA,IAC1B,CAAC,gBAAgB,QAAU;AAAA,IAC3B,CAAC,gBAAgB,KAAM;AAAA,IACvB,CAAC,eAAe,EAAE;AAAA,EACpB;AAEA,MAAI,UAAU;AACd,aAAW,CAAC,GAAG,KAAK,KAAK,QAAQ;AAC/B,UAAM,IAAI,SAAS,CAAC;AACpB,QAAI,OAAO,MAAM,SAAU,YAAW,UAAU,GAAG,OAAO,CAAC;AAAA,EAC7D;AAEA,QAAM,SAAyB,EAAE,GAAG,SAAS;AAC7C,MAAI,YAAY;AAChB,aAAW,CAAC,GAAG,KAAK,KAAK,QAAQ;AAC/B,UAAM,QAAQ,YAAY;AAC1B,iBAAa,QAAQ;AACrB,WAAO,CAAC,IAAI,OAAO,KAAK;AAAA,EAC1B;AACA,SAAO;AACT;AAKO,SAAS,cAAc,UAA0B,MAA0G;AAChK,QAAM,SAAiC;AAAA,IACrC,MAAM,SAAU;AAAA,IAChB,OAAO,QAAS;AAAA,IAChB,SAAS,MAAM;AAAA,IACf,SAAS;AAAA,IACT,cAAc;AAAA,IACd,cAAc;AAAA,IACd,aAAa;AAAA,EACf;AACA,MAAI,UAAU;AACd,aAAW,KAAK,OAAO,KAAK,MAAM,GAAiC;AACjE,UAAM,IAAI,SAAS,CAAyB;AAC5C,QAAI,OAAO,MAAM,SAAU,YAAW,UAAU,GAAG,OAAO,CAAC,GAAI,CAAC;AAAA,EAClE;AACA,QAAM,UAAU,OAAO,IAAI;AAC3B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,qBAAqB,EAAE,QAAQ,0CAA0C,IAAI,6CAA6C,CAAC;AAAA,EACvI;AACA,SAAO,OAAO,OAAO,IAAI,OAAO,OAAO;AACzC;AAGO,SAAS,gBAAgB,GAAmB,GAA2B;AAC5E,QAAM,MAAM,gBAAgB,CAAC;AAC7B,QAAM,MAAM,gBAAgB,CAAC;AAC7B,MAAI,MAAM,IAAK,QAAO;AACtB,MAAI,MAAM,IAAK,QAAO;AACtB,SAAO;AACT;AAEA,SAAS,gBAAgB,GAA2B;AAClD,QAAM,SAAiC;AAAA,IACrC,MAAM,SAAU;AAAA,IAChB,OAAO,QAAS;AAAA,IAChB,SAAS,MAAM;AAAA,IACf,SAAS;AAAA,IACT,cAAc;AAAA,IACd,cAAc;AAAA,IACd,aAAa;AAAA,EACf;AACA,MAAI,QAAQ;AACZ,aAAW,KAAK,OAAO,KAAK,MAAM,GAAG;AACnC,UAAM,IAAI,EAAE,CAAyB;AACrC,QAAI,OAAO,MAAM,SAAU,UAAS,UAAU,GAAG,OAAO,CAAC,GAAI,CAAC;AAAA,EAChE;AACA,SAAO;AACT;AAIO,SAAS,YAAY,GAAmB,GAAmC;AAChF,QAAM,OAAoC,CAAC,SAAS,UAAU,SAAS,QAAQ,SAAS,WAAW,WAAW,gBAAgB,gBAAgB,aAAa;AAC3J,QAAM,SAAyB,CAAC;AAChC,aAAW,KAAK,MAAM;AACpB,WAAO,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,KAAK;AAAA,EACrC;AACA,SAAO;AACT;AAEO,SAAS,iBAAiB,GAAmB,GAAmC;AACrF,SAAO,YAAY,GAAG,eAAe,CAAC,CAAC;AACzC;AAEA,SAAS,eAAe,GAAmC;AACzD,QAAM,SAAyB,CAAC;AAChC,aAAW,KAAK,OAAO,KAAK,CAAC,GAAkC;AAC7D,WAAO,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK;AAAA,EACxB;AACA,SAAO;AACT;;;ACxUA,IAAM,iBAAiB,oBAAI,IAAiC;AAC5D,IAAMC,yBAAwB;AAC9B,IAAM,0BAA0B;AAEhC,SAAS,aAAa,QAAwB;AAC5C,MAAI;AACF,WAAO,IAAI,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC,EAAE,SAAS,EAAE,YAAY;AAAA,EAC3E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,QAAgB,OAAkC;AAC/E,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;AACrD,UAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,MAAM,GAAG,QAAQ,kCAAkC,CAAC;AAAA,EACpG;AACA,MAAI,OAAO,SAASA,wBAAuB;AACzC,UAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,OAAO,MAAM,GAAG,QAAQ,8BAA8BA,sBAAqB,cAAc,CAAC;AAAA,EAC1I;AAGA,sBAAoB,QAAQ,KAAK;AAEjC,mBAAiB,OAAO,MAAM;AAC9B,QAAM,MAAM,aAAa,MAAM;AAC/B,iBAAe,IAAI,KAAK,EAAE,GAAG,MAAM,CAAC;AACtC;AAEA,SAAS,iBAAiB,OAA4B,QAAsB;AAC1E,QAAM,aAAa,CAAC,KAAc,KAAa,WAAmB;AAChE,QAAI,QAAQ,OAAW;AACvB,QAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACvB,YAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,GAAG,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAAA,IAC/G;AACA,QAAI,IAAI,WAAW,QAAQ;AACzB,YAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,IAAI,MAAM,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,eAAe,MAAM,iBAAiB,IAAI,MAAM,IAAI,CAAC;AAAA,IACrJ;AACA,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAI,OAAO,IAAI,CAAC,MAAM,YAAY,IAAI,CAAC,EAAG,WAAW,GAAG;AACtD,cAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,IAAI,CAAC,CAAC,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,IAAI,CAAC,gCAAgC,CAAC;AAAA,MAClI;AACA,UAAI,IAAI,CAAC,EAAG,SAAS,yBAAyB;AAC5C,cAAM,IAAI,mBAAmB,EAAE,QAAQ,OAAO,IAAI,CAAC,EAAG,MAAM,GAAG,QAAQ,WAAW,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,uBAAuB,cAAc,CAAC;AAAA,MACrK;AAAA,IACF;AAAA,EACF;AACA,aAAW,MAAM,cAAc,gBAAgB,CAAC;AAChD,aAAW,MAAM,eAAe,iBAAiB,CAAC;AAClD,aAAW,MAAM,UAAU,YAAY,CAAC;AACxC,aAAW,MAAM,WAAW,aAAa,CAAC;AAC1C,aAAW,MAAM,UAAU,YAAY,CAAC;AAC1C;AAEO,SAAS,UAAU,QAAiD;AAKzE,QAAM,MAAM,aAAa,MAAM;AAC/B,QAAM,MAAM,eAAe,IAAI,GAAG;AAClC,MAAI,IAAK,QAAO;AAEhB,MAAI;AACF,UAAM,OAAO,eAAe,MAAM;AAClC,WAAO,EAAE,GAAG,KAAK;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,UAAU,QAAyB;AACjD,QAAM,MAAM,aAAa,MAAM;AAC/B,SAAO,eAAe,IAAI,GAAG;AAC/B;;;ACrFO,IAAM,iBAA8C,OAAO,OAAO;AAAA,EACvE,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,cAAc;AAAA,EACd,wBAAwB;AAC1B,CAAC;AAWM,SAAS,aAAa,YAAwC,CAAC,GAAgC;AACpG,QAAM,SAA4B,EAAE,GAAG,gBAAgB,GAAG,UAAU;AAEpE,MAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,WAAW,GAAG;AACnE,UAAM,IAAI,MAAM,+DAA+D,OAAO,OAAO,MAAM,CAAC,IAAI;AAAA,EAC1G;AACA,MAAI,OAAO,oBAAoB,UAAa,OAAO,OAAO,oBAAoB,UAAU;AACtF,UAAM,IAAI,MAAM,8DAA8D,OAAO,OAAO,eAAe,CAAC,IAAI;AAAA,EAClH;AACA,MAAI,OAAO,mBAAmB,KAAK,OAAO,mBAAmB,GAAG;AAC9D,UAAM,IAAI,MAAM,6EAA6E,OAAO,cAAc,IAAI;AAAA,EACxH;AACA,MAAI,CAAC,CAAC,WAAW,SAAS,QAAQ,OAAO,EAAE,SAAS,OAAO,YAAY,GAAG;AACxE,UAAM,IAAI,MAAM,sCAAsC,OAAO,YAAY,sBAAsB;AAAA,EACjG;AACA,MAAI,CAAC,CAAC,cAAc,WAAW,SAAS,QAAQ,EAAE,SAAS,OAAO,cAAc,GAAG;AACjF,UAAM,IAAI,MAAM,wCAAwC,OAAO,cAAc,sBAAsB;AAAA,EACrG;AACA,MAAI,CAAC,CAAC,aAAa,QAAQ,EAAE,SAAS,OAAO,QAAQ,GAAG;AACtD,UAAM,IAAI,MAAM,kCAAkC,OAAO,QAAQ,sBAAsB;AAAA,EACzF;AACA,SAAO,OAAO,OAAO,MAAM;AAC7B;AAYO,SAAS,gBACd,QACA,SAC2C;AAC3C,MAAI,CAAC,OAAQ,QAAO;AAYpB,QAAM,SAA0B,CAAC;AACjC,MAAI,QAAQ,WAAW,OAAW,QAAO,SAAS,OAAO;AACzD,MAAI,QAAQ,aAAa,UAAa,OAAO,aAAa,OAAW,QAAO,WAAW,OAAO;AAC9F,MAAI,QAAQ,aAAa,UAAa,OAAO,aAAa,OAAW,QAAO,WAAW,OAAO;AAC9F,MAAI,QAAQ,oBAAoB,OAAW,QAAO,kBAAkB,OAAO;AAC3E,MAAI,QAAQ,YAAY,UAAa,OAAO,aAAc,QAAO,UAAU;AAC3E,SAAO,EAAE,GAAG,SAAS,GAAG,OAAO;AACjC;;;AC1FO,SAAS,SAAS,OAAgB,KAAc,SAAyB,UAAoB;AAElG,QAAM,MAAM,QAAQ,OAAO,GAAG;AAC9B,MAAI,MAAM,GAAG;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,KAAK,OAAO;AAC9B;AAeA,SAAS,cAAc,QAAiC;AACtD,SAAO,WAAW,YAAY,WAAW;AAC3C;AACA,SAAS,YAAY,QAAiC;AACpD,SAAO,WAAW,YAAY,WAAW;AAC3C;AAEO,SAAS,SAAS,IAAc,OAAyB;AAC9D,QAAM,WAAW,QAAQ,OAAO,GAAG,KAAK;AACxC,QAAM,SAAS,QAAQ,OAAO,GAAG,GAAG;AACpC,QAAM,aAAa,cAAc,GAAG,MAAM,IAAI,YAAY,IAAI,WAAW;AACzE,QAAM,YAAY,YAAY,GAAG,MAAM,IAAI,UAAU,IAAI,SAAS;AAClE,SAAO,cAAc;AACvB;AAKO,SAAS,SAAS,GAAa,GAAsB;AAC1D,SAAO,WAAW,GAAG,CAAC;AACxB;AAEO,SAAS,WAAW,GAAa,GAAsB;AAS5D,QAAM,QAAQ,QAAQ,EAAE,OAAO,EAAE,KAAK;AACtC,QAAM,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE;AACpC,QAAM,QAAQ,QAAQ,EAAE,KAAK,EAAE,GAAG;AAClC,QAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE;AAClC,QAAM,QAAQ,QAAQ,IAAI,EAAE;AAC5B,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,QAAQ,EAAG,QAAO;AAGtB,SAAO,SAAS,GAAG,EAAE,KAAK,SAAS,GAAG,EAAE;AAC1C;AAEO,SAASC,UAAS,GAAa,GAAsB;AAC1D,SAAO,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI;AACnC;AAEO,SAASC,SAAQ,GAAa,GAAsB;AACzD,SAAO,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI;AACnC;AAOO,SAAS,aAAa,GAAa,GAA8B;AACtE,MAAI,CAAC,WAAW,GAAG,CAAC,EAAG,QAAO;AAC9B,QAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI;AAChD,QAAM,QAAQ,cAAc,EAAE,QAAQ,EAAE;AACxC,QAAM,cAAc,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI;AAC5C,QAAM,MAAM,cAAc,EAAE,MAAM,EAAE;AAGpC,QAAM,WAAW,cACb,cAAc,EAAE,MAAM,IACtB,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,IAC1B,cAAc,EAAE,MAAM,IACtB,cAAc,EAAE,MAAM,KAAK,cAAc,EAAE,MAAM;AAGvD,QAAM,SAAS,cACX,YAAY,EAAE,MAAM,IACpB,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,IACtB,YAAY,EAAE,MAAM,IACpB,YAAY,EAAE,MAAM,KAAK,YAAY,EAAE,MAAM;AACnD,QAAM,SAAyB,WAC1B,SAAS,WAAW,kBACpB,SAAS,oBAAoB;AAClC,SAAO,EAAE,OAAO,KAAK,OAAO;AAC9B;AAOO,SAAS,MAAM,GAAa,GAA8B;AAC/D,MAAI,CAAC,WAAW,GAAG,CAAC,EAAG,QAAO;AAC9B,QAAM,gBAAgB,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI;AAClD,QAAM,QAAQ,gBAAgB,EAAE,QAAQ,EAAE;AAC1C,QAAM,YAAY,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI;AAC1C,QAAM,MAAM,YAAY,EAAE,MAAM,EAAE;AAClC,QAAM,WAAW,gBACb,cAAc,EAAE,MAAM,IACtB,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,IAC1B,cAAc,EAAE,MAAM,IACtB,cAAc,EAAE,MAAM,KAAK,cAAc,EAAE,MAAM;AACvD,QAAM,SAAS,YACX,YAAY,EAAE,MAAM,IACpB,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,IACtB,YAAY,EAAE,MAAM,IACpB,YAAY,EAAE,MAAM,KAAK,YAAY,EAAE,MAAM;AACnD,QAAM,SAAyB,WAC1B,SAAS,WAAW,kBACpB,SAAS,oBAAoB;AAClC,SAAO,EAAE,OAAO,KAAK,OAAO;AAC9B;AAYO,SAAS,WAAW,GAAa,GAAyB;AAC/D,MAAI,CAAC,WAAW,GAAG,CAAC,EAAG,QAAO,CAAC,CAAC;AAChC,QAAM,SAAqB,CAAC;AAM5B,MAAI,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG;AACjC,UAAM,SAAS,SAAS,GAAG,EAAE,KAAK,KAAK,CAAC,SAAS,GAAG,EAAE,KAAK;AAC3D,WAAO,KAAK;AAAA,MACV,OAAO,EAAE;AAAA,MACT,KAAK,EAAE;AAAA,MACP,QAAQ,cAAc,EAAE,MAAM,IACzB,SAAS,WAAW,kBACpB,SAAS,oBAAoB;AAAA,IACpC,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG;AAC7B,UAAM,WAAW,SAAS,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,EAAE,GAAG;AACzD,WAAO,KAAK;AAAA,MACV,OAAO,EAAE;AAAA,MACT,KAAK,EAAE;AAAA,MACP,QAAQ,WACH,YAAY,EAAE,MAAM,IAAI,WAAW,kBACnC,YAAY,EAAE,MAAM,IAAI,oBAAoB;AAAA,IACnD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAIO,IAAM,WAAW;AAQjB,SAAS,eAAe,WAAmC;AAChE,MAAI,UAAU,WAAW,EAAG,QAAO,CAAC;AACpC,QAAM,SAAS,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,GAAG,MAAM,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC;AAMtE,QAAM,SAAqB,CAAC,EAAE,GAAG,OAAO,CAAC,EAAG,CAAC;AAC7C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,UAAU,OAAO,CAAC;AACxB,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AAKrC,UAAM,WAAW,QAAQ,KAAK,KAAK,QAAQ,KAAK,MAAM;AACtD,UAAM,cAAc,aAAa,YAAY,KAAK,MAAM,KAAK,cAAc,QAAQ,MAAM;AACzF,QAAI,WAAW,MAAM,OAAO,KAAK,aAAa;AAI5C,YAAM,SAAS,QAAQ,QAAQ,KAAK,KAAK,GAAG;AAC5C,UAAI,SAAS,GAAG;AACd,aAAK,MAAM,QAAQ;AACnB,aAAK,SAAS,cAAc,KAAK,MAAM,IAClC,YAAY,QAAQ,MAAM,IAAI,WAAW,kBACzC,YAAY,QAAQ,MAAM,IAAI,oBAAoB;AAAA,MACzD,WAAW,WAAW,GAAG;AACvB,aAAK,SAAS,cAAc,KAAK,MAAM,IAClC,YAAY,KAAK,MAAM,KAAK,YAAY,QAAQ,MAAM,IAAI,WAAW,kBACrE,YAAY,KAAK,MAAM,KAAK,YAAY,QAAQ,MAAM,IAAI,oBAAoB;AAAA,MACrF;AAAA,IACF,OAAO;AACL,aAAO,KAAK,EAAE,GAAG,QAAQ,CAAC;AAAA,IAC5B;AAAA,EACF;AACA,SAAO;AACT;AAOA,IAAM,cAAc;AAOb,SAAS,cAAc,IAAc,GAAuB;AACjE,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,mDAAmD,CAAC,IAAI;AACpF,MAAI,MAAM,EAAG,QAAO,CAAC,EAAE;AACvB,QAAM,cAAc,gBAAgB,GAAG,KAAK;AAC5C,QAAM,YAAY,gBAAgB,GAAG,GAAG;AACxC,QAAM,UAAUC,MAAK,WAAW;AAChC,QAAM,QAAQA,MAAK,SAAS;AAC5B,MAAI,KAAK,IAAI,OAAO,IAAI,eAAe,KAAK,IAAI,KAAK,IAAI,aAAa;AACpE,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,QAAM,QAAQ,QAAQ,WAAW;AACjC,QAAM,SAAqB,CAAC;AAU5B,QAAM,aAAa,cAAc,GAAG,MAAM;AAC1C,QAAM,WAAW,YAAY,GAAG,MAAM;AACtC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,aAAa,UAAU,IAAI;AACjC,UAAM,WAAW,MAAM,IAAI,IAAI,QAAQ,aAAa;AACpD,UAAM,WAAW,MAAM,IAAI,aAAa;AACxC,UAAM,SAAS,MAAM,IAAI,IAAI,WAAW;AACxC,WAAO,KAAK;AAAA,MACV,OAAOC,QAAO,YAAY,WAAW;AAAA,MACrC,KAAKA,QAAO,UAAU,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQ/B,QAAQ,WACH,SAAS,WAAW,kBACpB,SAAS,oBAAoB;AAAA,IACpC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAASD,MAAK,GAAsG;AAOlH,QAAM,OAAO,cAAc,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI;AACpD,SAAO,OAAO,SACT,EAAE,QAAQ,KAAK,QACf,EAAE,UAAU,KAAK,OACjB,EAAE,UAAU,KAAK,OACjB,EAAE,eAAe;AACxB;AAEA,SAASC,QAAO,IAAY,MAAgH;AAC1I,QAAMC,cAAa;AACnB,QAAM,cAAc,KAAK,MAAM,KAAKA,WAAU;AAC9C,MAAI,YAAY,KAAKA;AACrB,MAAI,YAAY,EAAG,cAAaA;AAChC,QAAM,OAAO,KAAK,MAAM,YAAY,IAAS;AAC7C,QAAM,SAAS,KAAK,MAAO,YAAY,OAAa,GAAM;AAC1D,QAAM,SAAS,KAAK,MAAO,YAAY,MAAU,GAAK;AACtD,QAAM,cAAc,YAAY;AAShC,QAAM,QAAQ,cAAcA;AAC5B,QAAM,IAAI,IAAI,KAAK,KAAK;AACxB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,EAAE,eAAe;AAAA,IACvB,OAAO,EAAE,YAAY,IAAI;AAAA,IACzB,KAAK,EAAE,WAAW;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOO,SAAS,YACd,IACA,WACA,UAAyB,CAAC,GAClB;AASR,MAAI;AAKF,UAAM,CAAC,UAAU,MAAM,IAAI,oBAAoB,CAAC,GAAG,OAAO,GAAG,GAAG,GAA8C,WAAW,OAAO;AAChI,WAAO,GAAG,QAAQ,WAAM,MAAM;AAAA,EAChC,SAAS,KAAK;AAIZ,QAAI;AACF,YAAM,MAAM,IAAI,KAAK,eAAe,mBAAmB,QAAQ,UAAU,OAAO,GAAG,CAAC,CAAC;AAKrF,YAAM,YAAY,SAAS,GAAG,KAAK;AACnC,YAAM,UAAU,SAAS,GAAG,GAAG;AAC/B,aAAO,IAAI,YAAY,WAAW,OAAO;AAAA,IAC3C,QAAQ;AAGN,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,mBACd,IACA,WACA,UAAyB,CAAC,GACT;AAOjB,QAAM,aAAa,cAAc,GAAG,OAA8C,WAAW,OAAO;AACpG,QAAM,WAAW,cAAc,GAAG,KAA4C,WAAW,OAAO;AAChG,QAAM,SAA0B,CAAC,GAAG,UAAU;AAC9C,SAAO,KAAK,EAAE,MAAM,WAAW,OAAO,WAAM,CAAC;AAC7C,SAAO,KAAK,GAAG,QAAQ;AACvB,SAAO;AACT;AAEA,SAAS,SAAS,OAAsB;AACtC,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,cAAc,YAAY;AACtC,WAAO,IAAI,KAAK,EAAE,UAAU,EAAE,iBAAiB;AAAA,EACjD;AACA,MAAI,OAAO,GAAG,SAAS,YAAY,OAAO,GAAG,UAAU,YAAY,OAAO,GAAG,QAAQ,UAAU;AAC7F,WAAO,IAAI,KAAK,KAAK,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAG,EAAE,KAAK,EAAE,QAAQ,GAAG,EAAE,UAAU,GAAG,EAAE,UAAU,GAAG,EAAE,eAAe,CAAC,CAAC;AAAA,EACrH;AACA,QAAM,IAAI,MAAM,iFAAiF,OAAO,KAAK,GAAG;AAClH;;;AC/ZA,SAAS,WAAW,OAAmC;AACrD,SAAO,gBAAgB,KAAK;AAC9B;AAMA,SAASC,oBAAmB,MAA+B;AACzD,MAAI,OAAO,KAAK,cAAc,SAAU;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,MAAI,OAAO,KAAK,SAAS,YAAY,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,QAAQ,SAAU;AAAA,EACrG;AAMA,OAAK,YAAY,mBAAmB,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG;AACrE;AAQO,SAAS,IAAI,OAAgB,QAAgB,MAAkC;AACpF,QAAM,IAAI,WAAW,KAAK;AAC1B,MAAI,SAA4B,EAAE,GAAG,EAAE;AACvC,UAAQ,MAAM;AAAA,IACZ,KAAK,SAAS;AAAA,MACZ;AAAA;AAAA;AAAA;AAAA;AAKA,aAAO,QAAQ,OAAO,QAAQ,KAAK;AAAA,MACnC;AAEA,YAAM,SAAS,YAAY,EAAE,MAAM,OAAO,MAAO,OAAO,OAAO,MAAO,CAAC;AACvE,UAAI,OAAO,MAAO,OAAQ,QAAO,MAAM;AACvC,MAAAA,oBAAmB,MAAM;AACzB;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AAAA,MAQb;AAAA;AAAA;AAAA;AAIA,YAAM,SAAS,OAAO,QAAQ,KAAK,MAAM,OAAO,SAAS,KAAK,IAAI;AAAA,MAClE;AACA,aAAO,OAAO,KAAK,MAAM,QAAQ,EAAE;AACnC,aAAO,QAAQ,QAAQ,OAAO,OAAO,KAAK;AAC1C,YAAM,SAAS,YAAY,EAAE,MAAM,OAAO,MAAO,OAAO,OAAO,MAAO,CAAC;AACvE,UAAI,OAAO,MAAO,OAAQ,QAAO,MAAM;AACvC,MAAAA,oBAAmB,MAAM;AACzB;AAAA,IACF;AAAA,IACA,KAAK;AACH,eAAS,UAAU,QAAQ,SAAS,CAAC;AACrC;AAAA,IACF,KAAK;AACH,eAAS,UAAU,QAAQ,MAAM;AACjC;AAAA,IACF,KAAK;AACH,eAAS,UAAU,QAAQ,SAAS,IAAS;AAC7C;AAAA,IACF,KAAK;AACH,eAAS,UAAU,QAAQ,SAAS,GAAM;AAC1C;AAAA,IACF,KAAK;AACH,eAAS,UAAU,QAAQ,SAAS,GAAK;AACzC;AAAA,IACF,KAAK;AACH,eAAS,UAAU,QAAQ,MAAM;AACjC;AAAA,EACJ;AACA,SAAO;AACT;AAEA,SAAS,UAAU,GAAsB,MAAiC;AAUxE,QAAM,YAAY,cAAc,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI,IAAI;AAQ7D,QAAM,IAAI,YAAY;AACtB,QAAM,OAAO,KAAK,OAAO,KAAK,IAAI,IAAI,IAAI,UAAU,MAAM;AAC1D,QAAM,OAAO,IAAI,OAAO;AACxB,QAAM,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM,OAAO,IAAI,IAAI,KAAK,MAAM,OAAO,KAAK,IAAI,KAAK,MAAM,OAAO,MAAM,KAAK,GAAG;AACrH,QAAM,QAAQ,OAAO,OAAO;AAC5B,QAAM,OAAO,QAAQ,MAAM,OAAO,KAAK,MAAM,OAAO,CAAC,IAAI,KAAK,MAAM,OAAO,GAAG;AAC9E,QAAM,KAAK,KAAK,OAAO,IAAI,OAAO,KAAK,GAAG;AAC1C,QAAM,KAAK,OAAO,KAAK,OAAO,MAAM,KAAK,KAAK,CAAC,IAAI;AACnD,QAAM,QAAQ,KAAK,KAAK,KAAK,IAAI,KAAK;AACtC,QAAM,OAAO,SAAS,IAAI,QAAQ,IAAI;AAEtC,QAAM,SAA4B,EAAE,GAAG,GAAG,MAAM,MAAM,OAAO,OAAO,KAAK,GAAG;AAC5E,EAAAA,oBAAmB,MAAM;AACzB,SAAO;AACT;AAEA,SAAS,UAAU,GAAsB,SAAoC;AAM3E,QAAMC,cAAa;AACnB,QAAMC,eAAc;AACpB,QAAMC,iBAAgB;AACtB,QAAMC,iBAAgB;AAEtB,QAAM,WAAW,EAAE,QAAQ,KAAKF,gBAC3B,EAAE,UAAU,KAAKC,kBACjB,EAAE,UAAU,KAAKC,kBACjB,EAAE,eAAe,KAClB;AAGJ,QAAM,cAAc,KAAK,MAAM,UAAUH,WAAU;AACnD,MAAI,YAAY,UAAUA;AAC1B,MAAI,YAAY,GAAG;AAAE,iBAAaA;AAAA,EAAY;AAE9C,QAAM,OAAO,KAAK,MAAM,YAAYC,YAAW;AAC/C,QAAM,SAAS,KAAK,MAAO,YAAYA,eAAeC,cAAa;AACnE,QAAM,SAAS,KAAK,MAAO,YAAYA,iBAAiBC,cAAa;AACrE,QAAM,cAAc,YAAYA;AAEhC,QAAM,SAA4B,EAAE,GAAG,GAAG,MAAM,QAAQ,QAAQ,YAAY;AAC5E,MAAI,gBAAgB,GAAG;AACrB,WAAO,UAAU,QAAQ,WAAW;AAAA,EACtC;AACA,SAAO;AACT;AAEO,SAASC,UAAS,OAAgB,QAAgB,MAAkC;AACzF,SAAO,IAAI,OAAO,CAAC,QAAQ,IAAI;AACjC;AASO,IAAM,WAAW,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,OAAO;AAC7D,IAAM,YAAY,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,QAAQ;AAC/D,IAAM,WAAW,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,OAAO;AAC7D,IAAMC,WAAU,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,MAAM;AAC3D,IAAM,WAAW,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,OAAO;AAC7D,IAAM,aAAa,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,SAAS;AACjE,IAAM,aAAa,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,SAAS;AACjE,IAAM,kBAAkB,CAAC,GAAY,MAAc,IAAI,GAAG,GAAG,cAAc;AAE3E,IAAM,gBAAgB,CAAC,GAAY,MAAcD,UAAS,GAAG,GAAG,OAAO;AACvE,IAAM,iBAAiB,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,QAAQ;AACzE,IAAM,gBAAgB,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,OAAO;AACvE,IAAM,eAAe,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,MAAM;AACrE,IAAM,gBAAgB,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,OAAO;AACvE,IAAM,kBAAkB,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,SAAS;AAC3E,IAAM,kBAAkB,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,SAAS;AAC3E,IAAM,uBAAuB,CAAC,GAAY,MAAcA,UAAS,GAAG,GAAG,cAAc;AASrF,SAASE,YAAW,GAAY,GAAY,MAAwB;AACzE,QAAM,KAAK,WAAW,CAAC;AACvB,QAAM,KAAK,WAAW,CAAC;AAKvB,MAAI,SAAS,SAAS;AACpB,WAAO,GAAG,OAAQ,GAAG;AAAA,EACvB;AACA,MAAI,SAAS,UAAU;AACrB,WAAQ,GAAG,OAAQ,KAAK,GAAG,QAAS,KAAM,GAAG,OAAQ,KAAK,GAAG,QAAS;AAAA,EACxE;AACA,MAAI,SAAS,WAAW,SAAS,QAAQ;AACvC,UAAM,QAAQ,WAAW,EAAE;AAC3B,UAAM,QAAQ,WAAW,EAAE;AAC3B,UAAM,OAAO,QAAQ;AACrB,WAAO,SAAS,UAAU,KAAK,MAAM,OAAO,CAAC,IAAI;AAAA,EACnD;AAGA,QAAML,eAAc;AACpB,QAAMC,iBAAgB;AACtB,QAAMC,iBAAgB;AACtB,QAAM,MAAM,UAAU,EAAE;AACxB,QAAM,MAAM,UAAU,EAAE;AACxB,QAAM,SAAS,MAAM;AACrB,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAS,aAAO,KAAK,MAAM,SAASF,YAAW;AAAA,IACpD,KAAK;AAAW,aAAO,KAAK,MAAM,SAASC,cAAa;AAAA,IACxD,KAAK;AAAW,aAAO,KAAK,MAAM,SAASC,cAAa;AAAA,IACxD,KAAK;AAAgB,aAAO;AAAA,EAC9B;AACF;AAEA,SAAS,WAAW,GAA8B;AAIhD,SAAO,cAAc,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI;AAChD;AAEA,SAAS,UAAU,GAA8B;AAC/C,QAAMH,cAAa;AACnB,QAAMC,eAAc;AACpB,QAAMC,iBAAgB;AACtB,QAAMC,iBAAgB;AACtB,SAAO,WAAW,CAAC,IAAIH,eAClB,EAAE,QAAQ,KAAKC,gBACf,EAAE,UAAU,KAAKC,kBACjB,EAAE,UAAU,KAAKC,kBACjB,EAAE,eAAe;AACxB;AAIO,IAAM,oBAAoB,CAAC,GAAY,MAAeG,YAAW,GAAG,GAAG,OAAO;AAC9E,IAAM,qBAAqB,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,QAAQ;AAChF,IAAM,oBAAoB,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,OAAO;AAC9E,IAAM,mBAAmB,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,MAAM;AAC5E,IAAM,oBAAoB,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,OAAO;AAC9E,IAAM,sBAAsB,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,SAAS;AAClF,IAAM,sBAAsB,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,SAAS;AAClF,IAAM,2BAA2B,CAAC,GAAY,MAAeA,YAAW,GAAG,GAAG,cAAc;;;AC/NnG,SAAS,cAAc,MAAc,OAAuB;AAC1D,QAAM,UAAU,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC/D,QAAM,OAAQ,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ;AACpE,SAAO,UAAU,KAAK,OAAO,KAAK,QAAQ,QAAQ,CAAC;AACrD;AAIA,SAAS,UAAU,MAAc,OAAe,KAAqB;AACnE,QAAM,OAAO,cAAc,MAAM,OAAO,GAAG;AAC3C,WAAU,OAAO,KAAK,IAAK,KAAK,IAAI;AACtC;AAKA,SAAS,cAAc,MAAc,OAAe,SAAiB,SAAgC;AACnG,QAAM,OAAO,cAAc,MAAM,KAAK;AACtC,MAAI,UAAU,GAAG;AACf,UAAM,WAAW,UAAU,MAAM,OAAO,CAAC;AACzC,UAAM,QAAQ,KAAM,UAAU,WAAW,KAAK;AAC9C,UAAMC,OAAM,SAAS,UAAU,KAAK;AACpC,WAAOA,QAAO,OAAOA,OAAM;AAAA,EAC7B;AACA,QAAM,UAAU,UAAU,MAAM,OAAO,IAAI;AAC3C,QAAM,iBAAiB,QAAS,UAAU,UAAU,KAAK;AACzD,QAAM,MAAM,kBAAkB,UAAU,KAAK;AAC7C,SAAO,OAAO,IAAI,MAAM;AAC1B;AAKO,SAAS,WAAW,OAAgB,MAA0C;AACnF,MAAI,KAAK,UAAU,WAAc,CAAC,OAAO,cAAc,KAAK,KAAK,KAAK,KAAK,QAAQ,IAAI;AACrF,UAAM,IAAI,WAAW,4EAA4E,OAAO,KAAK,KAAK,CAAC,IAAI;AAAA,EACzH;AAIA,QAAMC,YAAW,KAAK,aAAa,UAAa,KAAK,aAAa,OAC9D,KAAK,WACL;AACJ,MAAI,CAAC,OAAO,cAAcA,SAAQ,KAAKA,YAAW,GAAG;AACnD,UAAM,IAAI,WAAW,+EAA+E,OAAO,KAAK,QAAQ,CAAC,IAAI;AAAA,EAC/H;AAMA,MAAI,KAAK,cAAc,KAAK,WAAW,KAAK,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,KAAK,MAAM,KAAK,IAAI,OAAO,IAAI,EAAE,GAAG;AAC5G,UAAM,IAAI,WAAW,yFAAyF;AAAA,EAChH;AACA,MAAI,KAAK,aAAa,KAAK,UAAU,KAAK,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC,GAAG;AAC5F,UAAM,IAAI,WAAW,+FAA+F;AAAA,EACtH;AACA,MAAI,KAAK,WAAW,KAAK,QAAQ,KAAK,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,KAAK,IAAI,KAAK,IAAI,EAAE,GAAG;AACzF,UAAM,IAAI,WAAW,4EAA4E;AAAA,EACnG;AACA,MAAI,KAAK,oBAAoB,KAAK,iBAAiB,KAAK,CAAC,MACvD,CAAC,OAAO,cAAc,EAAE,OAAO,KAAK,EAAE,YAAY,KAAK,EAAE,UAAU,OAAO,EAAE,UAAU,MACtF,CAAC,OAAO,cAAc,EAAE,OAAO,KAAK,EAAE,UAAU,KAAK,EAAE,UAAU,CAAC,GAAG;AACrE,UAAM,IAAI,WAAW,oHAAoH;AAAA,EAC3I;AAGA,QAAM,UAAqB,CAAC;AAC5B,QAAM,cAAc;AACpB,MAAI,QAAQ;AACZ,MAAI,UAAU;AASd,QAAM,SAAS,gBAAgB,KAAK;AACpC,QAAM,iBAAiB,cAAc,OAAO,MAAO,OAAO,OAAQ,OAAO,GAAI;AAS7E,MAAI,UAAmB;AACvB,MAAI,KAAK,aAAa,KAAK,UAAU,SAAS,KAAK,OAAQ,MAAkC,cAAc,UAAU;AACnH,cAAU,EAAE,GAAG,QAAQ,WAAW,UAAU,OAAO,MAAO,OAAO,OAAQ,OAAO,GAAI,EAAE;AAAA,EACxF;AACA,MAAI,QAAQ;AAEZ,WAAS,QAAQ,OAAyB;AAUxC,UAAM,IAAI;AACV,QAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAAG;AAAA,MAI/C;AACA,UAAI,CAAC,KAAK,UAAU,SAAS,EAAE,aAAa,CAAC,EAAG,QAAO;AAAA,IACzD;AACA,QAAI,KAAK,oBAAoB,KAAK,iBAAiB,SAAS,MACtD,KAAK,cAAc,aAAa,KAAK,cAAc,WAAW;AAAA,MAKlE;AACA,YAAM,UAAU,CAAC,CAAC,KAAK,aAAa,KAAK,UAAU,SAAS,KAAK,KAAK,UAAU,SAAS,EAAE,aAAa,CAAC;AAAA,MACzG;AACA,YAAM,aAAa,KAAK,oBAAoB,CAAC,GAAG,KAAK,CAAC;AAAA;AAAA,QAEpD,cAAc,EAAE,QAAQ,GAAG,EAAE,SAAS,GAAG,EAAE,SAAS,EAAE,OAAO,OAAO,EAAE,OAAO;AAAA,OAAE;AACjF,UAAI,CAAC,WAAW,CAAC,UAAW,QAAO;AAAA,IACrC;AACA,QAAI,KAAK,cAAc,KAAK,WAAW,SAAS,GAAG;AAAA,MAIjD;AACA,YAAM,MAAM,EAAE,OAAO;AAAA,MACrB;AACA,YAAM,OAAO,cAAc,EAAE,QAAQ,GAAG,EAAE,SAAS,CAAC;AAAA,MAGpD;AACA,YAAM,OAAO,KAAK,cAAc,CAAC,GAAG,KAAK,CAAC,MAAO,IAAI,IAAI,MAAM,MAAM,IAAI,OAAO,MAAM,GAAI;AAC1F,UAAI,CAAC,IAAK,QAAO;AAAA,IACnB;AACA,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAAA,MAC3C;AACA,UAAI,CAAC,KAAK,QAAQ,SAAS,EAAE,SAAS,CAAC,EAAG,QAAO;AAAA,IACnD;AACA,QAAI,KAAK,WAAW,KAAK,QAAQ,KAAK,CAAC,MAAM,QAAQ,GAAG,KAAK,MAAM,CAAC,EAAG,QAAO;AAC9E,WAAO;AAAA,EACT;AAUA,MAAI,UAAqB,CAAC;AAI1B,MAAI,cAAc;AAElB,WAAS,iBAAuB;AAG9B,UAAM,IAAI;AACV;AACA,QAAI;AACJ,QAAI;AACJ,QAAI,KAAK,cAAc,WAAW;AAChC,YAAM,cAAc,OAAO,OAAQ,KAAK,OAAO,QAAS,IAAI,IAAIA;AAChE,aAAO,KAAK,MAAM,cAAc,EAAE;AAClC,eAAS,CAAC,cAAc,OAAO,KAAK,CAAC;AAAA,IACvC,OAAO;AACL,aAAO,OAAO,OAAQ,IAAIA;AAC1B,eAAS,KAAK,WAAW,KAAK,QAAQ,SAAS,IAC3C,CAAC,GAAG,KAAK,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,IACtC,CAAC,OAAO,KAAM;AAAA,IACpB;AACA,UAAM,OAA8C,CAAC;AACrD,eAAW,KAAK,QAAQ;AACtB,YAAM,OAAO,cAAc,MAAM,CAAC;AAClC,UAAI,KAAK,cAAc,KAAK,WAAW,SAAS,GAAG;AACjD,mBAAW,KAAK,KAAK,YAAY;AAC/B,gBAAM,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI;AACpC,cAAI,QAAQ,KAAK,QAAQ,KAAM,MAAK,KAAK,EAAE,OAAO,GAAG,KAAK,KAAK,CAAC;AAAA,QAClE;AAAA,MACF,WAAW,KAAK,oBAAoB,KAAK,iBAAiB,SAAS,GAAG;AACpE,mBAAW,KAAK,KAAK,kBAAkB;AACrC,gBAAM,OAAO,cAAc,MAAM,GAAG,EAAE,SAAS,EAAE,OAAO;AACxD,cAAI,SAAS,KAAM,MAAK,KAAK,EAAE,OAAO,GAAG,KAAK,KAAK,CAAC;AAAA,QACtD;AAAA,MACF,OAAO;AACL,YAAI,OAAO,OAAQ,KAAM,MAAK,KAAK,EAAE,OAAO,GAAG,KAAK,OAAO,IAAK,CAAC;AAAA,MACnE;AAAA,IACF;AACA,SAAK,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG;AACtD,cAAU,KAAK,IAAI,CAAC,EAAE,OAAO,IAAI,OAAO;AAAA,MACtC,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,UAAU,MAAM,OAAO,GAAG;AAAA,IACvC,EAAE;AAAA,EACJ;AAWA,WAAS,UAAU,OAAoD;AACrE,QAAI,YAAY;AAChB,QAAI,gBAAgB;AACpB,UAAM,UAAU,KAAK,cAAc,YAAY,CAAC,CAAC,KAAK,aAAa,KAAK,UAAU,SAAS;AAC3F,UAAM,aAAa,KAAK,cAAc,aAAa,KAAK,cAAc;AACtE,UAAM,OAAO,KAAK,cAAc,aAAa,YACzC,KAAK,cAAc,aAAa,YAChC,KAAK,cAAc,WAAW,UAC9B,KAAK,cAAc,UAAU,SAC7B;AAEJ,WAAO,MAAM;AAOX;AACA,UAAI,gBAAgB,KAAM;AASxB,gBAAQ;AACR,eAAO,EAAE,OAAO,WAAW,OAAO,MAAM;AAAA,MAC1C;AACA,UAAI,SAAS;AACX,oBAAY,IAAI,WAAW,GAAG,MAAM;AAKpC,YAAIA,YAAW,GAAG;AAChB,gBAAM,IAAI,gBAAgB,SAAS;AACnC,gBAAM,WAAW,cAAc,EAAE,MAAO,EAAE,OAAQ,EAAE,GAAI;AACxD,cAAI,KAAK,OAAO,WAAW,kBAAkB,CAAC,IAAIA,cAAa,EAAG;AAAA,QACpE;AAAA,MACF,WAAW,YAAY;AACrB,YAAI,QAAQ,WAAW,GAAG;AACxB,yBAAe;AACf,cAAI,QAAQ,WAAW,EAAG;AAAA,QAC5B;AACA,oBAAY,QAAQ,MAAM;AAI1B,YAAI,QAAQ,WAAW,KAAK,KAAK,EAAG;AAAA,MACtC,OAAO;AACL,oBAAY,IAAI,WAAWA,WAAU,IAAiC;AAAA,MACxE;AACA,UAAI,KAAK,SAAS,QAAQ,WAAW,KAAK,KAAK,IAAI,GAAG;AACpD,gBAAQ;AACR,eAAO,EAAE,OAAO,WAAW,OAAO,MAAM;AAAA,MAC1C;AACA,UAAI,QAAQ,SAAS,EAAG;AAAA,IAC1B;AACA,WAAO,EAAE,OAAO,WAAW,OAAO,KAAK;AAAA,EACzC;AAEA,WAAS,cAAc,OAAsB;AAC3C,YAAQ,KAAK,KAAK;AAClB,QAAI,QAAQ,SAAS,YAAa,SAAQ,MAAM;AAAA,EAClD;AAEA,SAAO;AAAA,IACL,OAAO;AACL,UAAI,MAAO,QAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AACjD,UAAI,SAAS;AACX,kBAAU;AACV,YAAI,QAAQ,OAAO,GAAG;AACpB;AACA,cAAI,KAAK,UAAU,UAAa,SAAS,KAAK,MAAO,SAAQ;AAC7D,cAAI,KAAK,SAAS,QAAQ,SAAS,KAAK,KAAK,IAAI,GAAG;AAClD,oBAAQ;AACR,mBAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAAA,UACxC;AAEA,wBAAc,OAAO;AACrB,iBAAO,EAAE,OAAO,SAAS,MAAM,MAAM;AAAA,QACvC;AAEA,cAAMC,YAAW,UAAU,OAAO;AAClC,YAAI,CAACA,UAAS,MAAO,QAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAC3D,kBAAUA,UAAS;AACnB;AACA,YAAI,KAAK,UAAU,UAAa,SAAS,KAAK,MAAO,SAAQ;AAC7D,sBAAc,OAAO;AACrB,eAAO,EAAE,OAAO,SAAS,MAAM,MAAM;AAAA,MACvC;AACA,YAAM,WAAW,UAAU,OAAO;AAClC,UAAI,CAAC,SAAS,MAAO,QAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAC3D,gBAAU,SAAS;AACnB;AACA,UAAI,KAAK,UAAU,UAAa,SAAS,KAAK,MAAO,SAAQ;AAC7D,oBAAc,OAAO;AACrB,aAAO,EAAE,OAAO,SAAS,MAAM,MAAM;AAAA,IACvC;AAAA,IACA,WAAW;AACT,UAAI,QAAQ,WAAW,EAAG,QAAO,EAAE,OAAO,QAAW,MAAM,KAAK;AAChE,YAAM,IAAI,QAAQ,IAAI;AACtB,aAAO,EAAE,OAAO,GAAG,MAAM,MAAM;AAAA,IACjC;AAAA,EACF;AACF;AAGO,SAAS,KAAK,MAA0B,GAAsB;AACnE,QAAM,SAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,IAAI,KAAK,KAAK;AACpB,QAAI,EAAE,KAAM;AACZ,WAAO,KAAK,EAAE,KAAK;AAAA,EACrB;AACA,SAAO;AACT;AAQA,IAAM,sBAAsB;AAI5B,IAAM,iBAAiB;AAOhB,SAAS,KAAK,MAA0B,GAAsB;AACnE,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,KAAK,gBAAgB;AACvB,YAAM,IAAI;AAAA,QACR,oDAAoD,cAAc;AAAA,MACpE;AAAA,IACF;AACA,UAAM,IAAI,KAAK,KAAK;AACpB,QAAI,EAAE,KAAM;AAAA,EACd;AACA,QAAM,SAAoB,CAAC;AAC3B,SAAO,OAAO,SAAS,qBAAqB;AAC1C,UAAM,IAAI,KAAK,KAAK;AACpB,QAAI,EAAE,KAAM,QAAO;AACnB,WAAO,KAAK,EAAE,KAAK;AAAA,EACrB;AACA,QAAM,IAAI;AAAA,IACR,kCAAkC,mBAAmB;AAAA,EAEvD;AACF;AAGO,SAAS,QAAQ,OAAgB,MAAsB,YAAqB,UAA8B;AAC/G,QAAM,OAAO,WAAW,OAAO,IAAI;AACnC,QAAM,SAAoB,CAAC;AAI3B,QAAM,gBAAgB;AACtB,MAAI,YAAY;AAChB,SAAO,MAAM;AACX,QAAI,cAAc,eAAe;AAC/B,YAAM,IAAI;AAAA,QACR,4CAA4C,aAAa;AAAA,MAE3D;AAAA,IACF;AACA,UAAM,IAAI,KAAK,KAAK;AACpB,QAAI,EAAE,KAAM;AACZ,QAAI,QAAQ,EAAE,OAAO,QAAQ,KAAK,EAAG;AACrC,QAAI,QAAQ,EAAE,OAAO,UAAU,KAAK,EAAG,QAAO,KAAK,EAAE,KAAK;AAAA,EAC5D;AACA,SAAO;AACT;AAOA,SAAS,WAAW,OAA8G;AAChI,QAAM,IAAI,uDAAuD,KAAK,MAAM,KAAK,CAAC;AAClF,MAAI,CAAC,GAAG;AACN,UAAM,IAAI;AAAA,MACR,2GAAsG,KAAK;AAAA,IAC7G;AAAA,EACF;AACA,QAAM,OAAO,OAAO,EAAE,CAAC,CAAC;AACxB,QAAM,QAAQ,OAAO,EAAE,CAAC,CAAC;AACzB,QAAM,MAAM,OAAO,EAAE,CAAC,CAAC;AACvB,MAAI,QAAQ,KAAK,QAAQ,MAAM,MAAM,KAAK,MAAM,IAAI;AAClD,UAAM,IAAI,WAAW,2DAA2D,KAAK,IAAI;AAAA,EAC3F;AACA,QAAM,OAAO,EAAE,CAAC,MAAM,SAAY,OAAO,EAAE,CAAC,CAAC,IAAI;AACjD,QAAM,SAAS,EAAE,CAAC,MAAM,SAAY,OAAO,EAAE,CAAC,CAAC,IAAI;AACnD,QAAM,SAAS,EAAE,CAAC,MAAM,SAAY,OAAO,EAAE,CAAC,CAAC,IAAI;AACnD,MAAI,SAAS,WAAc,OAAO,MAAM,SAAU,MAAM,SAAU,KAAK;AACrE,UAAM,IAAI,WAAW,2DAA2D,KAAK,IAAI;AAAA,EAC3F;AACA,SAAO,EAAE,MAAM,OAAO,KAAK,MAAM,QAAQ,OAAO;AAClD;AAMO,SAAS,WAAW,OAA+B;AACxD,QAAM,QAAQ,MAAM,KAAK,EAAE,YAAY,EAAE,QAAQ,WAAW,EAAE,EAAE,MAAM,GAAG;AACzE,QAAM,OAAuB,EAAE,WAAW,SAAS,UAAU,EAAE;AAC/D,QAAM,cAAmC,oBAAI,IAAI;AAAA,IAC/C;AAAA,IAAY;AAAA,IAAY;AAAA,IAAU;AAAA,IAAS;AAAA,IAAU;AAAA,IAAW;AAAA,EAClE,CAAC;AACD,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,KAAM;AACX,UAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,QAAI,KAAK,EAAG;AACZ,UAAM,MAAM,KAAK,MAAM,GAAG,EAAE;AAC5B,UAAM,QAAQ,KAAK,MAAM,KAAK,CAAC;AAC/B,YAAQ,KAAK;AAAA,MACX,KAAK;AACH,YAAI,CAAC,YAAY,IAAI,KAAK,GAAG;AAC3B,gBAAM,IAAI,WAAW,8CAA8C,KAAK,IAAI;AAAA,QAC9E;AACA,aAAK,YAAY,MAAM,YAAY;AACnC;AAAA,MACF,KAAK,YAAY;AACf,cAAMD,YAAW,OAAO,KAAK;AAC7B,YAAI,CAAC,OAAO,cAAcA,SAAQ,KAAKA,YAAW,GAAG;AACnD,gBAAM,IAAI,WAAW,sEAAsE,KAAK,KAAK;AAAA,QACvG;AACA,aAAK,WAAWA;AAChB;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,cAAM,QAAQ,OAAO,KAAK;AAC1B,YAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG;AAC7C,gBAAM,IAAI,WAAW,mEAAmE,KAAK,KAAK;AAAA,QACpG;AACA,aAAK,QAAQ;AACb;AAAA,MACF;AAAA,MACA,KAAK;AACH,aAAK,QAAQ,WAAW,KAAK;AAC7B;AAAA,MACF,KAAK,SAAS;AACZ,cAAM,cAAsC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE;AAC9F,cAAM,QAAkB,CAAC;AACzB,cAAM,WAA6B,CAAC;AACpC,mBAAW,KAAK,MAAM,MAAM,GAAG,GAAG;AAMhC,gBAAM,IAAI,EAAE,MAAM,6BAA6B;AAG/C,cAAI,CAAC,KAAK,YAAY,EAAE,CAAC,CAAE,MAAM,QAAW;AAC1C,kBAAM,IAAI,WAAW,0DAA0D,CAAC,IAAI;AAAA,UACtF;AACA,gBAAM,UAAU,YAAY,EAAE,CAAC,CAAE;AACjC,cAAI,EAAE,CAAC,MAAM,QAAW;AACtB,kBAAM,UAAU,OAAO,EAAE,CAAC,CAAC;AAC3B,gBAAI,CAAC,OAAO,cAAc,OAAO,KAAK,YAAY,KAAK,UAAU,OAAO,UAAU,IAAI;AACpF,oBAAM,IAAI,WAAW,sDAAsD,CAAC,IAAI;AAAA,YAClF;AACA,qBAAS,KAAK,EAAE,SAAS,QAAQ,CAAC;AAAA,UACpC,OAAO;AACL,kBAAM,KAAK,OAAO;AAAA,UACpB;AAAA,QACF;AACA,aAAK,YAAY;AACjB,YAAI,SAAS,SAAS,EAAG,MAAK,mBAAmB;AACjD;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,cAAM,SAAS,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAC1C,YAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,UAAU,GAAG,KAAK,QAAQ,KAAK,MAAM,OAAO,MAAM,EAAE,GAAG;AACtF,gBAAM,IAAI,WAAW,gEAAgE;AAAA,QACvF;AACA,aAAK,aAAa;AAClB;AAAA,MACF;AAAA,MACA,KAAK,WAAW;AACd,cAAM,SAAS,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAC1C,YAAI,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,EAAE,GAAG;AAC/E,gBAAM,IAAI,WAAW,6DAA6D;AAAA,QACpF;AACA,aAAK,UAAU;AACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,YAAY,MAA8B;AACxD,QAAM,QAAkB,CAAC,QAAQ,KAAK,UAAU,YAAY,CAAC,EAAE;AAI/D,MAAI,KAAK,aAAa,UAAa,KAAK,aAAa,EAAG,OAAM,KAAK,YAAY,KAAK,QAAQ,EAAE;AAC9F,MAAI,KAAK,UAAU,OAAW,OAAM,KAAK,SAAS,KAAK,KAAK,EAAE;AAC9D,MAAI,KAAK,UAAU,OAAW,OAAM,KAAK,SAAS,OAAO,KAAK,KAAK,CAAC,EAAE;AACtE,QAAM,gBAAwC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK;AAC9G,MAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAAG;AAC/C,UAAM,KAAK,SAAS,KAAK,UAAU,IAAI,CAAC,MAAM,cAAc,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE;AAAA,EAC1F;AACA,MAAI,KAAK,oBAAoB,KAAK,iBAAiB,SAAS,GAAG;AAC7D,UAAM,WAAW,KAAK,iBAAiB,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,OAAO,KAAK,OAAO,EAAE,OAAO,CAAC,EAAE;AAGhH,QAAI,KAAK,aAAa,KAAK,UAAU,SAAS,GAAG;AAC/C,YAAM,MAAM,SAAS,CAAC,IAAI,SAAS,CAAC,GAAG,KAAK,UAAU,IAAI,CAAC,MAAM,cAAc,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,GAAG,QAAQ,EAAE,KAAK,GAAG,CAAC;AAAA,IACzH,OAAO;AACL,YAAM,KAAK,SAAS,SAAS,KAAK,GAAG,CAAC,EAAE;AAAA,IAC1C;AAAA,EACF;AACA,MAAI,KAAK,cAAc,KAAK,WAAW,SAAS,EAAG,OAAM,KAAK,cAAc,KAAK,WAAW,KAAK,GAAG,CAAC,EAAE;AACvG,MAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,EAAG,OAAM,KAAK,WAAW,KAAK,QAAQ,KAAK,GAAG,CAAC,EAAE;AAC3F,SAAO,MAAM,KAAK,GAAG;AACvB;;;AC7jBO,SAAS,uBAAuB,UAAmC,CAAC,GAAqB;AAC9F,QAAM,UAAU,IAAI,IAAI,QAAQ,WAAW,CAAC,GAAG,CAAC,CAAC;AAMjD,QAAM,eAAuC,EAAE,GAAI,QAAQ,gBAAgB,CAAC,EAAG;AAC/E,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,QAAI,aAAa,CAAC,MAAM,QAAW;AACjC,mBAAa,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI;AAAA,IACzC;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,UAAU,IAAI,IAAI,QAAQ,YAAY,CAAC,CAAC;AAAA,EAC1C;AACF;AAEO,SAAS,cAAc,KAAuB,OAAyB;AAC5E,QAAM,IAAI;AAIV,MAAI,MAAM,EAAE;AACZ,MAAI,OAAO,EAAE,SAAS,YAAY,OAAO,EAAE,UAAU,YAAY,OAAO,EAAE,QAAQ,UAAU;AAM1F,UAAM,mBAAmB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;AAAA,EACjD;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,MAAM,+FAA+F;AAAA,EACjH;AACA,MAAI,IAAI,QAAQ,IAAI,GAAG,EAAG,QAAO;AACjC,MAAI,IAAI,YAAY,IAAI,SAAS,UAAU,KAAK,EAAG,QAAO;AAC1D,SAAO;AACT;AAEO,SAAS,gBAAgB,KAAuB,OAAyB;AAC9E,MAAI,YAAY,IAAI,OAAO,GAAG,MAAM;AAGpC,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAI,cAAc,KAAK,SAAS,EAAG,QAAO;AAC1C,gBAAY,IAAI,WAAW,GAAG,MAAM;AAAA,EACtC;AACA,QAAM,IAAI,MAAM,wIAAmI;AACrJ;AAEO,SAAS,oBAAoB,KAAuB,OAAyB;AAClF,MAAI,YAAY,IAAI,OAAO,IAAI,MAAM;AACrC,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAI,cAAc,KAAK,SAAS,EAAG,QAAO;AAC1C,gBAAY,IAAI,WAAW,IAAI,MAAM;AAAA,EACvC;AACA,QAAM,IAAI,MAAM,mGAA8F;AAChH;AAEA,IAAM,6BAA6B;AAEnC,SAAS,uBAAuB,MAAoB;AAClD,MAAI,CAAC,OAAO,cAAc,IAAI,GAAG;AAC/B,UAAM,IAAI;AAAA,MACR,uEAAuE,IAAI;AAAA,IAC7E;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,GAAY,GAAoB;AACzD,QAAM,KAAK;AACX,QAAM,KAAK;AACX,QAAM,KAAK,GAAG,OAAO,MAAQ,GAAG,QAAQ,MAAM,GAAG;AACjD,QAAM,KAAK,GAAG,OAAO,MAAQ,GAAG,QAAQ,MAAM,GAAG;AACjD,SAAO,KAAK;AACd;AAEO,SAAS,gBAAgB,KAAuB,OAAgB,MAAuB;AAC5F,yBAAuB,IAAI;AAC3B,MAAI,SAAS,EAAG,QAAO;AACvB,QAAM,OAAO,OAAO,IAAI,IAAI;AAC5B,QAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,MAAI,UAAU,4BAA4B;AACxC,UAAM,IAAI;AAAA,MACR,gDAAgD,0BAA0B;AAAA,IAC5E;AAAA,EACF;AACA,MAAI,YAAY;AAChB,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,gBAAY,OAAO,IAAI,gBAAgB,KAAK,SAAS,IAAI,oBAAoB,KAAK,SAAS;AAAA,EAC7F;AACA,SAAO;AACT;AAEO,SAAS,qBAAqB,KAAuB,OAAgB,MAAuB;AACjG,yBAAuB,IAAI;AAC3B,SAAO,gBAAgB,KAAK,OAAO,CAAC,IAAI;AAC1C;AAEO,SAAS,yBAAyB,KAAuB,GAAY,GAAoB;AAC9F,QAAM,eAAe,kBAAkB,GAAG,CAAC;AAC3C,MAAI,iBAAiB,EAAG,QAAO;AAE/B,QAAM,YAAY,eAAe,IAAI,IAAI;AACzC,MAAI,YAAY;AAChB,MAAI,QAAQ;AACZ,MAAI,gBAAgB;AAEpB,SAAO,kBAAkB,WAAW,CAAC,MAAM,GAAG;AAC5C,gBAAY,IAAI,WAAW,WAAW,MAAM;AAC5C;AACA,QAAI,gBAAgB,4BAA4B;AAC9C,YAAM,IAAI;AAAA,QACR,yDAAyD,0BAA0B;AAAA,MACrF;AAAA,IACF;AACA,QAAI,cAAc,KAAK,SAAS,EAAG,UAAS;AAAA,EAC9C;AAEA,SAAO;AACT;;;ACzHA,IAAM,yBAAyB;AAExB,SAAS,sBAAsB,OAAuC;AAE3E,QAAM,QAAQ,oBAAI,IAAkE;AAQpF,QAAM,kBAAkB;AACxB,WAAS,QAAQ,MAAc;AAC7B,QAAI,OAAO,MAAM,IAAI,IAAI;AACzB,QAAI,KAAM,QAAO;AACjB,QAAI,MAAM,QAAQ,iBAAiB;AACjC,YAAM,SAAS,MAAM,KAAK,EAAE,KAAK,EAAE;AACnC,UAAI,WAAW,OAAW,OAAM,OAAO,MAAM;AAAA,IAC/C;AACA,WAAO,MAAM,IAAI,CAAC,MAAM;AACtB,UAAI;AACJ,UAAI,EAAE,SAAS;AACb,aAAK,EAAE,QAAQ,IAAI;AAAA,MACrB,OAAO;AACL,aAAK,EAAE,OAAO,EAAE,OAAQ,KAAK,EAAE,IAAK;AAAA,MACtC;AACA,aAAO,EAAE,GAAG,IAAI,MAAM,EAAE,KAAK;AAAA,IAC/B,CAAC;AACD,UAAM,IAAI,MAAM,IAAI;AACpB,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,UAAU,OAAgB;AACxB,YAAM,IAAI;AACV,UAAI,OAAO,EAAE,SAAS,YAAY,OAAO,EAAE,UAAU,YAAY,OAAO,EAAE,QAAQ,UAAU;AAC1F,cAAM,IAAI,MAAM,8DAA8D;AAAA,MAChF;AACA,YAAM,OAAO,QAAQ,EAAE,IAAI;AAC3B,aAAO,KAAK,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG;AAAA,IAChE;AAAA,IACA,gBAAgB,OAAgB,KAAc;AAC5C,YAAM,KAAK;AACX,YAAM,KAAK;AACX,UAAI,OAAO,IAAI,SAAS,YAAY,OAAO,IAAI,SAAS,UAAU;AAChE,cAAM,IAAI,MAAM,6EAA6E;AAAA,MAC/F;AACA,UAAI,GAAG,OAAO,GAAG,OAAO,wBAAwB;AAC9C,cAAM,IAAI;AAAA,UACR,+CAA+C,GAAG,IAAI,SAAI,GAAG,IAAI,iBAC9D,sBAAsB;AAAA,QAC3B;AAAA,MACF;AACA,YAAM,SAAoB,CAAC;AAC3B,eAAS,IAAI,GAAG,MAAM,KAAK,GAAG,MAAM,KAAK;AACvC,cAAM,OAAO,QAAQ,CAAC;AACtB,mBAAW,KAAK,MAAM;AACpB,gBAAM,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,KAAK,EAAE,IAAI;AACnD,cAAI,QAAQ,MAAM,EAAE,KAAK,KAAK,QAAQ,MAAM,EAAE,KAAK,GAAG;AACpD,mBAAO,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,KAAK,EAAE,IAAI,CAAC;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,SAAS,YAAY,KAAsB,OAAqC;AACrF,MAAI,YAAY,IAAI,OAAO,GAAG,MAAM;AACpC,WAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AAChC,QAAI,IAAI,UAAU,SAAS,EAAG,QAAO;AACrC,gBAAY,IAAI,WAAW,GAAG,MAAM;AAAA,EACtC;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,KAAsB,OAAqC;AACzF,MAAI,YAAY,IAAI,OAAO,IAAI,MAAM;AACrC,WAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AAChC,QAAI,IAAI,UAAU,SAAS,EAAG,QAAO;AACrC,gBAAY,IAAI,WAAW,IAAI,MAAM;AAAA,EACvC;AACA,SAAO;AACT;AAIO,SAAS,gBAAgB,KAAsB,OAAgB,KAAyB;AAC7F,SAAO,IAAI,gBAAgB,OAAO,GAAG;AACvC;;;AC1GO,SAAS,aACd,QACA,UACA,UAA+B,CAAC,GACvB;AACT,QAAM,WAAW,YAAY;AAC7B,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,WAAW,QAAQ,YAAY;AAMrC,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA,QAAQ,QAAQ,UAAU;AAAA,EAC5B;AACA,MAAI;AACF,WAAO,SAAS,cAAc;AAAA,MAC5B;AAAA,QACE,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA,QACd,KAAK,OAAO;AAAA,QACZ,MAAM,OAAO,QAAQ;AAAA,QACrB,QAAQ,OAAO,UAAU;AAAA,QACzB,QAAQ,OAAO,UAAU;AAAA,QACzB,aAAa,OAAO,eAAe;AAAA,QACnC,aAAa,OAAO,eAAe;AAAA,QACnC,YAAY,OAAO,cAAc;AAAA,QACjC;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AAEZ,UAAM,MAAO,IAAc;AAC3B,QAAI,8BAA8B,KAAK,GAAG,KAAK,mBAAmB,UAAU;AAC1E,YAAM,IAAI;AAAA,QACR,kBAAkB,QAAQ,oCAAoC,OAAO,IAAI,IAAI,OAAO,KAAK,IAAI,OAAO,GAAG,IAAI,OAAO,QAAQ,CAAC,IAAI,OAAO,UAAU,CAAC;AAAA,MAEnJ;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,YAAY,OAAwB;AAClD,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,eAAe,UAAU;AACrC,UAAM,IAAI,MAAM,6DAA6D,OAAO,KAAK,GAAG;AAAA,EAC9F;AACA,SAAO,EAAE;AACX;AAEO,SAAS,UAAU,OAAwB;AAChD,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,WAAW,UAAU;AACjC,UAAM,IAAI,MAAM,2DAA2D,OAAO,KAAK,GAAG;AAAA,EAC5F;AACA,SAAO,EAAE;AACX;AAEO,SAAS,qBAAqB,OAAwB;AAC3D,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,sBAAsB,SAAU,QAAO,EAAE;AACvD,MAAI,OAAO,GAAG,WAAW,UAAU;AAEjC,UAAM,IAAI,EAAE,OAAO,MAAM,yBAAyB;AAClD,QAAI,CAAC,EAAG,OAAM,IAAI,MAAM,+DAA+D,EAAE,MAAM,IAAI;AACnG,UAAM,OAAO,EAAE,CAAC,MAAM,MAAM,KAAK;AACjC,WAAO,QAAQ,OAAO,EAAE,CAAC,CAAC,IAAI,OAAO,OAAO,EAAE,CAAC,CAAC,IAAI,MAAM;AAAA,EAC5D;AACA,QAAM,IAAI,MAAM,sEAAsE,OAAO,KAAK,GAAG;AACvG;AAYO,SAAS,MAAM,OAAyB;AAC7C,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,eAAe,YAAY,OAAO,GAAG,WAAW,YAAY,OAAO,GAAG,SAAS,UAAU;AACrG,UAAM,IAAI,MAAM,uDAAuD,OAAO,KAAK,GAAG;AAAA,EACxF;AACA,QAAM,WAAW,YAAY;AAC7B,MAAI;AACF,UAAM,UAAU,EAAE,gBAAgB,aAAa;AAC/C,UAAM,MAAM,SAAS,cAAc;AAAA,MACjC,EAAE,MAAM,EAAE,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,IAAI,UAAU,EAAE,WAAW;AAAA,MAAG;AAAA,IACxE;AACA,UAAM,MAAM,SAAS,cAAc;AAAA,MACjC,EAAE,MAAM,EAAE,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,IAAI,UAAU,EAAE,WAAW;AAAA,MAAG;AAAA,IACxE;AAQA,UAAM,SAAS,IAAI,sBAAsB,SAAY,OAAO,IAAI,iBAAiB,IAAI,MAAM,gBAAgB,IAAI,MAAM;AACrH,UAAM,SAAS,IAAI,sBAAsB,SAAY,OAAO,IAAI,iBAAiB,IAAI,MAAM,gBAAgB,IAAI,MAAM;AACrH,QAAI,WAAW,OAAQ,QAAO;AAC9B,UAAM,cAAc,KAAK,IAAI,QAAQ,MAAM;AAC3C,WAAO,gBAAgB,EAAE,MAAM,MAAM;AAAA,EACvC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,gBAAgB,QAAwB;AAC/C,QAAM,IAAI,iDAAiD,KAAK,MAAM;AACtE,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,OAAO,EAAE,CAAC,MAAM,MAAM,KAAK;AACjC,SAAO,QAAQ,OAAO,EAAE,CAAC,CAAC,IAAI,OAAO,OAAO,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC,KAAK,CAAC;AAC3E;AAMO,SAAS,kBAAkB,OAAqC;AACrE,SAAO,eAAe,OAAO,CAAC;AAChC;AAEO,SAAS,sBAAsB,OAAqC;AACzE,SAAO,eAAe,OAAO,EAAE;AACjC;AAEA,SAAS,eAAe,OAAgB,WAAwC;AAC9E,QAAM,IAAI;AACV,MAAI,OAAO,GAAG,eAAe,UAAU;AACrC,UAAM,IAAI,MAAM,iBAAiB,YAAY,IAAI,sBAAsB,uBAAuB,oCAAoC,OAAO,KAAK,GAAG;AAAA,EACnJ;AACA,QAAM,WAAW,YAAY;AAC7B,QAAM,WAAW,EAAE;AACnB,MAAI,kBAAkB,IAAI,OAAO,WAAW,MAAM;AAIlD,QAAM,cAAc,OAAO,EAAE,WAAW,WACpC,EAAE,UACD,MAAM;AACL,QAAI;AACF,aAAQ,SAAS,cAAc;AAAA,QAC7B,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,OAAO,KAAK,EAAE,KAAK,MAAM,EAAE,QAAQ,IAAI,SAAS;AAAA,QACzE,EAAE,gBAAgB,aAAa;AAAA,MACjC,EAAyB;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACP,MAAI,gBAAgB,OAAW,QAAO;AACtC,WAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AAQhC,UAAM,KAAK;AACX,UAAM,eAAe,SAAS,cAAc;AAAA,MAC1C,EAAE,GAAG,IAAI,SAAS;AAAA,MAClB,EAAE,gBAAgB,aAAa;AAAA,IACjC;AACA,QAAI,aAAa,WAAW,aAAa;AAOvC,aAAO,iBAAiB,UAAU,UAAU,cAAc,aAAa,SAAS;AAAA,IAClF;AACA,sBAAkB,IAAI,iBAAiB,WAAW,MAAM;AAAA,EAC1D;AACA,SAAO;AACT;AAYA,SAAS,iBACP,UACA,UACA,KACA,cACA,WACS;AACT,QAAM,YAAY,SAAS,cAAc,KAAK,KAAK,SAAS,aAAa;AACzE,QAAM,UAAU,EAAE,gBAAgB,aAAa;AAG/C,QAAM,cAAc,YAAY,IAC5B,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI,OAAO,KAAK,IAAI,KAAK,MAAM,GAAG,QAAQ,EAAE,IACrE,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,QAAQ,EAAE;AAG1E,QAAM,WAAW,CAAC,MAAc,IAAI,aAAa,GAAG,SAAS;AAC7D,QAAM,WAAW,CAAC,MAAkC;AAClD,QAAI;AACF,YAAM,IAAI,SAAS,CAAC;AACpB,aAAQ,UAAU,EAAE,GAAG,GAAG,SAAS,GAAG,OAAO,EAAyB;AAAA,IACxE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,YAAY,YAAY,IAAI,eAAe,IAAI;AAIrD,MAAI,KAAK;AACT,MAAI,KAAK;AACT,SAAO,KAAK,KAAK,GAAG;AAClB,UAAM,MAAM,KAAK,OAAO,KAAK,MAAM,CAAC;AACpC,UAAM,MAAM,SAAS,GAAG;AACxB,QAAI,QAAQ,UAAa,QAAQ,UAAW,MAAK;AAAA,QAC5C,MAAK;AAAA,EACZ;AAGA,QAAM,WAAW,MAAM,OAAO,SAAS,IAAI,IAAI,SAAS,EAAE;AAC1D,MAAI;AACF,WAAO,UAAU;AAAA,MACf,MAAM,SAAS;AAAA,MAAM,OAAO,SAAS;AAAA,MAAO,KAAK,SAAS;AAAA,MAC1D,MAAM,SAAS;AAAA,MAAM,QAAQ,SAAS;AAAA,MAAQ;AAAA,IAChD,GAAG,OAAO;AAAA,EACZ,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,OAAgB,KAAyB;AACtE,QAAM,SAAoB,CAAC;AAC3B,QAAM,SAAS;AACf,MAAI,OAAO,QAAQ,eAAe,UAAU;AAC1C,UAAM,IAAI,MAAM,0EAA0E,OAAO,KAAK,GAAG;AAAA,EAC3G;AAGA,QAAM,OAAO;AACb,MAAI,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,QAAQ,UAAU;AACtG,UAAM,IAAI,MAAM,8EAA8E,OAAO,GAAG,GAAG;AAAA,EAC7G;AACA,QAAM,UAAU,KAAK,MAAM,WAAW,KAAK,OAAO,SAAS,KAAK;AAChE,QAAM,WAAW,YAAY;AAC7B,QAAM,WAAW,OAAO;AACxB,MAAI,eAAe,IAAI,OAAO,GAAG,MAAM;AACvC,MAAI,aAAa,OAAO;AACxB,WAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AAKhC,UAAM,KAAK;AACX,UAAM,YAAY,SAAS,cAAc;AAAA,MACvC,EAAE,GAAG,IAAI,SAAS;AAAA,MAClB,EAAE,gBAAgB,aAAa;AAAA,IACjC;AACA,QAAI,UAAU,WAAW,YAAY;AAEnC,UAAI,UAAU,OAAO,WAAY,UAAU,SAAS,YAAY,UAAU,QAAQ,YAAa,UAAU,UAAU,YAAY,UAAU,MAAM,QAAW;AAC1J,aAAO,KAAK,SAAS;AACrB,mBAAa,UAAU;AAAA,IACzB;AACA,mBAAe,IAAI,cAAc,GAAG,MAAM;AAAA,EAC5C;AACA,SAAO;AACT;AAIO,SAAS,oBACd,QACA,UACW;AACX,QAAM,WAAW,YAAY;AAY7B,QAAM,UAAU,SAAS,cAAc;AAAA,IACrC,EAAE,GAAG,QAAQ,SAAS;AAAA,IACtB,EAAE,gBAAgB,WAAW,QAAQ,SAAS;AAAA,EAChD;AACA,QAAM,QAAQ,SAAS,cAAc;AAAA,IACnC,EAAE,GAAG,QAAQ,SAAS;AAAA,IACtB,EAAE,gBAAgB,SAAS,QAAQ,SAAS;AAAA,EAC9C;AAEA,QAAM,4BAA4B,CAAC,MACjC,EAAE,SAAS,OAAO,QAAQ,EAAE,UAAU,OAAO,SAAS,EAAE,QAAQ,OAAO,OACvE,EAAE,SAAS,OAAO,QAAQ,EAAE,WAAW,OAAO,UAC9C,EAAE,WAAW,OAAO,UAAU,EAAE,gBAAgB,OAAO;AAEzD,MAAI,CAAC,0BAA0B,OAAO,KAAK,CAAC,0BAA0B,KAAK,GAAG;AAE5E,WAAO,CAAC;AAAA,EACV;AACA,MAAI,QAAQ,UAAU,EAAE,qBAAqB,MAAM,UAAU,EAAE,kBAAkB;AAE/E,WAAO,CAAC,OAAO;AAAA,EACjB;AAEA,SAAO,CAAC,SAAS,KAAK;AACxB;;;ACvUA,SAAS,YAAY,MAAsB;AACzC,MAAI,OAAO,KAAK,IAAI,EAAG,QAAO;AAC9B,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO;AACjC,MAAI,YAAY,KAAK,IAAI,EAAG,QAAO;AACnC,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO;AACjC,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO;AACjC,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO;AACjC,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO;AACjC,MAAI,OAAO,KAAK,IAAI,EAAG,QAAO;AAC9B,MAAI,OAAO,KAAK,IAAI,EAAG,QAAO;AAC9B,MAAI,OAAO,KAAK,IAAI,EAAG,QAAO;AAC9B,MAAI,SAAS,IAAK,QAAO;AAGzB,MAAI,SAAS,OAAO,SAAS,SAAS,SAAS,OAAQ,QAAO;AAC9D,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO;AACjC,MAAI,SAAS,KAAM,QAAO;AAAA,EAO1B;AACA,MAAI,SAAS,QAAQ,SAAS,OAAQ,QAAO;AAC7C,SAAO;AACT;AAEO,SAAS,sBAAgD;AAC9D,SAAO,gBAAgB,IAAI,CAAC,SAAS;AACnC,UAAM,OAAO,eAAe,IAAI;AAChC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ,KAAK;AAAA,MACb,eAAe;AAAA,QACb,KAAK;AAAA,QACL;AAAA,QACA,mBAAmB,KAAK,aAAa;AAAA,QACrC,kBAAkB,KAAK,YAAY;AAAA,QACnC,qBAAqB,KAAK,eAAe;AAAA,QACzC,uBAAuB,KAAK,iBAAiB;AAAA,QAC7C,uBAAuB,KAAK,iBAAiB;AAAA,QAC7C,oBAAoB,KAAK,aAAa;AAAA,QACtC,oBAAoB,KAAK,eAAe,KAAK,IAAI,CAAC;AAAA,MACpD,EAAE,KAAK,IAAI;AAAA,MACX,QAAQ,YAAY,IAAI;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AASO,SAAS,eAA8C;AAC5D,QAAM,SAAwC,CAAC;AAC/C,aAAW,QAAQ,iBAAiB;AAClC,UAAM,OAAO,eAAe,IAAI;AAChC,WAAO,IAAI,IAAI;AAAA,MACb,WAAW;AAAA,MACX,SAAS,KAAK;AAAA,MACd,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QASP,mBAAmB,KAAK,gBAAgB,QAAQ,IAAI;AAAA,QACpD,kBAAkB,KAAK,eAAe,QAAQ,IAAI;AAAA,QAClD,qBAAqB,KAAK,kBAAkB,QAAQ,IAAI;AAAA,QACxD,uBAAuB,KAAK,oBAAoB,QAAQ,IAAI;AAAA,QAC5D,uBAAuB,KAAK,oBAAoB,QAAQ,IAAI;AAAA,QAC5D,oBAAoB,KAAK,gBAAgB,QAAQ,IAAI;AAAA,QACrD,oBAAoB,KAAK,eAAe,KAAK,IAAI,CAAC;AAAA,MACpD,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;AAgBO,SAAS,qBAAqB,WAAuC;AAC1E,QAAM,WAAW,cAAc,SAAS;AACxC,QAAM,cAAkC,CAAC;AACzC,aAAW,WAAW,SAAS,UAAU;AAKvC,QAAI,UAAU,QAAQ;AACtB,QAAI;AACJ,QAAI,QAAQ,SAAS,yBAAyB;AAC5C,mBAAa;AAAA,IACf,WAAW,QAAQ,SAAS,wBAAwB;AAClD,mBAAa;AAAA,IACf,WAAW,QAAQ,SAAS,yBAAyB;AACnD,mBAAa;AAAA,IACf,WAAW,QAAQ,SAAS,qBAAqB;AAC/C,mBAAa;AAAA,IACf;AACA,gBAAY,KAAK;AAAA,MACf,aAAa;AAAA,MACb,WAAW,UAAU;AAAA,MACrB,UAAU;AAAA,MACV;AAAA,MACA,MAAM,QAAQ;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAmBO,IAAM,wBAA+C;AAAA,EAC1D,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,iFAA6E;AAAA,EAC5G,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACtG,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,4GAAuG;AAAA,EACrI,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,gEAA2D;AAAA,EAC1F,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,gEAA2D;AAAA,EACzF,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrB,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,qEAAgE;AAAA,EAC7F,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,gCAAgC;AAAA,EAC/D,EAAE,MAAM,KAAK,IAAI,OAAO,OAAO,iCAAiC;AAAA,EAChE,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,iEAA4D;AAAA,EAC1F,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,iEAA4D;AAAA,EAC1F,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,sEAAiE;AAAA,EAChG,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,oEAA+D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM9F,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,yLAAsL;AAAA,EACrN,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,0EAAqE;AAAA,EACpG,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,0FAAqF;AAAA,EACnH,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,gGAA2F;AAAA,EAC1H,EAAE,MAAM,QAAQ,IAAI,QAAQ,OAAO,uIAAmI;AAAA,EACtK,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,wFAAmF;AAAA,EACjH,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,wFAAmF;AAAA,EAClH,EAAE,MAAM,OAAO,IAAI,MAAM,OAAO,wFAAmF;AAAA,EACnH,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,wFAAmF;AAAA,EACpH,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,wFAAmF;AAAA,EAClH,EAAE,MAAM,OAAO,IAAI,MAAM,OAAO,wFAAmF;AACrH;AAOO,IAAM,2BAAkD;AAAA,EAC7D,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA;AAAA;AAAA;AAAA,EAIvB,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,6GAAwG;AAAA,EACrI,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,sGAAkG;AAAA,EAC/H,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,kEAA6D;AAAA,EAC9F,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA,EAGrB,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,OAAO,IAAI,IAAI;AAAA,EACvB,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,kHAAmH;AAAA,EAChJ,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,OAAO,IAAI,MAAM;AAAA,EACzB,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA,EACrB,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,mFAA8E;AAAA,EAC/G,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,qDAAgD;AAAA,EAC/E,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,OAAO,IAAI,MAAM,OAAO,8EAAyE;AAAA,EACzG,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,8EAAyE;AAAA,EACxG,EAAE,MAAM,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrB,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,oLAAiL;AAAA,EAChN,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,wFAAoF;AAAA,EAClH,EAAE,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,mFAA+E;AAAA,EAC7G,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,yIAAoI;AAAA,EAClK,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACxG,EAAE,MAAM,OAAO,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACvG,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACtG,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACrG,EAAE,MAAM,QAAQ,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACxG,EAAE,MAAM,OAAO,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACvG,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,4EAAuE;AAAA,EACtG,EAAE,MAAM,KAAK,IAAI,MAAM,OAAO,4EAAuE;AACvG;AAKO,SAAS,cAAc,WAAmB,QAA0B;AAQzE,MAAI,QAAQ;AACZ,MAAI,UAAU,QAAW;AACvB,UAAM,WAAW,YAAY;AAC7B,YAAQ,SAAS,cAAc,KAAK;AAAA,MAClC,MAAM;AAAA,MAAM,OAAO;AAAA,MAAG,KAAK;AAAA,MAAG,MAAM;AAAA,MAAI,QAAQ;AAAA,MAAI,QAAQ;AAAA,MAAI,aAAa;AAAA,IAC/E,CAAC;AAAA,EACH;AACA,SAAO,OAAc,OAA8C,WAAW,EAAE,QAAQ,QAAQ,CAAC;AACnG;AAMO,SAAS,UAAU,WAA2B;AACnD,OAAK;AACL,SAAO;AACT;;;AC9TA,SAAS,gBAAgB,QAA+B;AACtD,QAAM,SAAwB,CAAC;AAC/B,MAAI,IAAI;AACR,SAAO,IAAI,OAAO,QAAQ;AACxB,QAAI,OAAO,CAAC,MAAM,KAAK;AACrB,YAAM,MAAM,OAAO,QAAQ,KAAK,IAAI,CAAC;AACrC,UAAI,QAAQ,IAAI;AACd,eAAO,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,MAAM,CAAC,EAAE,CAAC;AACrD;AAAA,MACF;AACA,aAAO,KAAK,EAAE,MAAM,WAAW,OAAO,OAAO,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC;AAChE,UAAI,MAAM;AAAA,IACZ,OAAO;AACL,UAAI,IAAI;AACR,aAAO,IAAI,OAAO,UAAU,OAAO,CAAC,MAAM,IAAK,MAAK;AACpD,aAAO,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;AACxD,UAAI;AAAA,IACN;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,cAAc,MAAc,YAAqC;AACxE,QAAM,SAAwB,CAAC;AAC/B,MAAI,IAAI;AACR,SAAO,IAAI,KAAK,QAAQ;AACtB,UAAM,QAAQ,WAAW,KAAK,CAAC,QAAQ,KAAK,WAAW,KAAK,CAAC,CAAC;AAC9D,QAAI,OAAO;AACT,aAAO,KAAK,EAAE,MAAM,SAAS,OAAO,MAAM,CAAC;AAC3C,WAAK,MAAM;AACX;AAAA,IACF;AACA,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAI,QAAQ,KAAK,SAAS,WAAW;AACnC,WAAK,SAAS,KAAK,CAAC;AAAA,IACtB,OAAO;AACL,aAAO,KAAK,EAAE,MAAM,WAAW,OAAO,KAAK,CAAC,EAAE,CAAC;AAAA,IACjD;AACA,SAAK;AAAA,EACP;AACA,SAAO;AACT;AAEA,SAAS,UAAU,QAAgB,OAA8B,gBAAgC;AAC/F,QAAM,SAAS,IAAI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,KAAK,EAAE,CAAC,CAAC;AAChE,QAAM,aAAa,CAAC,GAAG,OAAO,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AAExE,QAAM,gBAAgB,gBAAgB,MAAM;AAC5C,MAAI,MAAM;AACV,aAAW,SAAS,eAAe;AACjC,QAAI,MAAM,SAAS,WAAW;AAG5B,aAAO,IAAI,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC;AAC1C;AAAA,IACF;AACA,eAAW,OAAO,cAAc,MAAM,OAAO,UAAU,GAAG;AACxD,UAAI,IAAI,SAAS,SAAS;AACxB,cAAM,SAAS,OAAO,IAAI,IAAI,KAAK;AACnC,YAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,gBAAM,IAAI;AAAA,YACR,kBAAkB,IAAI,KAAK,YAAY,cAAc,+CAC/B,MAAM;AAAA,UAE9B;AAAA,QACF;AACA,eAAO;AAAA,MACT,WAAW,WAAW,KAAK,IAAI,KAAK,GAAG;AAGrC,eAAO,IAAI,IAAI,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC1C,OAAO;AACL,eAAO,IAAI;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAuBO,SAAS,2BAA2B,WAA2B;AACpE,SAAO,UAAU,WAAW,uBAAuB,QAAQ;AAC7D;AAYO,SAAS,6BAA6B,WAA2B;AACtE,SAAO,UAAU,WAAW,0BAA0B,UAAU;AAClE;;;AC3FA,IAAI;AAEJ,IAAI;AAEG,SAAS,gBAA0B;AACxC,SAAO,iBAAiB,eAAe,OAAO;AAChD;AAMO,SAAS,eAAwB;AACtC,SAAO,gBAAgB,cAAc,OAAO;AAC9C;AAQO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/C,YACkB,OACA,eACA,aAChB;AACA;AAAA,MACE,kBAAkB,KAAK,mCAAmC,aAAa,iBAC/D,WAAW,4EACL,WAAW,YAAY,aAAa;AAAA,IAGpD;AAVgB;AACA;AACA;AAShB,SAAK,OAAO;AAAA,EACd;AAAA,EAZkB;AAAA,EACA;AAAA,EACA;AAWpB;AAEO,SAAS,kBAAkB,MAAgB,aAA2B;AAC3E,MAAI,eAAgB,OAAM,IAAI,sBAAsB,UAAU,eAAe,aAAa,WAAW;AACrG,mBAAiB,EAAE,MAAM,YAAY;AACvC;AA0BO,SAAS,oBACd,QACA,WACA,SACU;AACV,QAAM,OAAO,cAAc;AAC3B,MAAI,OAAO,KAAK,eAAe,WAAY,QAAO,KAAK,WAAW,QAAQ,WAAW,OAAO;AAC5F,SAAO,OAAO,IAAI,CAAC,UAAU,KAAK,OAAO,WAAW,OAAO,CAAC;AAC9D;AAOO,SAAS,iBAAiB,MAAe,aAA2B;AACzE,MAAI,cAAe,OAAM,IAAI,sBAAsB,SAAS,cAAc,aAAa,WAAW;AAClG,kBAAgB,EAAE,MAAM,YAAY;AACtC;AA8BO,SAAS,oBAAoB,OAA0B;AAC5D,gBAAc,CAAC,MAAM,MAAM,MAAM,SAAS,MAAM,KAAK,CAAC;AACxD;AAqCA,SAAS,kBAAsB,MAAU,WAAmB;AAC1D,MAAI;AACJ,SAAO;AAAA,IACL,KAAK,MAAW,UAAU,QAAQ,OAAO;AAAA,IACzC,KAAK,CAAC,MAAU,gBAA8B;AAC5C,UAAI,QAAS,OAAM,IAAI,sBAAsB,WAAW,QAAQ,aAAa,WAAW;AACxF,gBAAU,EAAE,MAAM,YAAY;AAAA,IAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,OAAO,MAAY;AAAE,gBAAU;AAAA,IAAW;AAAA;AAAA,EAE5C;AACF;AAGA,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,yBAAyB,kBAAkB,gBAAqB,gBAAgB;AACtF,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,yBAAyB,kBAAkB,gBAAqB,gBAAgB;AACtF,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,sBAAsB,kBAAkB,aAAkB,aAAa;AAC7E,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,kBAAkB,kBAAkB,SAAc,SAAS;AACjE,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,kBAAkB,kBAAkB,SAAc,SAAS;AACjE,IAAM,gBAAgB,kBAAkB,OAAY,OAAO;AAC3D,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,kBAAkB,kBAAkB,SAAc,SAAS;AACjE,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,sBAAsB,kBAAkB,aAAkB,aAAa;AAC7E,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,sBAAsB,kBAAkB,aAAkB,aAAa;AAC7E,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,gBAAgB,kBAAkB,OAAY,OAAO;AAC3D,IAAM,eAAe,kBAAkB,MAAW,MAAM;AACxD,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,+BAA+B,kBAAkB,sBAA2B,sBAAsB;AACxG,IAAM,8BAA8B,kBAAkB,qBAA0B,qBAAqB;AACrG,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,6BAA6B,kBAAkB,oBAAyB,oBAAoB;AAClG,IAAM,6BAA6B,kBAAkB,oBAAyB,oBAAoB;AAClG,IAAM,4BAA4B,kBAAkB,mBAAwB,mBAAmB;AAC/F,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,gCAAgC,kBAAkB,uBAA4B,uBAAuB;AAC3G,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,2BAA2B,kBAAkB,kBAAuB,kBAAkB;AAC5F,IAAM,4BAA4B,kBAAkB,mBAAwB,mBAAmB;AAC/F,IAAM,0BAA0B,kBAAkB,iBAAsB,iBAAiB;AACzF,IAAM,0BAA0B,kBAAkB,iBAAsB,iBAAiB;AACzF,IAAM,2BAA2B,kBAAkB,kBAAuB,kBAAkB;AAC5F,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,0BAA0B,kBAAkB,iBAAsB,iBAAiB;AACzF,IAAM,iCAAiC,kBAAkB,wBAA6B,wBAAwB;AAC9G,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,mBAAmB,kBAAkB,UAAe,UAAU;AACpE,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,gBAAgB,kBAAkB,OAAY,OAAO;AAC3D,IAAM,yBAAyB,kBAAkB,gBAAqB,gBAAgB;AACtF,IAAM,6BAA6B,kBAAkB,oBAAyB,oBAAoB;AAClG,IAAM,kBAAkB,kBAAkB,SAAc,SAAS;AACjE,IAAM,qBAAqB,kBAAkB,YAAiB,YAAY;AAC1E,IAAM,sBAAsB,kBAAkB,aAAkB,aAAa;AAC7E,IAAM,iCAAiC,kBAAkB,wBAA6B,wBAAwB;AAC9G,IAAM,+BAA+B,kBAAkB,sBAA2B,sBAAsB;AACxG,IAAM,sBAAsB,kBAAkB,aAAkB,aAAa;AAC7E,IAAM,0BAA0B,kBAAkB,iBAAsB,iBAAiB;AACzF,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,4BAA4B,kBAAkB,mBAAwB,mBAAmB;AAC/F,IAAM,gCAAgC,kBAAkB,uBAA4B,uBAAuB;AAC3G,IAAM,8BAA8B,kBAAkB,qBAA0B,qBAAqB;AACrG,IAAM,8BAA8B,kBAAkB,qBAA0B,qBAAqB;AACrG,IAAM,uBAAuB,kBAAkB,cAAmB,cAAc;AAChF,IAAM,+BAA+B,kBAAkB,sBAA2B,sBAAsB;AACxG,IAAM,wBAAwB,kBAAkB,eAAoB,eAAe;AACnF,IAAM,oBAAoB,kBAAkB,WAAgB,WAAW;AACvE,IAAM,uCAAuC,kBAAkB,8BAAmC,8BAA8B;AAEzH,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,wBAAwB,uBAAuB;AACrD,IAAM,4BAA4B,uBAAuB;AACzD,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,wBAAwB,uBAAuB;AACrD,IAAM,4BAA4B,uBAAuB;AACzD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,qBAAqB,oBAAoB;AAC/C,IAAM,yBAAyB,oBAAoB;AACnD,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,iBAAiB,gBAAgB;AACvC,IAAM,qBAAqB,gBAAgB;AAC3C,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,iBAAiB,gBAAgB;AACvC,IAAM,qBAAqB,gBAAgB;AAC3C,IAAM,eAAe,cAAc;AACnC,IAAM,mBAAmB,cAAc;AACvC,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,iBAAiB,gBAAgB;AACvC,IAAM,qBAAqB,gBAAgB;AAC3C,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,qBAAqB,oBAAoB;AAC/C,IAAM,yBAAyB,oBAAoB;AACnD,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,qBAAqB,oBAAoB;AAC/C,IAAM,yBAAyB,oBAAoB;AACnD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,eAAe,cAAc;AACnC,IAAM,mBAAmB,cAAc;AACvC,IAAM,cAAc,aAAa;AACjC,IAAM,kBAAkB,aAAa;AACrC,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,8BAA8B,6BAA6B;AACjE,IAAM,kCAAkC,6BAA6B;AACrE,IAAM,6BAA6B,4BAA4B;AAC/D,IAAM,iCAAiC,4BAA4B;AACnE,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,4BAA4B,2BAA2B;AAC7D,IAAM,gCAAgC,2BAA2B;AACjE,IAAM,4BAA4B,2BAA2B;AAC7D,IAAM,gCAAgC,2BAA2B;AACjE,IAAM,2BAA2B,0BAA0B;AAC3D,IAAM,+BAA+B,0BAA0B;AAC/D,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,+BAA+B,8BAA8B;AACnE,IAAM,mCAAmC,8BAA8B;AACvE,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,0BAA0B,yBAAyB;AACzD,IAAM,8BAA8B,yBAAyB;AAC7D,IAAM,2BAA2B,0BAA0B;AAC3D,IAAM,+BAA+B,0BAA0B;AAC/D,IAAM,yBAAyB,wBAAwB;AACvD,IAAM,6BAA6B,wBAAwB;AAC3D,IAAM,yBAAyB,wBAAwB;AACvD,IAAM,6BAA6B,wBAAwB;AAC3D,IAAM,0BAA0B,yBAAyB;AACzD,IAAM,8BAA8B,yBAAyB;AAC7D,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,yBAAyB,wBAAwB;AACvD,IAAM,6BAA6B,wBAAwB;AAC3D,IAAM,gCAAgC,+BAA+B;AACrE,IAAM,oCAAoC,+BAA+B;AACzE,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,kBAAkB,iBAAiB;AACzC,IAAM,sBAAsB,iBAAiB;AAC7C,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,eAAe,cAAc;AACnC,IAAM,mBAAmB,cAAc;AACvC,IAAM,wBAAwB,uBAAuB;AACrD,IAAM,4BAA4B,uBAAuB;AACzD,IAAM,4BAA4B,2BAA2B;AAC7D,IAAM,gCAAgC,2BAA2B;AACjE,IAAM,iBAAiB,gBAAgB;AACvC,IAAM,qBAAqB,gBAAgB;AAC3C,IAAM,oBAAoB,mBAAmB;AAC7C,IAAM,wBAAwB,mBAAmB;AACjD,IAAM,qBAAqB,oBAAoB;AAC/C,IAAM,yBAAyB,oBAAoB;AACnD,IAAM,gCAAgC,+BAA+B;AACrE,IAAM,oCAAoC,+BAA+B;AACzE,IAAM,8BAA8B,6BAA6B;AACjE,IAAM,kCAAkC,6BAA6B;AACrE,IAAM,qBAAqB,oBAAoB;AAC/C,IAAM,yBAAyB,oBAAoB;AACnD,IAAM,yBAAyB,wBAAwB;AACvD,IAAM,6BAA6B,wBAAwB;AAC3D,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,2BAA2B,0BAA0B;AAC3D,IAAM,+BAA+B,0BAA0B;AAC/D,IAAM,+BAA+B,8BAA8B;AACnE,IAAM,mCAAmC,8BAA8B;AACvE,IAAM,6BAA6B,4BAA4B;AAC/D,IAAM,iCAAiC,4BAA4B;AACnE,IAAM,6BAA6B,4BAA4B;AAC/D,IAAM,iCAAiC,4BAA4B;AACnE,IAAM,sBAAsB,qBAAqB;AACjD,IAAM,0BAA0B,qBAAqB;AACrD,IAAM,8BAA8B,6BAA6B;AACjE,IAAM,kCAAkC,6BAA6B;AACrE,IAAM,uBAAuB,sBAAsB;AACnD,IAAM,2BAA2B,sBAAsB;AACvD,IAAM,mBAAmB,kBAAkB;AAC3C,IAAM,uBAAuB,kBAAkB;AAC/C,IAAM,sCAAsC,qCAAqC;AACjF,IAAM,0CAA0C,qCAAqC;;;AChc5F,SAAS,WAAW,OAAgB,OAA8B;AAChE,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,IAAI;AAAA,MACR,6DAA6D,KAAK,MAAM,OAAO,KAAK,CAAC;AAAA,IACvF;AAAA,EACF;AACA,QAAM,MAAM;AAGZ,QAAM,UAAU,OAAO,IAAI,SAAS;AACpC,QAAM,WAAW,OAAO,IAAI,UAAU;AACtC,QAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,MAAI,YAAY,YAAY,aAAa,QAAQ;AAC/C,UAAM,IAAI;AAAA,MACR,sCAAsC,KAAK;AAAA,IAE7C;AAAA,EACF;AAUA,MAAI,SAAS;AACX,UAAM,IAAI,IAAI;AACd,UAAM,IAAI,IAAI;AACd,UAAM,IAAI,IAAI;AACd,QAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,YAAY,IAAI,UAAU;AAC/E,YAAM,IAAI,iBAAiB;AAAA,QACzB,OAAO;AAAA,QACP,QAAQ,QAAQ,CAAC,mBAAmB,QAAQ,KAAK,QAAQ;AAAA,MAC3D,CAAC;AAAA,IACH;AACA,QAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,KAAK,IAAI,IAAI;AAC3C,YAAM,IAAI,iBAAiB;AAAA,QACzB,OAAO;AAAA,QACP,QAAQ,SAAS,CAAC;AAAA,MACpB,CAAC;AAAA,IACH;AACA,UAAM,SAAS,MAAM,KAAK,oBAAoB,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC;AAC9G,QAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,KAAK,IAAI,QAAQ;AAC/C,YAAM,IAAI,iBAAiB;AAAA,QACzB,OAAO;AAAA,QACP,QAAQ,OAAO,CAAC,0BAA0B,CAAC,WAAW,CAAC,SAAS,MAAM;AAAA,MACxE,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,UAAW,IAAI,OAAkB;AAAA,IACvC,OAAO,WAAY,IAAI,QAAmB;AAAA,IAC1C,KAAK,SAAU,IAAI,MAAiB;AAAA,IACpC,MAAM,OAAO,IAAI,SAAS,WAAY,IAAI,OAAkB;AAAA,IAC5D,QAAQ,OAAO,IAAI,WAAW,WAAY,IAAI,SAAoB;AAAA,IAClE,QAAQ,OAAO,IAAI,WAAW,WAAY,IAAI,SAAoB;AAAA,IAClE,aAAa,OAAO,IAAI,gBAAgB,WAAY,IAAI,cAAyB;AAAA,EACnF;AACF;AAKA,IAAM,WAAW;AACjB,IAAM,WAAW;AAKjB,IAAME,kBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,gBAAgB,KAAK;AAC3B,IAAM,cAAc,KAAK;AACzB,IAAM,aAAa,KAAK;AAExB,SAAS,mBAAmB,MAAc,OAAe,KAAqB;AAQ5E,SAAO,cAAc,MAAM,OAAO,GAAG,IAAI,cAAcA,iBAAgB,GAAG,CAAC;AAC7E;AAEA,SAAS,UAAU,QAA+B;AAOhD,MAAI,OAAO,SAAS,UAAa,OAAO,UAAU,UAAa,OAAO,QAAQ,QAAW;AACvF,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AACA,QAAM,OAAO,mBAAmB,OAAO,MAAM,OAAO,OAAO,OAAO,GAAG;AACrE,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,cAAc,OAAO,eAAe;AAC1C,SAAO,OAAO,aAAa,OAAO,cAAc,SAAS,gBAAgB,SAAS,gBAAgB;AACpG;AAuBA,IAAM,kBAAkB;AAAA,EACtB,SAAS;AAAA;AAAA,EACT,SAAS;AAAA;AAAA,EACT,OAAO;AAAA;AAAA,EACP,MAAM;AAAA;AAAA,EACN,QAAQ;AAAA;AACV;AA2BA,SAAS,eAAe,MAAqF;AAC3G,QAAM,SAAoC,EAAE,GAAG,iBAAiB,GAAG,KAAK;AAExE,aAAW,OAAO,OAAO,KAAK,MAAM,GAAkB;AACpD,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACtE,YAAM,IAAI;AAAA,QACR,wCAAwC,GAAG,2CAA2C,OAAO,KAAK,CAAC;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,OAAO,UAAU;AACnC,QAAM,YAAY,OAAO,UAAU;AACnC,QAAM,UAAU,OAAO,QAAQ;AAC/B,QAAM,SAAS,OAAO,OAAO;AAE7B,QAAM,WAAW,OAAO,SAAS;AAEjC,MAAI,EAAE,aAAa,aAAa,aAAa,WAAW,WAAW,UAAU,UAAU,WAAW;AAChG,UAAM,IAAI;AAAA,MACR,4KAC6D,OAAO,OAAO,cAChE,OAAO,OAAO,cAAc,OAAO,KAAK,WAAW,OAAO,IAAI,aAAa,OAAO,MAAM;AAAA,IAErG;AAAA,EACF;AAEA,SAAO;AAAA,IACL,EAAE,OAAO,WAAW,MAAM,SAAS;AAAA,IACnC,EAAE,OAAO,WAAW,MAAM,SAAS;AAAA,IACnC,EAAE,OAAO,SAAS,MAAM,OAAO;AAAA,IAC/B,EAAE,OAAO,QAAQ,MAAM,MAAM;AAAA,IAC7B,EAAE,OAAO,UAAU,MAAM,QAAQ;AAAA,EACnC;AACF;AAEA,IAAM,WAAW,oBAAI,IAAqC;AAC1D,IAAM,qBAAqB;AAE3B,SAAS,OAAO,QAAgB,SAAqD;AACnF,QAAM,MAAM,GAAG,mBAAmB,MAAM,CAAC,IAAI,OAAO;AACpD,MAAI,MAAM,SAAS,IAAI,GAAG;AAC1B,MAAI,IAAK,QAAO;AAChB,MAAI,SAAS,QAAQ,oBAAoB;AACvC,UAAM,YAAY,SAAS,KAAK,EAAE,KAAK,EAAE;AACzC,QAAI,cAAc,OAAW,UAAS,OAAO,SAAS;AAAA,EACxD;AACA,MAAI;AACF,UAAM,IAAI,KAAK,mBAAmB,mBAAmB,MAAM,GAAG,EAAE,QAAQ,CAAC;AAAA,EAC3E,SAAS,KAAK;AAMZ,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAS,IAAc,QAAQ,CAAC;AAAA,EACjF;AACA,WAAS,IAAI,KAAK,GAAG;AACrB,SAAO;AACT;AAEA,SAAS,mBAAmB,QAAwB;AAClD,MAAI;AACF,WAAO,IAAI,KAAK,OAAO,OAAO,QAAQ,MAAM,GAAG,CAAC,EAAE,SAAS,EAAE,YAAY;AAAA,EAC3E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA6CO,SAAS,eACd,OACA,OACA,UAAiC,CAAC,GAC1B;AACR,QAAM,UAAU,WAAW,OAAO,OAAO;AACzC,QAAM,UAAU,WAAW,OAAO,OAAO;AAQzC,QAAM,SAAS,UAAU,OAAO,IAAI,UAAU,OAAO;AACrD,QAAM,QAAQ,KAAK,IAAI,MAAM;AAE7B,QAAM,cAAc,eAAe,QAAQ,OAAO;AAClD,MAAI,OAAoC;AACxC,aAAW,EAAE,OAAO,MAAM,cAAc,KAAK,aAAa;AACxD,QAAI,QAAQ,OAAO;AACjB,aAAO;AACP;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,SAAS,IAAI;AAC7B,QAAM,UAAU,KAAK,MAAM,SAAS,OAAO;AAE3C,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,MAAM,OAAO,QAAQ,OAAO;AAClC,SAAO,IAAI,OAAO,SAAS,IAAI;AACjC;AAwBO,SAAS,oBACd,MACA,UAAiC,CAAC,GAC1B;AACR,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,YAAY;AAAA,IAChB,MAAM,IAAI,YAAY;AAAA,IACtB,OAAO,IAAI,SAAS,IAAI;AAAA,IACxB,KAAK,IAAI,QAAQ;AAAA,IACjB,MAAM,IAAI,SAAS;AAAA,IACnB,QAAQ,IAAI,WAAW;AAAA,IACvB,QAAQ,IAAI,WAAW;AAAA,IACvB,aAAa,IAAI,gBAAgB;AAAA,EACnC;AACA,SAAO,eAAe,MAAM,WAAW,OAAO;AAChD;AAEA,SAAS,SAAS,MAA2C;AAC3D,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAU,aAAO;AAAA,IACtB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAO,aAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASnB,KAAK;AAAQ,aAAO,IAAI;AAAA;AAAA,IAExB,KAAK;AAAS,aAAO,KAAK;AAAA;AAAA;AAAA,IAG1B,KAAK;AAAW,aAAO,KAAK;AAAA;AAAA,IAE5B,KAAK;AAAQ,aAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQ1B;AACE,YAAM,IAAI,MAAM,oDAAoD,OAAO,IAAI,CAAC,IAAI;AAAA,EAExF;AACF;;;ACvTA,SAAS,SAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM;AACxC;AAUA,SAAS,aAAgB,MAAsE;AAC7F,SAAO,CAAC,UAA+B;AACrC,QAAI;AACF,aAAO,KAAK,KAAK;AAAA,IACnB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,UACP,GACA,MACS;AACT,SAAO,OAAO,EAAE,IAAI,MAAM;AAC5B;AASA,SAAS,OAAO,OAAgB,UAA2B;AACzD,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,MAAO,MAA6C,OAAO,WAAW;AAC5E,SAAO,QAAQ,YAAY,QAAQ;AACrC;AAEO,IAAM,cAA6D,aAAa,SAAS,gBAAgB,OAA2C;AACzJ,MAAI,OAAO,OAAO,WAAW,EAAG,QAAO;AACvC,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,SAAS,YACpB,OAAO,EAAE,UAAU,YACnB,OAAO,EAAE,QAAQ,YACjB,OAAO,EAAE,SAAS,eAClB,UAAU,GAAG,iBAAiB,KAC9B,UAAU,GAAG,cAAc;AAClC,CAAC;AAEM,IAAM,cAA6D,aAAa,SAAS,gBAAgB,OAA2C;AACzJ,MAAI,OAAO,OAAO,WAAW,EAAG,QAAO;AACvC,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI;AAIV,SAAO,OAAO,EAAE,SAAS,YACpB,OAAO,EAAE,SAAS,eAClB,CAAC,UAAU,GAAG,cAAc,KAC5B,CAAC,UAAU,GAAG,aAAa,KAC3B,CAAC,UAAU,GAAG,iBAAiB;AACtC,CAAC;AAEM,IAAM,kBAAiE,aAAa,SAAS,oBAAoB,OAA2C;AACjK,MAAI,OAAO,OAAO,eAAe,EAAG,QAAO;AAC3C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI;AAIV,SAAO,OAAO,EAAE,SAAS,YACpB,OAAO,EAAE,UAAU,YACnB,OAAO,EAAE,QAAQ,YACjB,OAAO,EAAE,SAAS,YAClB,UAAU,GAAG,eAAe,KAC5B,CAAC,UAAU,GAAG,WAAW;AAChC,CAAC;AAEM,IAAM,kBAAiE,aAAa,SAAS,oBAAoB,OAA2C;AACjK,MAAI,OAAO,OAAO,eAAe,EAAG,QAAO;AAC3C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI;AAEV,SAAO,OAAO,EAAE,SAAS,YACpB,OAAO,EAAE,UAAU,YACnB,OAAO,EAAE,QAAQ,YACjB,OAAO,EAAE,SAAS,YAClB,UAAU,GAAG,cAAc,KAC3B,UAAU,GAAG,WAAW;AAC/B,CAAC;AAEM,IAAM,YAA2D,aAAa,SAAS,cAAc,OAA2C;AACrJ,MAAI,OAAO,OAAO,SAAS,EAAG,QAAO;AACrC,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAK7B,QAAM,IAAI;AACV,SAAO,UAAU,GAAG,oBAAoB,KACnC,CAAC,UAAU,GAAG,WAAW,KACzB,OAAO,EAAE,SAAS;AACzB,CAAC;AAEM,IAAM,mBAAkE,aAAa,SAAS,qBAAqB,OAA2C;AACnK,MAAI,OAAO,OAAO,gBAAgB,EAAG,QAAO;AAC5C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI;AAGV,SAAO,OAAO,EAAE,SAAS,YACpB,OAAO,EAAE,UAAU,YACnB,OAAO,EAAE,QAAQ,eACjB,UAAU,GAAG,aAAa;AACjC,CAAC;AAEM,IAAM,kBAAiE,aAAa,SAAS,oBAAoB,OAA2C;AACjK,MAAI,OAAO,OAAO,eAAe,EAAG,QAAO;AAC3C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI;AAKV,SAAO,OAAO,EAAE,SAAS,eACpB,OAAO,EAAE,UAAU,eACnB,OAAO,EAAE,QAAQ,YACjB,OAAO,EAAE,cAAc,YACvB,UAAU,GAAG,aAAa;AACjC,CAAC;AAEM,IAAM,aAAmE,aAAa,SAAS,eAAe,OAAkD;AACrK,MAAI,OAAO,OAAO,UAAU,EAAG,QAAO;AACtC,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAM7B,QAAM,IAAI;AACV,SAAO,UAAU,GAAG,OAAO;AAC7B,CAAC;AAaM,IAAM,aAA4D,aAAa,SAAS,eAAe,OAA2C;AACvJ,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,MAAO,MAA6C,OAAO,WAAW;AAC5E,MAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,WAAW,EAAG,QAAO;AACnE,QAAM,IAAI;AACV,SAAO,UAAU,GAAG,WAAW,KAC1B,UAAU,GAAG,aAAa,KAC1B,UAAU,GAAG,iBAAiB,KAC9B,UAAU,GAAG,aAAa,KAC1B,UAAU,GAAG,kBAAkB,KAC/B,UAAU,GAAG,iBAAiB,KAC9B,UAAU,GAAG,iBAAiB,KAC9B,UAAU,GAAG,oBAAoB,KACjC,UAAU,GAAG,cAAc,KAC3B,UAAU,GAAG,eAAe,KAC5B,UAAU,GAAG,cAAc,KAC3B,UAAU,GAAG,OAAO;AAC3B,CAAC;AAMD,SAAS,cAAc,OAAwB;AAC7C,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,OAAQ,MAA8C;AAC5D,QAAI,QAAQ,OAAO,KAAK,SAAS,YAAY,KAAK,SAAS,UAAU;AACnE,aAAO,eAAe,KAAK,IAAI;AAAA,IACjC;AACA,WAAO;AAAA,EACT;AACA,SAAO,OAAO;AAChB;AAEA,SAAS,WAAW,OAAgB,OAAgC,cAA4B;AAC9F,MAAI,CAAC,MAAM,KAAK,GAAG;AACjB,UAAM,IAAI;AAAA,MACR,qCAAqC,YAAY,SAAS,cAAc,KAAK,CAAC;AAAA,IAChF;AAAA,EACF;AACF;AAEO,SAAS,eAAe,OAAmD;AAChF,aAAW,OAAO,YAAY,kHAAkH;AAClJ;AACO,SAAS,cAAc,OAAmD;AAC/E,aAAW,OAAO,WAAW,SAAS;AACxC;AACO,SAAS,gBAAgB,OAAmD;AACjF,aAAW,OAAO,aAAa,WAAW;AAC5C;AACO,SAAS,gBAAgB,OAAmD;AACjF,aAAW,OAAO,aAAa,WAAW;AAC5C;AACO,SAAS,oBAAoB,OAAmD;AACrF,aAAW,OAAO,iBAAiB,eAAe;AACpD;AACO,SAAS,oBAAoB,OAAmD;AACrF,aAAW,OAAO,iBAAiB,eAAe;AACpD;AACO,SAAS,qBAAqB,OAAmD;AACtF,aAAW,OAAO,kBAAkB,gBAAgB;AACtD;AACO,SAAS,oBAAoB,OAAmD;AACrF,aAAW,OAAO,iBAAiB,eAAe;AACpD;AACO,SAAS,eAAe,OAA0D;AACvF,aAAW,OAAO,YAAY,UAAU;AAC1C;;;AC3SA,IAAMC,YAAW,oBAAI,IAAqC;AAC1D,IAAMC,sBAAqB;AAE3B,SAASC,QAAO,QAAgB,SAAqD;AAEnF,QAAM,MAAM,GAAG,MAAM,IAAI,OAAO;AAChC,MAAI,MAAMF,UAAS,IAAI,GAAG;AAC1B,MAAI,IAAK,QAAO;AAChB,MAAIA,UAAS,QAAQC,qBAAoB;AACvC,UAAM,YAAYD,UAAS,KAAK,EAAE,KAAK,EAAE;AACzC,QAAI,cAAc,OAAW,CAAAA,UAAS,OAAO,SAAS;AAAA,EACxD;AACA,MAAI;AACF,UAAM,IAAI,KAAK,mBAAmB,mBAAmB,MAAM,GAAG,EAAE,QAAQ,CAAC;AAAA,EAC3E,SAAS,KAAK;AAKZ,UAAM,IAAI,mBAAmB,EAAE,QAAQ,QAAQ,QAAS,IAAc,QAAQ,CAAC;AAAA,EACjF;AACA,EAAAA,UAAS,IAAI,KAAK,GAAG;AACrB,SAAO;AACT;AASO,SAAS,eACd,OACA,OACA,UAAiC,CAAC,GAC1B;AACR,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,MAAME,QAAO,QAAQ,OAAO;AAClC,QAAM,UAAU,CAAC,iBAAiB,OAAO,KAAK;AAC9C,QAAM,UAAU,KAAK,IAAI,OAAO;AAEhC,MAAI,YAAY,GAAG;AACjB,WAAO,IAAI,OAAO,GAAG,KAAK;AAAA,EAC5B;AACA,MAAI,UAAU,GAAG;AACf,WAAO,IAAI,OAAO,SAAS,KAAK;AAAA,EAClC;AACA,MAAI,UAAU,IAAI;AAChB,WAAO,IAAI,OAAO,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM;AAAA,EACrD;AACA,MAAI,UAAU,KAAK;AACjB,WAAO,IAAI,OAAO,CAAC,KAAK,MAAM,CAAC,UAAU,EAAE,GAAG,OAAO;AAAA,EACvD;AACA,SAAO,IAAI,OAAO,CAAC,KAAK,MAAM,CAAC,UAAU,GAAG,GAAG,MAAM;AACvD;AAEO,SAAS,oBACd,MACA,UAAiC,CAAC,GAC1B;AAER,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,YAAY;AAAA,IAChB,MAAM,IAAI,YAAY;AAAA,IACtB,OAAO,IAAI,SAAS,IAAI;AAAA,IACxB,KAAK,IAAI,QAAQ;AAAA,EACnB;AACA,SAAO,eAAe,MAAM,WAAW,OAAO;AAChD;;;ACzDO,SAAS,gBAAgB,UAA4B,CAAC,GAAc;AAEzE,QAAM,eAA0D,CAAC,GAAG,MAAM;AAC1E,QAAM,mBAAmB,oBAAI,IAAY;AACzC,aAAW,UAAU,QAAQ,UAAU,CAAC,GAAG;AACzC,qBAAiB,IAAI,OAAO,IAAI;AAAA,EAClC;AAEA,aAAW,UAAU,QAAQ,UAAU,CAAC,GAAG;AACzC,UAAM,cAAc,aAAa,UAAU,CAAC,CAAC,IAAI,MAAM,SAAS,OAAO,IAAI;AAC3E,QAAI,eAAe,GAAG;AACpB,mBAAa,WAAW,IAAI,CAAC,OAAO,MAAM,OAAO,SAAS,OAAO,KAAK;AAAA,IACxE,OAAO;AACL,mBAAa,KAAK,CAAC,OAAO,MAAM,OAAO,SAAS,OAAO,KAAK,CAAC;AAAA,IAC/D;AAAA,EACF;AAEA,eAAa,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM;AACrD,QAAM,iBAAiB,IAAI,IAAI,aAAa,IAAI,CAAC,CAAC,MAAM,SAAS,KAAK,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC;AACvG,QAAM,qBAAqB,aAAa,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAE5D,WAAS,eAAe,WAAmB;AACzC,UAAM,SAA8D,CAAC;AACrE,QAAI,IAAI;AACR,WAAO,IAAI,UAAU,QAAQ;AAC3B,YAAM,KAAK,UAAU,CAAC;AACtB,UAAI,OAAO,KAAK;AAEd,YAAI,UAAU,IAAI,CAAC,MAAM,KAAK;AAC5B,UAAAC,eAAc,QAAQ,GAAG;AACzB,eAAK;AACL;AAAA,QACF;AACA,YAAI,IAAI,IAAI;AACZ,YAAI,UAAU;AACd,YAAI,SAAS;AACb,eAAO,IAAI,UAAU,QAAQ;AAC3B,cAAI,UAAU,CAAC,MAAM,KAAK;AACxB,gBAAI,UAAU,IAAI,CAAC,MAAM,KAAK;AAC5B,yBAAW;AACX,mBAAK;AACL;AAAA,YACF;AACA,qBAAS;AACT,iBAAK;AACL;AAAA,UACF;AACA,qBAAW,UAAU,CAAC;AACtB,eAAK;AAAA,QACP;AACA,YAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sDAAsD,SAAS,GAAG;AAC/F,QAAAA,eAAc,QAAQ,OAAO;AAC7B,YAAI;AACJ;AAAA,MACF;AACA,YAAM,QAAQ,mBAAmB,KAAK,CAAC,QAAQ,UAAU,WAAW,KAAK,CAAC,CAAC;AAC3E,UAAI,OAAO;AAOT,cAAM,UAAU,MAAM,MAAM,SAAS,CAAC;AACtC,YAAI,UAAU,IAAI,MAAM,MAAM,MAAM,SAAS;AAC3C,cAAI,MAAM,IAAI,MAAM;AACpB,iBAAO,UAAU,GAAG,MAAM,QAAS,QAAO;AAC1C,gBAAM,IAAI,kBAAkB;AAAA,YAC1B,OAAO,UAAU,MAAM,GAAG,GAAG;AAAA,YAC7B,QAAQ;AAAA,YACR,SACE,kBAAkB,UAAU,MAAM,GAAG,GAAG,CAAC,uBAAuB,SAAS,mDACxD,KAAK;AAAA,UAC1B,CAAC;AAAA,QACH;AACA,eAAO,KAAK,EAAE,MAAM,SAAS,OAAO,MAAM,CAAC;AAC3C,aAAK,MAAM;AACX;AAAA,MACF;AACA,MAAAA,eAAc,QAAQ,EAAE;AACxB,WAAK;AAAA,IACP;AACA,WAAO;AAAA,EACT;AAEA,WAASA,eAAc,QAA6D,OAAqB;AACvG,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAI,QAAQ,KAAK,SAAS,WAAW;AACnC,WAAK,SAAS;AAAA,IAChB,OAAO;AACL,aAAO,KAAK,EAAE,MAAM,WAAW,MAAM,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,gBAAgB,QAAQ,iBAAiB;AAE/C,SAAO;AAAA,IACL,OAAO,UAAwB,WAAmB,OAAsB,CAAC,GAAG;AAC1E,UAAI,UAAU,SAAS,mBAAmB;AACxC,cAAM,IAAI,MAAM,yDAAyD,iBAAiB,oBAAoB,UAAU,MAAM,IAAI;AAAA,MACpI;AACA,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,SAAS,eAAe,SAAS;AACvC,UAAI,SAAS;AACb,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,SAAS,WAAW;AAC5B,oBAAU,MAAM;AAChB;AAAA,QACF;AACA,cAAM,UAAU,eAAe,IAAI,MAAM,KAAK;AAAA,QAC9C;AAAA;AAAA;AAAA;AAAA;AAKA,YAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC,MAAM,KAAK,GAAG;AAAA,QAC5E;AACA,YAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,gBAAM,IAAI;AAAA,YACR,wBAAwB,MAAM,KAAK,eAAe,OAAO,QAAQ,KAAK,CAAC;AAAA,UACzE;AAAA,QACF;AACA,kBAAU,QAAQ,QAAQ,UAAU,MAAM;AAAA,MAC5C;AACA,aAAO;AAAA,IACT;AAAA,IACA,cAAc,UAAwB,WAAmB,OAAsB,CAAC,GAAG;AACjF,UAAI,UAAU,SAAS,mBAAmB;AACxC,cAAM,IAAI,MAAM,yDAAyD,iBAAiB,oBAAoB,UAAU,MAAM,IAAI;AAAA,MACpI;AACA,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,SAAS,eAAe,SAAS;AACvC,YAAM,MAAuB,CAAC;AAC9B,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,SAAS,WAAW;AAC5B,gBAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAAA,UAC/B;AAAA;AAAA;AAAA;AAAA;AAKA,cAAI,QAAQ,KAAK,SAAS,UAAW,MAAK,SAAS,MAAM;AAAA,cAEpD,KAAI,KAAK,EAAE,MAAM,WAAW,OAAO,MAAM,MAAM,CAAC;AACrD;AAAA,QACF;AACA,cAAM,UAAU,eAAe,IAAI,MAAM,KAAK;AAAA,QAC9C;AAAA;AAAA;AAAA;AAIA,YAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC,MAAM,KAAK,GAAG;AAAA,QAC5E;AACA,YAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,gBAAM,IAAI,MAAM,wBAAwB,MAAM,KAAK,eAAe,OAAO,QAAQ,KAAK,CAAC,IAAI;AAAA,QAC7F;AACA,YAAI,KAAK,EAAE,MAAM,SAAS,OAAO,QAAQ,QAAQ,UAAU,MAAM,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,MAC1F;AACA,aAAO;AAAA,IACT;AAAA,IACA,cAAc,WAAmC;AAC/C,UAAI,UAAU,SAAS,mBAAmB;AACxC,cAAM,IAAI,MAAM,yDAAyD,iBAAiB,oBAAoB,UAAU,MAAM,IAAI;AAAA,MACpI;AACA,YAAM,SAAS,eAAe,SAAS;AACvC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAiD;AAAA,QAC3E,OAAO,UAAwB,OAAsB,CAAC,GAAG;AACvD,gBAAM,SAAS,KAAK,UAAU;AAC9B,cAAI,SAAS;AACb,qBAAW,SAAS,QAAQ;AAC1B,gBAAI,MAAM,SAAS,WAAW;AAC5B,wBAAU,MAAM;AAChB;AAAA,YACF;AACA,kBAAM,UAAU,eAAe,IAAI,MAAM,KAAK;AAAA,YAC9C;AAAA;AAEA,gBAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC,MAAM,KAAK,GAAG;AAAA,YAC5E;AACA,gBAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,oBAAM,IAAI,MAAM,wBAAwB,MAAM,KAAK,eAAe,OAAO,QAAQ,KAAK,CAAC,IAAI;AAAA,YAC7F;AACA,sBAAU,QAAQ,QAAQ,UAAU,MAAM;AAAA,UAC5C;AACA,iBAAO;AAAA,QACT;AAAA,QACA,cAAc,UAAwB,OAAsB,CAAC,GAAG;AAC9D,gBAAM,SAAS,KAAK,UAAU;AAC9B,gBAAM,MAAuB,CAAC;AAC9B,qBAAW,SAAS,QAAQ;AAC1B,gBAAI,MAAM,SAAS,WAAW;AAC5B,oBAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAAA,cAC/B;AAAA;AAEA,kBAAI,QAAQ,KAAK,SAAS,UAAW,MAAK,SAAS,MAAM;AAAA,kBAEpD,KAAI,KAAK,EAAE,MAAM,WAAW,OAAO,MAAM,MAAM,CAAC;AACrD;AAAA,YACF;AACA,kBAAM,UAAU,eAAe,IAAI,MAAM,KAAK;AAAA,YAC9C;AAAA;AAEA,gBAAI,CAAC,QAAS,OAAM,IAAI,MAAM,gCAAgC,MAAM,KAAK,GAAG;AAAA,YAC5E;AACA,gBAAI,SAAS,QAAQ,KAAK,MAAM,QAAW;AACzC,oBAAM,IAAI,MAAM,wBAAwB,MAAM,KAAK,eAAe,OAAO,QAAQ,KAAK,CAAC,IAAI;AAAA,YAC7F;AACA,gBAAI,KAAK,EAAE,MAAM,SAAS,OAAO,QAAQ,QAAQ,UAAU,MAAM,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,UAC1F;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5MO,IAAM,wBAAwB,CAAC,WAAW,YAAY,iBAAiB,QAAQ;AAsL/E,SAAS,mBAAmB,SAA6B;AAC9D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcA,IAAI,OAAO,SAAS,MAAM;AACxB,YAAM,IAAK,WAAsL;AACjM,YAAM,QAAQ,UAAU,UAAU,GAAG,QAAQ,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,GAAG,OAAO,GAAG;AAC1G,cAAQ,IAAI,OAAO,KAAK,KAAK,KAAK,OAAO,GAAG,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK,EAAE,EAAE;AAAA,IACtF;AAAA,IACA,YAAY,OAAO;AACjB,YAAM,IAAK,WAAsE;AACjF,YAAM,WAAW,MAAM,YAAY;AACnC,SAAG,QAAQ,IAAI,OAAO,KAAK,QAAQ,KAAK,MAAM,OAAO,GAAG,MAAM,WAAW,SAAY,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,KAAK,EAAE,EAAE;AAAA,IAChI;AAAA,IACA,cAAc,YAAY;AACxB,aAAQ,sBAA4C,SAAS,UAAU;AAAA,IACzE;AAAA,IACA,eAAe,MAAM;AACnB,YAAM,WAAW,cAAc;AAC/B,YAAM,UAAU,IAAI,SAAsC,KAAK,UAAU,GAAG,IAAI;AAMhF,YAAM,QAAS,KAA8C;AAC7D,UAAI,OAAO,UAAU,YAAY;AAC/B,QAAC,QAA6D,aAC5D,CAAC,QAAQ,WAAW,YAAY,MAAM,QAAQ,WAAW,SAAS,QAAQ;AAAA,MAC9E;AACA,wBAAkB,SAAS,OAAO;AAAA,IACpC;AAAA,IACA,cAAc,MAAM;AAClB,YAAM,WAAW,aAAa;AAC9B,uBAAiB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAChE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,uBAAuB,MAAM;AAC3B,YAAM,WAAW,sBAAsB;AACvC,gCAA0B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACzE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,uBAAuB,MAAM;AAC3B,YAAM,WAAW,sBAAsB;AACvC,gCAA0B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACzE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,oBAAoB,MAAM;AACxB,YAAM,WAAW,mBAAmB;AACpC,6BAAuB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACtE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,gBAAgB,MAAM;AACpB,YAAM,WAAW,eAAe;AAChC,yBAAmB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAClE;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,gBAAgB,MAAM;AACpB,YAAM,WAAW,eAAe;AAChC,yBAAmB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAClE;AAAA,IACA,cAAc,MAAM;AAClB,YAAM,WAAW,aAAa;AAC9B,uBAAiB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAChE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,gBAAgB,MAAM;AACpB,YAAM,WAAW,eAAe;AAChC,yBAAmB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAClE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,oBAAoB,MAAM;AACxB,YAAM,WAAW,mBAAmB;AACpC,6BAAuB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACtE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,oBAAoB,MAAM;AACxB,YAAM,WAAW,mBAAmB;AACpC,6BAAuB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACtE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,cAAc,MAAM;AAClB,YAAM,WAAW,aAAa;AAC9B,uBAAiB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAChE;AAAA,IACA,aAAa,MAAM;AACjB,YAAM,WAAW,YAAY;AAC7B,sBAAgB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC/D;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,6BAA6B,MAAM;AACjC,YAAM,WAAW,4BAA4B;AAC7C,sCAAgC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC/E;AAAA,IACA,4BAA4B,MAAM;AAChC,YAAM,WAAW,2BAA2B;AAC5C,qCAA+B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC9E;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,2BAA2B,MAAM;AAC/B,YAAM,WAAW,0BAA0B;AAC3C,oCAA8B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC7E;AAAA,IACA,2BAA2B,MAAM;AAC/B,YAAM,WAAW,0BAA0B;AAC3C,oCAA8B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC7E;AAAA,IACA,0BAA0B,MAAM;AAC9B,YAAM,WAAW,yBAAyB;AAC1C,mCAA6B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC5E;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,8BAA8B,MAAM;AAClC,YAAM,WAAW,6BAA6B;AAC9C,uCAAiC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAChF;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,yBAAyB,MAAM;AAC7B,YAAM,WAAW,wBAAwB;AACzC,kCAA4B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC3E;AAAA,IACA,0BAA0B,MAAM;AAC9B,YAAM,WAAW,yBAAyB;AAC1C,mCAA6B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC5E;AAAA,IACA,wBAAwB,MAAM;AAC5B,YAAM,WAAW,uBAAuB;AACxC,iCAA2B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC1E;AAAA,IACA,wBAAwB,MAAM;AAC5B,YAAM,WAAW,uBAAuB;AACxC,iCAA2B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC1E;AAAA,IACA,yBAAyB,MAAM;AAC7B,YAAM,WAAW,wBAAwB;AACzC,kCAA4B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC3E;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,wBAAwB,MAAM;AAC5B,YAAM,WAAW,uBAAuB;AACxC,iCAA2B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC1E;AAAA,IACA,+BAA+B,MAAM;AACnC,YAAM,WAAW,8BAA8B;AAC/C,wCAAkC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACjF;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,iBAAiB,MAAM;AACrB,YAAM,WAAW,gBAAgB;AACjC,0BAAoB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACnE;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,cAAc,MAAM;AAClB,YAAM,WAAW,aAAa;AAC9B,uBAAiB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAChE;AAAA,IACA,uBAAuB,MAAM;AAC3B,YAAM,WAAW,sBAAsB;AACvC,gCAA0B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACzE;AAAA,IACA,2BAA2B,MAAM;AAC/B,YAAM,WAAW,0BAA0B;AAC3C,oCAA8B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC7E;AAAA,IACA,gBAAgB,MAAM;AACpB,YAAM,WAAW,eAAe;AAChC,yBAAmB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAClE;AAAA,IACA,mBAAmB,MAAM;AACvB,YAAM,WAAW,kBAAkB;AACnC,4BAAsB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACrE;AAAA,IACA,oBAAoB,MAAM;AACxB,YAAM,WAAW,mBAAmB;AACpC,6BAAuB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACtE;AAAA,IACA,+BAA+B,MAAM;AACnC,YAAM,WAAW,8BAA8B;AAC/C,wCAAkC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACjF;AAAA,IACA,6BAA6B,MAAM;AACjC,YAAM,WAAW,4BAA4B;AAC7C,sCAAgC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC/E;AAAA,IACA,oBAAoB,MAAM;AACxB,YAAM,WAAW,mBAAmB;AACpC,6BAAuB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACtE;AAAA,IACA,wBAAwB,MAAM;AAC5B,YAAM,WAAW,uBAAuB;AACxC,iCAA2B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC1E;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,0BAA0B,MAAM;AAC9B,YAAM,WAAW,yBAAyB;AAC1C,mCAA6B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC5E;AAAA,IACA,8BAA8B,MAAM;AAClC,YAAM,WAAW,6BAA6B;AAC9C,uCAAiC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAChF;AAAA,IACA,4BAA4B,MAAM;AAChC,YAAM,WAAW,2BAA2B;AAC5C,qCAA+B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC9E;AAAA,IACA,4BAA4B,MAAM;AAChC,YAAM,WAAW,2BAA2B;AAC5C,qCAA+B,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC9E;AAAA,IACA,qBAAqB,MAAM;AACzB,YAAM,WAAW,oBAAoB;AACrC,8BAAwB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvE;AAAA,IACA,6BAA6B,MAAM;AACjC,YAAM,WAAW,4BAA4B;AAC7C,sCAAgC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IAC/E;AAAA,IACA,sBAAsB,MAAM;AAC1B,YAAM,WAAW,qBAAqB;AACtC,+BAAyB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,kBAAkB,MAAM;AACtB,YAAM,WAAW,iBAAiB;AAClC,2BAAqB,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACpE;AAAA,IACA,qCAAqC,MAAM;AACzC,YAAM,WAAW,oCAAoC;AACrD,8CAAwC,IAAI,SAAS,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO;AAAA,IACvF;AAAA,EACF;AACF;AAKO,SAAS,kBAA8B;AAC5C,SAAO,mBAAmB,gBAAgB;AAC5C;AAoDO,SAAS,uBACd,SACA,YACA,eAA+C,MAAM;AAAC,GAC1C;AACZ,QAAM,OAAO,mBAAmB,OAAO;AACvC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASL,GAAG;AAAA,IACH,IAAI,OAAO,SAAS,MAAM;AACxB,mBAAa,EAAE,QAAQ,OAAO,OAAO,SAAS,KAAK,CAAC;AACpD,WAAK,IAAI,OAAO,SAAS,IAAI;AAAA,IAC/B;AAAA,IACA,YAAY,OAAO;AACjB,mBAAa;AAAA,QACX,QAAQ;AAAA,QACR,OAAO,MAAM,aAAa,UAAU,UAAU;AAAA,QAC9C,SAAS,MAAM;AAAA,QACf,QAAQ,MAAM;AAAA,MAChB,CAAC;AACD,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,IACA,eAAe,QAAQ,OAAO;AAC5B,iBAAW,EAAE,MAAM,UAAU,KAAK,OAAO,CAAC;AAC1C,WAAK,eAAe,QAAQ,KAAK;AAAA,IACnC;AAAA,IACA,oBAAoB,QAAQ,OAAO;AACjC,iBAAW,EAAE,MAAM,eAAe,KAAK,OAAO,CAAC;AAC/C,WAAK,oBAAoB,QAAQ,KAAK;AAAA,IACxC;AAAA,IACA,wBAAwB,SAAS;AAC/B,iBAAW,EAAE,MAAM,mBAAmB,KAAK,QAAQ,SAAS,CAAC;AAC7D,WAAK,wBAAwB,OAAO;AAAA,IACtC;AAAA,IACA,gBAAgB,SAAS;AACvB,iBAAW,SAAS,SAAS,UAAU,CAAC,GAAG;AACzC,mBAAW,EAAE,MAAM,mBAAmB,KAAK,MAAM,KAAK,CAAC;AAAA,MACzD;AACA,aAAO,KAAK,gBAAgB,OAAO;AAAA,IACrC;AAAA,IACA,oBAAoB,OAAO;AACzB,iBAAW,EAAE,MAAM,eAAe,KAAK,MAAM,KAAK,CAAC;AACnD,WAAK,oBAAoB,KAAK;AAAA,IAChC;AAAA,IACA,sBAAsB,OAAO;AAM3B,aAAO,KAAK,sBAAsB,KAAK;AAAA,IACzC;AAAA,IACA,eAAe,MAAM;AACnB,WAAK,eAAe,IAAI;AACxB,iBAAW,EAAE,MAAM,kBAAkB,KAAK,SAAS,CAAC;AAAA,IACtD;AAAA,IACA,cAAc,MAAM;AAClB,WAAK,cAAc,IAAI;AACvB,iBAAW,EAAE,MAAM,iBAAiB,KAAK,QAAQ,CAAC;AAAA,IACpD;AAAA,EACF;AACF;AA6BO,SAAS,MAAM,OAA8B;AAClD,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,WAAW,EAAG,QAAO;AAC9D,MAAI,OAAO,EAAE,aAAa,WAAY,QAAO;AAC7C,MAAI,EAAE,aAAa,UAAa,EAAE,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAI,QAAO;AACvH,MAAI,EAAE,aAAa,UAAa,OAAO,EAAE,aAAa,SAAU,QAAO;AACvE,SAAO;AACT;;;AtC3vBO,IAAMC,UAA8C,IAAI,SAAS,cAAc,EAAE,GAAG,IAAI;AACxF,IAAMC,SAA2C,IAAI,SAAS,aAAa,EAAE,GAAG,IAAI;AAsGpF,IAAMC,iBAA4D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC7G,IAAMC,iBAA2D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC5G,IAAMC,iBAAmE,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AACpH,IAAMC,iBAA6D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC9G,IAAMC,kBAA+D,IAAI,SAAS,sBAAsB,EAAE,GAAG,IAAI;AACjH,IAAMC,cAAuD,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AACrG,IAAMC,aAAqD,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AAClG,IAAMC,iBAA6D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC9G,IAAMC,kBAA+D,IAAI,SAAS,sBAAsB,EAAE,GAAG,IAAI;AACjH,IAAMC,iBAA6D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC9G,IAAMC,gBAAiE,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AACjH,IAAMC,cAA6D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AAC3G,IAAMC,eAA+D,IAAI,SAAS,mBAAmB,EAAE,GAAG,IAAI;AAC9G,IAAMC,cAA6D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AAC3G,IAAMC,YAAyD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AACrG,IAAMC,YAAyD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AACrG,IAAMC,cAA6D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AAC3G,IAAMC,WAAoD,IAAI,SAAS,eAAe,EAAE,GAAG,IAAI;AAC/F,IAAMC,YAAsD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AAClG,IAAMC,WAAoD,IAAI,SAAS,eAAe,EAAE,GAAG,IAAI;AAC/F,IAAMC,SAAgD,IAAI,SAAS,aAAa,EAAE,GAAG,IAAI;AACzF,IAAMC,aAAwD,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AACrG,IAAMC,WAAoD,IAAI,SAAS,eAAe,EAAE,GAAG,IAAI;AAC/F,IAAMC,cAA0D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AACxG,IAAMC,eAA4D,IAAI,SAAS,mBAAmB,EAAE,GAAG,IAAI;AAC3G,IAAMC,aAAwD,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AACrG,IAAMC,cAA0D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AACxG,IAAMC,eAA4D,IAAI,SAAS,mBAAmB,EAAE,GAAG,IAAI;AAC3G,IAAMC,iBAAgE,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AACjH,IAAMC,cAA0D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AACxG,IAAMC,aAAwD,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AACrG,IAAMC,SAA8C,IAAI,SAAS,aAAa,EAAE,GAAG,IAAI;AACvF,IAAMC,QAA4C,IAAI,SAAS,YAAY,EAAE,GAAG,IAAI;AACpF,IAAMC,YAAoD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AAChG,IAAMC,gBAAiE,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AACjH,IAAMC,iBAAmE,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AACpH,IAAMC,gBAAiE,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AACjH,IAAMC,iBAAmE,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AACpH,IAAMC,wBAAiF,IAAI,SAAS,4BAA4B,EAAE,GAAG,IAAI;AACzI,IAAMC,uBAA+E,IAAI,SAAS,2BAA2B,EAAE,GAAG,IAAI;AACtI,IAAMC,iBAAmE,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AACpH,IAAMC,sBAA6E,IAAI,SAAS,0BAA0B,EAAE,GAAG,IAAI;AACnI,IAAMC,sBAA6E,IAAI,SAAS,0BAA0B,EAAE,GAAG,IAAI;AACnI,IAAMC,qBAA2E,IAAI,SAAS,yBAAyB,EAAE,GAAG,IAAI;AAChI,IAAMC,YAAyD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AACrG,IAAMC,aAA2D,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AACxG,IAAMC,yBAA8E,IAAI,SAAS,6BAA6B,EAAE,GAAG,IAAI;AACvI,IAAMC,iBAA8D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC/G,IAAMC,oBAAoE,IAAI,SAAS,wBAAwB,EAAE,GAAG,IAAI;AACxH,IAAMC,qBAAsE,IAAI,SAAS,yBAAyB,EAAE,GAAG,IAAI;AAC3H,IAAMC,mBAAkE,IAAI,SAAS,uBAAuB,EAAE,GAAG,IAAI;AACrH,IAAMC,mBAAkE,IAAI,SAAS,uBAAuB,EAAE,GAAG,IAAI;AACrH,IAAMC,oBAAoE,IAAI,SAAS,wBAAwB,EAAE,GAAG,IAAI;AACxH,IAAMC,aAA4D,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AACzG,IAAMC,aAA4D,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AACzG,IAAMC,gBAA0D,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AAC1G,IAAMC,mBAAgE,IAAI,SAAS,uBAAuB,EAAE,GAAG,IAAI;AACnH,IAAMC,0BAAuF,IAAI,SAAS,8BAA8B,EAAE,GAAG,IAAI;AACjJ,IAAMC,YAAoD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AAChG,IAAMC,YAAoD,IAAI,SAAS,gBAAgB,EAAE,GAAG,IAAI;AAChG,IAAMC,gBAA4D,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AAC5G,IAAMC,SAA8C,IAAI,SAAS,aAAa,EAAE,GAAG,IAAI;AACvF,IAAMC,kBAAgE,IAAI,SAAS,sBAAsB,EAAE,GAAG,IAAI;AAClH,IAAMC,sBAAwE,IAAI,SAAS,0BAA0B,EAAE,GAAG,IAAI;AAC9H,IAAMC,WAAoD,IAAI,SAAS,eAAe,EAAE,GAAG,IAAI;AAC/F,IAAMC,cAA0D,IAAI,SAAS,kBAAkB,EAAE,GAAG,IAAI;AACxG,IAAMC,eAA4D,IAAI,SAAS,mBAAmB,EAAE,GAAG,IAAI;AAC3G,IAAMC,0BAAwF,IAAI,SAAS,8BAA8B,EAAE,GAAG,IAAI;AAClJ,IAAMC,wBAAoF,IAAI,SAAS,4BAA4B,EAAE,GAAG,IAAI;AAC5I,IAAMC,eAA0D,IAAI,SAAS,mBAAmB,EAAE,GAAG,IAAI;AACzG,IAAMC,mBAAkE,IAAI,SAAS,uBAAuB,EAAE,GAAG,IAAI;AACrH,IAAMC,gBAA4D,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AAC5G,IAAMC,qBAAsE,IAAI,SAAS,yBAAyB,EAAE,GAAG,IAAI;AAC3H,IAAMC,yBAA8E,IAAI,SAAS,6BAA6B,EAAE,GAAG,IAAI;AACvI,IAAMC,uBAA0E,IAAI,SAAS,2BAA2B,EAAE,GAAG,IAAI;AACjI,IAAMC,uBAAyE,IAAI,SAAS,2BAA2B,EAAE,GAAG,IAAI;AAChI,IAAMC,gBAA2D,IAAI,SAAS,oBAAoB,EAAE,GAAG,IAAI;AAC3G,IAAMC,wBAA2E,IAAI,SAAS,4BAA4B,EAAE,GAAG,IAAI;AACnI,IAAMC,iBAA6D,IAAI,SAAS,qBAAqB,EAAE,GAAG,IAAI;AAC9G,IAAMC,aAAqD,IAAI,SAAS,iBAAiB,EAAE,GAAG,IAAI;AAClG,IAAMC,gCAA2F,IAAI,SAAS,oCAAoC,EAAE,GAAG,IAAI;","names":["addDays","balanceDuration","between","ceil","clamp","compareDuration","compileFormat","compileParser","createBusinessCalendar","createConfig","daysInYear","difference","explainFormat","fieldForToken","floor","format","formatDurationToParts","formatISODuration","formatRFC3339","formatRRule","formatRangeToParts","formatSQL","fromUnixMicroseconds","fromUnixNanoseconds","getAutocompleteData","getDocUrl","getHoverDocs","getInlineDiagnostics","getLocale","getMonth","getNextTransition","getPreviousTransition","getWeekday","hasLocale","intersection","interval","isAfter","isBefore","isBetween","isEqual","isLeapMonth","isLeapYear","isSameDay","isSameMonth","isSameQuarter","isSameWeek","isSameYear","isToday","isTomorrow","isValidFormat","isWeekday","isYesterday","listRegisteredGrammars","listTokens","mergeIntervals","mergeWithConfig","monthsInYear","nextHoliday","overlaps","parse","parseDuration","parseHTTPDate","parseISODuration","parseRFC2822","parseRFC3339","parseRRule","parseRelative","parseSQL","possibleInstantsFor","previewFormat","previousHoliday","resolveZoned","subtract","subtractBusinessDays","subtractDuration","toUnixMicroseconds","toUnixMilliseconds","toUnixNanoseconds","toUnixSeconds","tokenInfo","tokenizeFormat","translateDateFnsFormatString","truncate","union","validateFormat","weekOfYear","weekYear","format","min","max","escapeRegExp","name","MAX_CACHE_SIZE","requireFields","daysInYear","MS_PER_HOUR","MS_PER_MINUTE","MS_PER_SECOND","weekdayOf","MS_PER_DAY","format","appendLiteral","DURATION_TOKEN_STRINGS","appendLiteral","MAX_LOCALE_TAG_LENGTH","isBefore","isAfter","toMs","fromMs","MS_PER_DAY","recomputeDayOfWeek","MS_PER_DAY","MS_PER_HOUR","MS_PER_MINUTE","MS_PER_SECOND","subtract","addDays","difference","day","interval","advanced","REFERENCE_YEAR","rtfCache","MAX_RTF_CACHE_SIZE","getRtf","appendLiteral","format","parse","compileFormat","compileParser","parseRelative","explainFormat","tokenizeFormat","listTokens","tokenInfo","isValidFormat","validateFormat","fieldForToken","monthsInYear","isLeapYear","isLeapMonth","weekOfYear","weekYear","getMonth","getWeekday","isEqual","isBefore","isAfter","clamp","isBetween","isToday","isTomorrow","isYesterday","isSameDay","isSameWeek","isSameMonth","isSameQuarter","isSameYear","isWeekday","floor","ceil","truncate","parseRFC3339","formatRFC3339","parseRFC2822","parseHTTPDate","fromUnixMicroseconds","fromUnixNanoseconds","toUnixSeconds","toUnixMilliseconds","toUnixMicroseconds","toUnixNanoseconds","parseSQL","formatSQL","formatDurationToParts","parseDuration","parseISODuration","formatISODuration","balanceDuration","compareDuration","subtractDuration","getLocale","hasLocale","createConfig","mergeWithConfig","listRegisteredGrammars","interval","overlaps","intersection","union","mergeIntervals","formatRangeToParts","between","parseRRule","formatRRule","createBusinessCalendar","subtractBusinessDays","nextHoliday","previousHoliday","resolveZoned","getNextTransition","getPreviousTransition","possibleInstantsFor","getAutocompleteData","getHoverDocs","getInlineDiagnostics","previewFormat","getDocUrl","translateDateFnsFormatString"]}