@vielzeug/codex 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/data/catalog.json +139 -130
  2. package/data/llms-full.txt +13091 -17593
  3. package/data/llms.txt +12 -11
  4. package/data/manifest.json +1 -1
  5. package/data/packages/arsenal.json +1 -1
  6. package/data/packages/assay.json +1 -1
  7. package/data/packages/clockwork.json +2 -2
  8. package/data/packages/codex.json +1 -1
  9. package/data/packages/coins.json +1 -1
  10. package/data/packages/conduit.json +1 -1
  11. package/data/packages/courier.json +1 -1
  12. package/data/packages/dnd.json +14 -12
  13. package/data/packages/familiar.json +26 -16
  14. package/data/packages/flux.json +1 -1
  15. package/data/packages/forge.json +1 -1
  16. package/data/packages/herald.json +19 -33
  17. package/data/packages/keymap.json +13 -19
  18. package/data/packages/ledger.json +28 -25
  19. package/data/packages/lingua.json +30 -28
  20. package/data/packages/necromancer.json +50 -0
  21. package/data/packages/orbit.json +34 -39
  22. package/data/packages/ore.json +1 -1
  23. package/data/packages/prism.json +37 -40
  24. package/data/packages/pulse.json +26 -24
  25. package/data/packages/refine.json +1 -1
  26. package/data/packages/ripple.json +1 -1
  27. package/data/packages/rune.json +6 -7
  28. package/data/packages/sandbox.json +7 -6
  29. package/data/packages/scout.json +10 -10
  30. package/data/packages/scroll.json +18 -17
  31. package/data/packages/sourcerer.json +1 -1
  32. package/data/packages/spell.json +1 -1
  33. package/data/packages/tempo.json +49 -81
  34. package/data/packages/vault.json +37 -40
  35. package/data/packages/ward.json +5 -17
  36. package/data/packages/wayfinder.json +9 -9
  37. package/data/refine.json +4914 -4914
  38. package/data/search.json +210 -211
  39. package/dist/cli.js +1 -1
  40. package/dist/cli.js.map +1 -1
  41. package/dist/http.js +46 -6
  42. package/dist/http.js.map +1 -1
  43. package/dist/server.js +1 -1
  44. package/dist/server.js.map +1 -1
  45. package/dist/tools/index.js +13 -5
  46. package/dist/tools/index.js.map +1 -1
  47. package/package.json +4 -4
@@ -1,51 +1,16 @@
1
1
  {
2
- "apiSource": "// Re-export Temporal namespace so consumers never need to import @js-temporal/polyfill directly.\nexport { Temporal } from '@js-temporal/polyfill';\n\n// ─── Errors ───────────────────────────────────────────────────────────────────\nexport {\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n} from './errors';\n\n// ─── Core ─────────────────────────────────────────────────────────────────────\nexport {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';\n\n// ─── Conversion utilities ─────────────────────────────────────────────────────\nexport { inTz, toInstant } from './_convert';\n\n// ─── Boundary ─────────────────────────────────────────────────────────────────\nexport { endOf, startOf } from './boundary';\n\n// ─── Compare ──────────────────────────────────────────────────────────────────\nexport { clamp, isAfter, isBefore, isSame, within } from './compare';\n\n// ─── Format ───────────────────────────────────────────────────────────────────\nexport {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';\n\n// ─── Classify ─────────────────────────────────────────────────────────────────\nexport { expires, timeDiff } from './classify';\n\n// ─── Range ────────────────────────────────────────────────────────────────────\nexport { dateRange, recurrence } from './range';\n\n// ─── Public types ─────────────────────────────────────────────────────────────\nexport type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';\n",
2
+ "apiSource": "// Tempo keeps this re-export so all consumers share one Temporal implementation and version.\nexport { Temporal } from '@js-temporal/polyfill';\n\nexport {\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n} from './errors';\nexport { difference, isValid, now, nowInstant, parse, shift } from './core';\nexport { inTimeZone, toInstant } from './_convert';\nexport { endOf, startOf } from './boundary';\nexport { clamp, contains, isAfter, isBefore, isSame } from './compare';\nexport {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';\nexport { classifyExpiry, timeDiff } from './classify';\nexport { dateRange, recurrence } from './range';\nexport type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';\n",
3
3
  "docs": {
4
- "index": "---\ntitle: Tempo — Temporal date and time utilities\ndescription: Temporal-powered parsing, timezone conversion, arithmetic (DST-safe), and Intl formatting for modern TypeScript.\npackage: tempo\ncategory: time\nkeywords: [temporal, date-time, timezone, formatting, arithmetic, dst, intl, calendar]\nrelated: [arsenal]\nexports:\n [\n now,\n nowInstant,\n parse,\n parsePlainDate,\n parsePlainDateTime,\n parseInstant,\n parseZoned,\n isValid,\n toInstant,\n inTz,\n shift,\n difference,\n within,\n clamp,\n isBefore,\n isAfter,\n isSame,\n startOf,\n endOf,\n format,\n formatParts,\n formatRange,\n formatRangeParts,\n formatInstant,\n formatZoned,\n formatRelative,\n parseDuration,\n formatDuration,\n expires,\n timeDiff,\n humanize,\n dateRange,\n recurrence,\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n ]\nenvironments: [browser, node, ssr, deno]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"tempo\" />\n\n## Why Tempo?\n\nManual date handling breaks at daylight-saving boundaries, timezone edges, and DST transitions.\n\n```ts\n// Before — fragile, loses timezone context\nconst reminder = new Date(meeting.getTime() - 15 * 60_000);\n\n// After DST-safe, handles transitions correctly\nconst reminder = shift(meeting, { minutes: -15 });\n```\n\n| Feature | Tempo | date-fns | Day.js | Native Date |\n| -------------- | ---------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------ | -------------------------------------- |\n| Bundle size | <PackageInfo package=\"tempo\" type=\"size\" /> | ~10 kB | ~3 kB | 0 kB |\n| DST-safe math | <ore-icon name=\"check\" size=\"16\"></ore-icon> (Temporal) | Manual | Manual | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Timezone aware | <ore-icon name=\"check\" size=\"16\"></ore-icon> Full support | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Partial |\n| Immutable | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Format presets | <ore-icon name=\"check\" size=\"16\"></ore-icon> (`'short'`, `'medium'`, `'long'`, etc.) | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Type inference | <ore-icon name=\"check\" size=\"16\"></ore-icon> Full TypeScript | Partial | Partial | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n\n<div class=\"decision-callout\">\n\n**Use Tempo when** you need reliable timezone handling, DST-safe arithmetic, and clean Temporal-based APIs without heavy dependencies.\n\n**Consider alternatives when** you need extensive locale data (date-fns).\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/tempo\n```\n\n```sh [npm]\nnpm install @vielzeug/tempo\n```\n\n```sh [yarn]\nyarn add @vielzeug/tempo\n```\n\n:::\n\n## Quick Start\n\n```ts\nimport { format, formatInstant, inTz, parsePlainDateTime, shift, toInstant } from '@vielzeug/tempo';\n\n// Parse a wall-clock string (no timezone attached)\nconst localMeeting = parsePlainDateTime('2026-03-21T10:30:00');\n\n// Convert to an absolute instant using the user's timezone\nconst meetingInstant = toInstant(localMeeting, { tz: 'America/New_York' });\n\n// Project to a zoned view and subtract 15 minutes (DST-safe)\nconst meetingNY = inTz(meetingInstant, 'America/New_York');\nconst reminder = shift(meetingNY, { minutes: -15 });\n\n// Format for display\nconst text = format(reminder, { pattern: 'short', locale: 'en-US', tz: 'America/New_York' });\n\n// Format for APIs/logs (stable UTC instant string)\nconst stable = formatInstant(reminder);\n```\n\n> **No `Temporal.*` imports needed.** Tempo re-exports `Temporal` and provides `parseInstant`, `parseZoned`, `parsePlainDateTime`, `parsePlainDate`, `nowInstant`, and `now` as drop-in replacements for every common Temporal constructor. Use `parse(input, as?)` for flexible input detection.\n\n## Features\n\n<div class=\"features-grid\">\n\n- **Zero Temporal imports** — `parseInstant()`, `parseZoned()`, `parsePlainDateTime()`, `parsePlainDate()`, `nowInstant()`, `now()` replace every common `Temporal.*` constructor; import only from `@vielzeug/tempo`\n- **DST-safe arithmetic** — `shift()` handles transitions correctly; always returns `ZonedDateTime` (call `.toInstant()` if needed)\n- **Timezone conversion** `inTz()` to project any input into a timezone, `toInstant()` to normalize to UTC; invalid timezone strings throw `TempoError`\n- **Formatting split by intent** — `format()` for UI (with presets and `intl` escape hatch), `formatInstant()` for UTC strings, `formatZoned()` for zoned strings\n- **Relative and range formatting** — `formatRelative()` for UX copy, `formatRange()` / `formatRangeParts()` for localized time spans, `formatParts()` for custom rendering\n- **Range + comparison helpers** — `within()`, `clamp()`, `isBefore()`, `isAfter()`, `isSame()` with calendar-unit and week-start support\n- **Boundary helpers** `startOf()` and `endOf()` for day/week/month/year-style snapping\n- **Duration tools** — `difference()`, `parseDuration()`, `formatDuration()`\n- **Expiry classification** — `expires()` for flexible threshold-based TTL bucketing; `timeDiff()` for structured time differences; `humanize()` for human-readable output\n- **Recurrence generation** — `recurrence()` for lazily generating repeating dates (daily/weekly/monthly/yearly); `dateRange()` for step-based date sequences; timezone inferred from `ZonedDateTime` inputs\n- **Intl integration** formatting respects locale and calendar systems\n- **Polyfilled Temporal** — works in runtimes without native support via `@js-temporal/polyfill`\n- <PackageInfo package=\"tempo\" type=\"size\" /> gzipped\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Spell](/spell/) — schema validation with a similar `v` namespace pattern; combine with Tempo's date validators for typed form fields that accept date strings\n- [Rune](/rune/) — structured logger; use Tempo to format timestamps consistently in log entries and audit trails\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
5
- "api": "---\ntitle: Tempo — API Reference\ndescription: Complete API reference for @vielzeug/tempo date/time functions.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Common gotcha |\n| ---------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |\n| `now(tz)` | Current zoned date/time | Requires a valid IANA timezone string |\n| `nowInstant()` | Current UTC instant | Use instead of `Temporal.Now.instant()` |\n| `parse(input, as?)` | Parse any ISO 8601 string; `as` pins the return type | Without `as`, auto-detects: ZonedDateTime → Instant → PlainDateTime → PlainDate |\n| `parseInstant(input)` | Parse a UTC ISO string to `Instant` | Input must end in `Z` or include an offset |\n| `parseZoned(input)` | Parse a zoned ISO string to `ZonedDateTime` | Must include offset and timezone (`[Region/City]`) |\n| `parsePlainDateTime(input)` | Parse a wall-clock string to `PlainDateTime` | No timezone attached — use `toInstant()` to pin it |\n| `parsePlainDate(input)` | Parse a date-only string to `PlainDate` | Use instead of `Temporal.PlainDate.from()` |\n| `isValid(value)` | Type guard for any `TimeInput` | Returns `false` for strings, numbers, and `null` |\n| `toInstant(input, options?)` | Normalize any input to a UTC instant | Plain inputs require `options.tz` |\n| `inTz(input, tz)` | Project any input into a specific timezone | Returns `ZonedDateTime`; re-projects `ZonedDateTime` inputs (wall-clock changes) |\n| `shift(input, duration, options?)` | DST-safe add/subtract | `options.tz` required for plain/instant inputs |\n| `difference(start, end, options?)` | Duration between two values | Requires `tz` only for calendar units or plain inputs |\n| `within(value, start, end, options?)` | Inclusive range check | Bounds auto-normalized; use `unit` for calendar checks |\n| `clamp(value, start, end, options?)` | Clamp to `[start, end]`; see notes for return type | With `unit` + `ZonedDateTime` input, returns `ZonedDateTime`; otherwise `Instant` |\n| `isBefore(a, b, options?)` | Returns `true` when `a` is earlier than `b` | Omit `unit` for raw timeline comparison |\n| `isAfter(a, b, options?)` | Returns `true` when `a` is later than `b` | Omit `unit` for raw timeline comparison |\n| `isSame(a, b, options?)` | Returns `true` when `a` and `b` are equal | Set `unit` for calendar-unit equality |\n| `startOf(input, unit, options?)` | Snap to start of a calendar unit | Week boundaries depend on `weekStartsOn` (default Monday) |\n| `endOf(input, unit, options?)` | Snap to end of a calendar unit | Returns 1 nanosecond before the next unit starts |\n| `format(input, options?)` | Localized display formatting with presets | `intl` and `pattern` are mutually exclusive |\n| `formatParts(input, options?)` | Raw `Intl.DateTimeFormatPart[]` for custom rendering | Same options as `format()` |\n| `formatInstant(input, options?)` | UTC ISO-8601 instant string | Always UTC regardless of input zone |\n| `formatZoned(input, options?)` | Zoned ISO-8601 string | `options.tz` required for non-zoned inputs |\n| `formatRange(start, end, options?)` | Localized time-span string | Throws when zoned inputs are in different zones without `tz` |\n| `formatRangeParts(start, end, options?)` | Raw `Intl.DateTimeRangeFormatPart[]` array | Same zone-mismatch rules as `formatRange()` |\n| `formatRelative(input, options?)` | UX relative text (\"in 2 hours\", \"3 days ago\") | Input restricted to `Instant` or `ZonedDateTime` |\n| `parseDuration(input)` | Parse ISO 8601 duration or `DurationLike` object | Throws `TempoError` for invalid strings |\n| `formatDuration(input, options?)` | Format a duration for display | Falls back to plain English if `Intl.DurationFormat` absent |\n| `expires(date, thresholds, options?)` | Classify a date against named threshold buckets | Returns `null` when no threshold matches; define thresholds at module scope for best perf |\n| `timeDiff(a, b?, options?)` | Largest-unit difference as `{ unit, value }` | No `tz` needed when both inputs are `Instant` |\n| `humanize(diff, options?)` | `TimeDiffResult` → human-readable string | English-only; use `formatRelative()` for localized output |\n| `dateRange(start, end, step, options?)` | Lazy generator of `ZonedDateTime` values | `step` must advance time forward; `tz` inferred from `ZonedDateTime`, required otherwise |\n| `recurrence(start, rule, options?)` | Lazy generator for repeating dates | `count` or `until` required; `tz` inferred from `ZonedDateTime` start |\n| `TempoError` | Base error class thrown by all tempo functions | `instanceof TempoError` catches every subtype below |\n| `TempoInvalidInputError` | Subtype — parse/duration input could not be understood | Thrown by `parse()`, `parseInstant()`, `parseZoned()`, `parsePlainDate()`, `parsePlainDateTime()`, `parseDuration()` |\n| `TempoInvalidTzError` | Subtype — timezone string is not a valid IANA name or offset | Thrown by any function that resolves a `tz` string |\n| `TempoMissingTzError` | Subtype — operation needs a timezone but none could be inferred | Thrown when a plain input is passed without `options.tz` |\n| `TempoUnsupportedInputError` | Subtype — input value is not a recognised `TimeInput` | Thrown by `toInstant()` for non-`TimeInput` values |\n\n## Package Entry Point\n\n```ts\nimport {\n Temporal,\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n clamp,\n dateRange,\n difference,\n endOf,\n expires,\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n inTz,\n isAfter,\n isBefore,\n isSame,\n isValid,\n now,\n nowInstant,\n parse,\n parseDuration,\n parseInstant,\n parsePlainDateTime,\n parsePlainDate,\n parseZoned,\n recurrence,\n shift,\n startOf,\n timeDiff,\n toInstant,\n within,\n} from '@vielzeug/tempo';\n```\n\n`Temporal` is re-exported directly — consumers never need to import `@js-temporal/polyfill` themselves. Use `parse(input, as?)` for flexible input detection, or the specific helpers (`parseInstant`, `parseZoned`, `parsePlainDateTime`, `parsePlainDate`) when the input format is known.\n\n## Core Functions\n\n### `now(tz): Temporal.ZonedDateTime`\n\n```ts\nnow(tz: string): Temporal.ZonedDateTime;\n```\n\nReturns the current time as a `ZonedDateTime` in `tz`.\n\n**Example:**\n\n```ts\nimport { now } from '@vielzeug/tempo';\n\nnow('UTC');\nnow('Europe/Berlin');\nnow('Asia/Tokyo');\n```\n\n---\n\n### `nowInstant(): Temporal.Instant`\n\n```ts\nnowInstant(): Temporal.Instant;\n```\n\nReturns the current absolute instant (UTC point in time). Use this instead of `Temporal.Now.instant()` so your code only imports from `@vielzeug/tempo`.\n\n**Example:**\n\n```ts\nimport { expires, nowInstant, timeDiff } from '@vielzeug/tempo';\n\n// Snapshot the current instant\nconst t = nowInstant();\n\ntimeDiff(t); // { unit: 'millisecond', value: 0 }\nexpires(t, { expired: { days: 0 }, safe: { years: 100 } }); // 'safe'\n```\n\n---\n\n### `parseZoned(input): Temporal.ZonedDateTime`\n\n```ts\nparseZoned(input: string): Temporal.ZonedDateTime;\n```\n\nParses a full ISO 8601 zoned date-time string (must include both offset and `[Region/City]` identifier) into a `ZonedDateTime`. Throws a descriptive `[tempo]` error on invalid input. Use instead of `Temporal.ZonedDateTime.from()`.\n\n**Example:**\n\n```ts\nimport { parseZoned } from '@vielzeug/tempo';\n\nparseZoned('2026-03-21T11:00:00+01:00[Europe/Berlin]');\nparseZoned('2026-03-21T00:00:00[UTC]');\n```\n\n---\n\n### `parsePlainDate(input): Temporal.PlainDate`\n\n```ts\nparsePlainDate(input: string): Temporal.PlainDate;\n```\n\nParses an ISO 8601 date-only string into a timezone-free `PlainDate`. Use this instead of `Temporal.PlainDate.from()`. Pair with `inTz()` or `toInstant()` when a timezone is needed.\n\n**Example:**\n\n```ts\nimport { inTz, parsePlainDate } from '@vielzeug/tempo';\n\nparsePlainDate('2026-03-21'); // 2026-03-21\n\n// Attach a timezone when needed\ninTz(parsePlainDate('2026-03-21'), 'America/New_York');\n```\n\n---\n\n### `parsePlainDateTime(input): Temporal.PlainDateTime`\n\n```ts\nparsePlainDateTime(input: string): Temporal.PlainDateTime;\n```\n\nParses an ISO 8601 date or date-time string into a timezone-free `PlainDateTime`. Use this at the boundary where user input or database values arrive as wall-clock strings.\n\n**Example:**\n\n```ts\nimport { parsePlainDateTime } from '@vielzeug/tempo';\n\nparsePlainDateTime('2026-03-21'); // 2026-03-21T00:00:00\nparsePlainDateTime('2026-03-21T10:15:30'); // 2026-03-21T10:15:30\n```\n\n---\n\n### `parseInstant(input): Temporal.Instant`\n\n```ts\nparseInstant(input: string): Temporal.Instant;\n```\n\nParses a UTC ISO 8601 string into a `Temporal.Instant`. The input must include an offset or end in `Z`. Throws a `TempoError` with code `INVALID_INPUT` on invalid input.\n\n**Example:**\n\n```ts\nimport { parseInstant } from '@vielzeug/tempo';\n\nparseInstant('2026-03-21T10:15:30Z');\nparseInstant('2026-03-21T11:15:30+01:00');\n```\n\n---\n\n### `parse(input, as?): TimeInput`\n\n```ts\nparse(input: string, as: 'zoned'): Temporal.ZonedDateTime;\nparse(input: string, as: 'instant'): Temporal.Instant;\nparse(input: string, as: 'plain-datetime'): Temporal.PlainDateTime;\nparse(input: string, as: 'plain-date'): Temporal.PlainDate;\nparse(input: string, as?: ParseAs): TimeInput;\n```\n\nParses any ISO 8601 string. Without `as`, auto-detects the most specific type in order: `ZonedDateTime` → `Instant` → `PlainDateTime` → `PlainDate`. With `as`, the return type is narrowed at compile time. Throws a descriptive `[tempo]` error if parsing fails.\n\nThe `as` parameter accepts a `ParseAs` value: `'zoned' | 'instant' | 'plain-datetime' | 'plain-date'`.\n\n**Example:**\n\n```ts\nimport { parse } from '@vielzeug/tempo';\n\n// Auto-detect\nparse('2026-03-21T11:00:00+01:00[Europe/Berlin]'); // Temporal.ZonedDateTime\nparse('2026-03-21T10:00:00Z'); // Temporal.Instant\nparse('2026-03-21T10:00:00'); // Temporal.PlainDateTime\nparse('2026-03-21'); // Temporal.PlainDate\n\n// Typed overloads — return type is narrowed\nparse('2026-03-21T10:00:00Z', 'instant'); // Temporal.Instant\nparse('2026-03-21', 'plain-date'); // Temporal.PlainDate\n```\n\n---\n\n### `isValid(value): value is TimeInput`\n\n```ts\nisValid(value: unknown): value is TimeInput;\n```\n\nType guard that returns `true` when `value` is a valid `Temporal.Instant`, `ZonedDateTime`, `PlainDateTime`, or `PlainDate`.\n\n**Example:**\n\n```ts\nimport { isValid, parseInstant } from '@vielzeug/tempo';\n\nisValid(parseInstant('2026-03-21T10:00:00Z')); // true\nisValid('2026-03-21'); // false\nisValid(null); // false\n```\n\n---\n\n### `toInstant(input, options?): Temporal.Instant`\n\n```ts\ntoInstant(input: TimeInput, options?: TimeOptions): Temporal.Instant;\n```\n\nNormalizes any `TimeInput` to an absolute `Temporal.Instant`.\n\n**Parameters — `TimeOptions`:**\n\n| Option | Type | Description |\n| ------ | -------- | -------------------------------------------------- |\n| `tz` | `string` | Required when input is `PlainDate`/`PlainDateTime` |\n\n**Example:**\n\n```ts\nimport { parseInstant, parsePlainDateTime, toInstant } from '@vielzeug/tempo';\n\ntoInstant(parseInstant('2026-03-21T10:15:30Z'));\ntoInstant(parsePlainDateTime('2026-03-21T10:15:30'), { tz: 'America/New_York' });\n```\n\n---\n\n### `inTz(input, tz): Temporal.ZonedDateTime`\n\n```ts\ninTz(input: TimeInput, tz: string): Temporal.ZonedDateTime;\n```\n\nProjects any `TimeInput` into `tz`. When `input` is already a `ZonedDateTime`, it is **re-projected** via `withTimeZone()` — the absolute instant is preserved but the wall-clock time changes.\n\n**Example:**\n\n```ts\nimport { inTz, parseInstant, parseZoned } from '@vielzeug/tempo';\n\ninTz(parseInstant('2026-03-21T10:15:30Z'), 'Europe/Berlin');\n// → 2026-03-21T11:15:30+01:00[Europe/Berlin]\n\n// ZonedDateTime re-projected — same instant, different wall clock\ninTz(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'), 'UTC');\n// → 2026-03-21T10:15:30+00:00[UTC]\n```\n\n---\n\n### `shift(input, duration, options?): Temporal.ZonedDateTime`\n\n```ts\n// ZonedDateTime input — tz inferred, options optional\nshift(input: Temporal.ZonedDateTime, duration: Temporal.DurationLike, options?: TimeOptions): Temporal.ZonedDateTime;\n\n// Instant / PlainDate / PlainDateTime — tz required\nshift(input: Temporal.Instant | Temporal.PlainDate | Temporal.PlainDateTime, duration: Temporal.DurationLike, options: ShiftOptions & { tz: string }): Temporal.ZonedDateTime;\n```\n\nAdds `duration` to `input` using DST-aware calendar arithmetic. Negative values subtract. **Always returns `Temporal.ZonedDateTime`** — call `.toInstant()` if you need an `Instant` back.\n\n**Parameters — `ShiftOptions` (extends `TimeOptions`):**\n\n| Option | Type | Default | Description |\n| -------- | ------------------------ | -------------- | ----------------------------------------------------- |\n| `tz` | `string` | — | Required for plain/instant inputs; inferred for zoned |\n| `prefer` | `DateTimeDisambiguation` | `'compatible'` | DST disambiguation for `PlainDateTime` inputs |\n\n**Example:**\n\n```ts\nimport { parseInstant, parseZoned, shift } from '@vielzeug/tempo';\n\n// Zoned input — timezone inferred\nshift(parseZoned('2026-03-08T01:30:00-05:00[America/New_York]'), { hours: 1 });\n// → 2026-03-08T03:30:00-04:00[America/New_York] (DST spring-forward handled)\n\n// Instant input — timezone required\nshift(parseInstant('2026-03-21T10:00:00Z'), { days: 1 }, { tz: 'UTC' });\n```\n\n---\n\n### `difference(start, end, options?): Temporal.Duration`\n\n```ts\ndifference(start: TimeInput, end: TimeInput, options?: DifferenceOptions): Temporal.Duration;\n```\n\nReturns the signed duration from `start` to `end`. When `start > end` the result is negative.\n\n**Parameters — `DifferenceOptions`:**\n\n| Option | Type | Default | Description |\n| ------------------- | ------------------------ | -------------- | ------------------------------------------- |\n| `tz` | `string` | — | Required for plain inputs or calendar units |\n| `largestUnit` | `Temporal.DateTimeUnit` | `'second'` | Largest unit in the returned duration |\n| `smallestUnit` | `Temporal.DateTimeUnit` | `'second'` | Smallest unit; excess is rounded |\n| `roundingMode` | `Temporal.RoundingMode` | `'trunc'` | Rounding direction for `smallestUnit` |\n| `roundingIncrement` | `number` | `1` | Rounding granularity for `smallestUnit` |\n| `prefer` | `DateTimeDisambiguation` | `'compatible'` | DST disambiguation |\n\nTwo `Temporal.Instant` inputs with sub-day `largestUnit`/`smallestUnit` do not need `tz`. Calendar units (`day`, `week`, `month`, `year`) always require `tz`.\n\n**Example:**\n\n```ts\nimport { difference, parseInstant, parseZoned } from '@vielzeug/tempo';\n\n// Instant-to-instant, sub-day units — no tz needed\ndifference(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T12:30:00Z'), {\n largestUnit: 'hour',\n smallestUnit: 'minute',\n}); // PT2H30M\n\n// DST-correct day count across spring-forward\ndifference(\n parseZoned('2026-03-08T00:00:00-05:00[America/New_York]'),\n parseZoned('2026-03-09T00:00:00-04:00[America/New_York]'),\n { largestUnit: 'hour' },\n).hours; // 23 (one hour shorter due to DST)\n```\n\n## Query and Comparison\n\n### `within(value, start, end, options?): boolean`\n\n```ts\nwithin(value: TimeInput, start: TimeInput, end: TimeInput, options?: CompareOptions): boolean;\n```\n\nReturns `true` when `value` falls within `[start, end]` (inclusive). Bounds are automatically normalized, so `within(v, hi, lo)` behaves the same as `within(v, lo, hi)`.\n\nSet `options.unit` to compare on calendar-unit boundaries (e.g., same day, same week).\n\n**Example:**\n\n```ts\nimport { parseInstant, within } from '@vielzeug/tempo';\n\nconst lo = parseInstant('2026-03-21T10:00:00Z');\nconst hi = parseInstant('2026-03-21T12:00:00Z');\n\nwithin(parseInstant('2026-03-21T11:00:00Z'), lo, hi); // true\nwithin(lo, lo, hi); // true (inclusive)\nwithin(parseInstant('2026-03-22T05:00:00Z'), lo, hi, { unit: 'day', tz: 'UTC' }); // true\n```\n\n---\n\n### `clamp(value, start, end, options?): Temporal.Instant`\n\n```ts\nclamp(value: TimeInput, start: TimeInput, end: TimeInput, options?: CompareOptions): Temporal.Instant;\n```\n\nReturns `value` clamped to `[start, end]`. Returns a `Temporal.Instant` for non-zoned inputs. When `value` is a `ZonedDateTime` and `options.unit` is set, returns a `Temporal.ZonedDateTime` floored to the start of the clamped unit. Bounds are automatically normalized when `start > end`.\n\n**Example:**\n\n```ts\nimport { clamp, parseInstant } from '@vielzeug/tempo';\n\nconst lo = parseInstant('2026-03-21T10:00:00Z');\nconst hi = parseInstant('2026-03-21T12:00:00Z');\n\nclamp(parseInstant('2026-03-21T13:00:00Z'), lo, hi).toString(); // '2026-03-21T12:00:00Z'\nclamp(parseInstant('2026-03-23T05:00:00Z'), lo, hi, { unit: 'day', tz: 'America/New_York' });\n```\n\n---\n\n### `isBefore(a, b, options?): boolean`\n\n```ts\nisBefore(a: TimeInput, b: TimeInput, options?: CompareOptions): boolean;\n```\n\nReturns `true` when `a` is earlier than `b` on the timeline. Set `options.unit` for calendar-unit comparison.\n\n**Example:**\n\n```ts\nimport { isBefore, parseInstant } from '@vielzeug/tempo';\n\nisBefore(parseInstant('2026-03-21T23:30:00Z'), parseInstant('2026-03-22T00:15:00Z'), {\n unit: 'day',\n tz: 'UTC',\n}); // true — different UTC days\n```\n\n---\n\n### `isAfter(a, b, options?): boolean`\n\n```ts\nisAfter(a: TimeInput, b: TimeInput, options?: CompareOptions): boolean;\n```\n\nReturns `true` when `a` is later than `b` on the timeline. Set `options.unit` for calendar-unit comparison.\n\n**Example:**\n\n```ts\nimport { isAfter, parseInstant } from '@vielzeug/tempo';\n\nisAfter(parseInstant('2026-03-21T12:00:00Z'), parseInstant('2026-03-21T10:00:00Z')); // true\n```\n\n---\n\n### `isSame(a, b, options?): boolean`\n\n```ts\nisSame(a: TimeInput, b: TimeInput, options?: CompareOptions): boolean;\n```\n\nReturns `true` when `a` and `b` represent the same point or the same calendar unit. Infers timezone from `ZonedDateTime` inputs; throws when both are zoned in different zones and `options.tz` is omitted.\n\n**Example:**\n\n```ts\nimport { isSame, parseInstant } from '@vielzeug/tempo';\n\nisSame(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T10:00:00Z')); // true\n\n// Same calendar day in New York even though UTC dates differ\nisSame(parseInstant('2026-03-21T23:30:00Z'), parseInstant('2026-03-22T00:15:00Z'), {\n unit: 'day',\n tz: 'America/New_York',\n}); // true\n```\n\n## Boundary Helpers\n\n### `startOf(input, unit, options?): Temporal.ZonedDateTime`\n\n```ts\nstartOf(input: TimeInput, unit: BoundaryUnit, options?: BoundaryOptions): Temporal.ZonedDateTime;\n```\n\nSnaps `input` to the start of `unit`. For `ZonedDateTime` inputs, `options.tz` is inferred automatically.\n\n**Parameters — `BoundaryOptions`:**\n\n| Option | Type | Default | Description |\n| -------------- | -------------- | ------- | ------------------------------------ |\n| `tz` | `string` | — | Required for non-zoned inputs |\n| `weekStartsOn` | `WeekStartDay` | `1` | ISO weekday (1 = Monday, 7 = Sunday) |\n\nSupported units: `'minute'` · `'hour'` · `'day'` · `'week'` · `'month'` · `'year'`\n\n**Example:**\n\n```ts\nimport { parseInstant, startOf } from '@vielzeug/tempo';\n\nstartOf(parseInstant('2026-03-21T10:15:30Z'), 'day', { tz: 'UTC' });\n// → 2026-03-21T00:00:00+00:00[UTC]\n\nstartOf(parseInstant('2026-03-25T12:00:00Z'), 'week', { tz: 'UTC', weekStartsOn: 1 });\n// → 2026-03-23T00:00:00+00:00[UTC] (Monday)\n```\n\n---\n\n### `endOf(input, unit, options?): Temporal.ZonedDateTime`\n\n```ts\nendOf(input: TimeInput, unit: BoundaryUnit, options?: BoundaryOptions): Temporal.ZonedDateTime;\n```\n\nSnaps `input` to the last nanosecond of `unit` (`startOf(nextUnit) - 1ns`).\n\n**Example:**\n\n```ts\nimport { endOf, parseInstant } from '@vielzeug/tempo';\n\nendOf(parseInstant('2026-03-21T10:15:30Z'), 'day', { tz: 'UTC' });\n// → 2026-03-21T23:59:59.999999999+00:00[UTC]\n```\n\n## Formatting\n\n### `format(input, options?): string`\n\n```ts\nformat(input: TimeInput, options?: FormatOptions): string;\n```\n\nFormats `input` for display using `Intl.DateTimeFormat`. Use `pattern` for common presets or `intl` for a custom `Intl.DateTimeFormatOptions` object. `intl` and `pattern` are **mutually exclusive** — enforced at the type level.\n\n**Parameters — `FormatOptions` (discriminated union):**\n\n| Variant | Option | Type | Default | Description |\n| ---------------- | --------- | ---------------------------- | ------------- | -------------------------------------------------------- |\n| `pattern` branch | `pattern` | `FormatPattern` | `'medium'` | Preset shorthand |\n| `intl` branch | `intl` | `Intl.DateTimeFormatOptions` | — | Full `Intl` spec; mutually exclusive with `pattern` |\n| Both variants | `locale` | `Intl.LocalesArgument` | system locale | BCP 47 locale tag |\n| Both variants | `tz` | `string` | — | Inferred from `ZonedDateTime` inputs; required otherwise |\n\n**Patterns:**\n\n| Pattern | Equivalent |\n| ------------- | --------------------------------------------- |\n| `'short'` | `{ dateStyle: 'short', timeStyle: 'short' }` |\n| `'medium'` | `{ dateStyle: 'medium', timeStyle: 'short' }` |\n| `'long'` | `{ dateStyle: 'full', timeStyle: 'long' }` |\n| `'date-only'` | `{ dateStyle: 'short' }` |\n| `'time-only'` | `{ timeStyle: 'short' }` |\n\n**Example:**\n\n```ts\nimport { format, parseInstant } from '@vielzeug/tempo';\n\nformat(parseInstant('2026-03-21T10:15:30Z'), { pattern: 'short', locale: 'en-GB', tz: 'UTC' });\n// → '21/03/2026, 10:15'\n\n// Escape hatch: full Intl spec\nformat(parseInstant('2026-03-21T10:15:30Z'), {\n intl: { hour: '2-digit', minute: '2-digit', hour12: false },\n locale: 'en-US',\n tz: 'UTC',\n});\n// → '10:15'\n```\n\n---\n\n### `formatParts(input, options?): Intl.DateTimeFormatPart[]`\n\n```ts\nformatParts(input: TimeInput, options?: FormatOptions): Intl.DateTimeFormatPart[];\n```\n\nReturns the raw `Intl.DateTimeFormatPart[]` array for `input`, enabling custom rendering where individual parts (year, month, day, etc.) need to be styled or composed differently. Accepts the same options as `format()`.\n\n**Example:**\n\n```ts\nimport { formatParts, parseInstant } from '@vielzeug/tempo';\n\nconst parts = formatParts(parseInstant('2026-03-21T10:15:30Z'), { pattern: 'date-only', tz: 'UTC' });\n// [{ type: 'month', value: '3' }, { type: 'literal', value: '/' }, ...]\n```\n\n---\n\n### `formatInstant(input, options?): string`\n\n```ts\nformatInstant(input: TimeInput, options?: TimeOptions): string;\n```\n\nReturns a UTC ISO-8601 instant string (`YYYY-MM-DDTHH:mm:ssZ`). Use this for transport, logging, and APIs.\n\n**Example:**\n\n```ts\nimport { formatInstant, parseInstant } from '@vielzeug/tempo';\n\nformatInstant(parseInstant('2026-03-21T10:15:30Z'));\n// → '2026-03-21T10:15:30Z'\n```\n\n---\n\n### `formatZoned(input, options?): string`\n\n```ts\nformatZoned(input: TimeInput, options?: TimeOptions): string;\n```\n\nReturns a full zoned ISO-8601 string including offset and timezone ID. Infers timezone from `ZonedDateTime` inputs; requires `options.tz` for all other input types.\n\n**Example:**\n\n```ts\nimport { formatZoned, parseInstant, parseZoned } from '@vielzeug/tempo';\n\nformatZoned(parseInstant('2026-03-21T10:15:30Z'), { tz: 'Europe/Berlin' });\n// → '2026-03-21T11:15:30+01:00[Europe/Berlin]'\n\nformatZoned(parseZoned('2026-03-21T10:15:30+01:00[Europe/Berlin]'));\n// → '2026-03-21T10:15:30+01:00[Europe/Berlin]'\n```\n\n---\n\n### `formatRange(start, end, options?): string`\n\n```ts\nformatRange(start: TimeInput, end: TimeInput, options?: FormatOptions): string;\n```\n\nFormats a localized time span using `Intl.DateTimeFormat.formatRange`. Infers a shared timezone from `ZonedDateTime` inputs; throws if they are in different zones and `options.tz` is omitted.\n\n**Example:**\n\n```ts\nimport { formatRange, parseInstant } from '@vielzeug/tempo';\n\nformatRange(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T12:00:00Z'), {\n pattern: 'short',\n locale: 'en-US',\n tz: 'UTC',\n});\n// → '3/21/2026, 10:00 – 12:00 AM'\n```\n\n---\n\n### `formatRangeParts(start, end, options?): Intl.DateTimeRangeFormatPart[]`\n\n```ts\nformatRangeParts(\n start: TimeInput,\n end: TimeInput,\n options?: FormatOptions,\n): ReturnType<Intl.DateTimeFormat['formatRangeToParts']>;\n```\n\nReturns the raw `Intl.DateTimeRangeFormatPart[]` array for a time span, enabling fine-grained rendering of range start, end, and shared parts separately. Applies the same timezone-inference and mismatch-detection rules as `formatRange()`.\n\n**Example:**\n\n```ts\nimport { formatRangeParts, parseInstant } from '@vielzeug/tempo';\n\nconst parts = formatRangeParts(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T12:00:00Z'), {\n pattern: 'short',\n locale: 'en-US',\n tz: 'UTC',\n});\n// [{ type: 'month', value: '3', source: 'shared' }, ...]\n\n// Render only the start part\nconst startParts = parts.filter((p) => p.source === 'startRange' || p.source === 'shared');\n```\n\n---\n\n### `formatRelative(input, options?): string`\n\n```ts\nformatRelative(input: RelativeTimeInput, options?: RelativeFormatOptions): string;\n```\n\nReturns a UX-friendly relative time string (\"in 2 hours\", \"3 days ago\") using `Intl.RelativeTimeFormat`. When `options.base` is omitted, the current instant is used.\n\n**Parameters — `RelativeFormatOptions`:**\n\n| Option | Type | Default | Description |\n| --------- | -------------------------------- | -------- | -------------------------------------------------------- |\n| `base` | `RelativeTimeInput` | `now` | Reference point for the relative calculation |\n| `locale` | `Intl.LocalesArgument` | system | BCP 47 locale tag |\n| `numeric` | `Intl.RelativeTimeFormatNumeric` | `'auto'` | `'always'` forces \"1 day ago\"; `'auto'` uses \"yesterday\" |\n| `style` | `Intl.RelativeTimeFormatStyle` | `'long'` | `'short'` or `'narrow'` for compact labels |\n\nUnit selection uses approximate thresholds: differences under 60 s → `'second'`, under 60 min → `'minute'`, under 24 h → `'hour'`, under 7 d → `'day'`, under ~4.35 weeks → `'week'`, under 12 months → `'month'`, otherwise `'year'`. These thresholds use fixed second constants (1 month ≈ 30.4375 days) and do not account for DST — use `difference()` with `ZonedDateTime` inputs for calendar-accurate results.\n\n**Example:**\n\n```ts\nimport { formatRelative, parseInstant } from '@vielzeug/tempo';\n\nconst base = parseInstant('2026-03-21T10:00:00Z');\n\nformatRelative(parseInstant('2026-03-21T12:00:00Z'), { base, locale: 'en-US', numeric: 'always' });\n// → 'in 2 hours'\n\nformatRelative(parseInstant('2026-03-19T10:00:00Z'), { base, locale: 'en-US' });\n// → '2 days ago'\n```\n\n## Duration Helpers\n\n### `parseDuration(input): Temporal.Duration`\n\n```ts\nparseDuration(input: string | Temporal.DurationLike): Temporal.Duration;\n```\n\nParses an ISO 8601 duration string or a `Temporal.DurationLike` object into a `Temporal.Duration`. Throws `TempoError` with code `INVALID_INPUT` for invalid input.\n\n**Example:**\n\n```ts\nimport { parseDuration } from '@vielzeug/tempo';\n\nparseDuration('PT2H30M');\nparseDuration({ hours: 2, minutes: 30 });\nparseDuration('-PT1H'); // negative duration\n```\n\n---\n\n### `formatDuration(input, options?): string`\n\n```ts\nformatDuration(input: string | Temporal.DurationLike, options?: DurationFormatOptions): string;\n```\n\nFormats a duration for display. Uses `Intl.DurationFormat` when available; falls back to a plain English representation (\"2 hours, 30 minutes\").\n\n**Parameters — `DurationFormatOptions`:**\n\n| Option | Type | Default | Description |\n| -------- | -------------------------------------------- | -------- | ----------------- |\n| `locale` | `Intl.LocalesArgument` | system | BCP 47 locale tag |\n| `style` | `'digital' \\| 'long' \\| 'narrow' \\| 'short'` | `'long'` | Display style |\n\n**Example:**\n\n```ts\nimport { formatDuration } from '@vielzeug/tempo';\n\nformatDuration('PT2H30M', { locale: 'en-US', style: 'short' });\nformatDuration({ hours: 1, minutes: 30 }, { locale: 'de-DE' });\n```\n\n## Expiry and Classification\n\n### `expires(date, thresholds, options?, now?): K | null`\n\n```ts\nexpires<K extends string>(\n date: TimeInput,\n thresholds: Record<K, Temporal.DurationLike>,\n options?: TimeOptions,\n now?: Temporal.Instant,\n): K | null;\n```\n\nClassifies `date` into a named bucket by computing `diff = date − now` and returning the key of the first threshold where `diff ≤ threshold`. Thresholds are sorted ascending before comparison.\n\n- Returns `null` when no threshold matches.\n- Requires `options.tz` when input is `PlainDate` or `PlainDateTime`.\n- Pass `now` to fix the reference point (useful in tests).\n\n**Negative thresholds classify past dates.** A threshold of `{ days: -N }` matches dates that are more than N days in the _past_ (i.e. `diff ≤ -N days`). Use negative thresholds at the front of your map for \"expired\" or \"overdue\" buckets:\n\n```ts\nconst THRESHOLDS = {\n longExpired: { days: -30 }, // more than 30 days ago\n expired: { days: 0 }, // any past date (diff ≤ 0)\n critical: { days: 3 }, // within 3 days in the future\n warning: { days: 14 },\n safe: { years: 100 },\n} as const;\n```\n\n**Performance:** define threshold objects at module scope (not inline literals) so the internal `WeakMap` sort-cache is effective.\n\n**Example:**\n\n```ts\nimport { expires } from '@vielzeug/tempo';\n\nconst THRESHOLDS = {\n longExpired: { days: -30 }, // more than 30 days past\n expired: { days: 0 }, // any past date\n critical: { days: 3 }, // within 3 days\n warning: { days: 14 }, // within 14 days\n safe: { years: 100 }, // catch-all far future\n} as const;\n\nexpires(Temporal.Now.instant().subtract({ days: 60 }), THRESHOLDS); // 'longExpired'\nexpires(Temporal.Now.instant().subtract({ hours: 6 }), THRESHOLDS); // 'expired'\nexpires(Temporal.Now.instant().add({ hours: 48 }), THRESHOLDS); // 'critical'\nexpires(Temporal.Now.instant().add({ days: 10 }), THRESHOLDS); // 'warning'\nexpires(Temporal.Now.instant().add({ years: 1 }), THRESHOLDS); // 'safe'\n\n// No threshold matches — returns null\nexpires(Temporal.Now.instant().add({ years: 200 }), { soon: { days: 3 } }); // null\n```\n\n---\n\n### `timeDiff(a, b?, options?): TimeDiffResult`\n\n```ts\ntimeDiff(a: TimeInput, b?: TimeInput, options?: TimeOptions): TimeDiffResult;\n```\n\nReturns the absolute difference between `a` and `b` as `{ unit, value }` in the largest meaningful unit. When `b` is omitted, the current instant is used.\n\n**Timezone requirement:**\n\n- When both inputs are `Temporal.Instant`: no `tz` needed — uses millisecond arithmetic (1 day = 86 400 s).\n- When either input is `PlainDate`, `PlainDateTime`, or `ZonedDateTime`: `tz` is required (inferred from `ZonedDateTime` inputs).\n\nSub-second differences return `{ unit: 'millisecond', value: <ms> }`. Zero difference returns `{ unit: 'millisecond', value: 0 }`.\n\n**Example:**\n\n```ts\nimport { parseInstant, parseZoned, timeDiff } from '@vielzeug/tempo';\n\n// No tz needed for two Instants — uses ms arithmetic (1 year ≈ 365.25 days)\n// 2026-01 → 2027-06 ≈ 17 months; floor(17/12) = 1, so unit is 'year', value is 1\ntimeDiff(parseInstant('2026-01-01T00:00:00Z'), parseInstant('2027-06-01T00:00:00Z')); // { unit: 'year', value: 1 }\n\n// b defaults to now\ntimeDiff(Temporal.Now.instant().subtract({ hours: 3 })); // { unit: 'hour', value: 3 }\n\n// Calendar-accurate with tz\ntimeDiff(parseInstant('2026-01-01T00:00:00Z'), parseZoned('2026-06-15T00:00:00[UTC]'), {\n tz: 'UTC',\n}); // { unit: 'month', value: 5 }\n```\n\n---\n\n### `humanize(diff, options?): string`\n\n```ts\nhumanize(diff: TimeDiffResult, options?: { locale?: Intl.LocalesArgument }): string;\n```\n\nConverts a `TimeDiffResult` to a human-readable string. Uses the singular form when `value === 1`, plural otherwise. Unit names are **English-only** — use `formatRelative()` or `formatDuration()` for fully localized output.\n\n**Parameters — `options`:**\n\n| Option | Type | Default | Description |\n| -------- | ---------------------- | ----------- | --------------------------------------------------- |\n| `locale` | `Intl.LocalesArgument` | `undefined` | Locale for the numeric part via `Intl.NumberFormat` |\n\n**Returns:** `string`\n\n**Example:**\n\n```ts\nimport { humanize, timeDiff } from '@vielzeug/tempo';\n\nhumanize({ unit: 'day', value: 1 }); // '1 day'\nhumanize({ unit: 'hour', value: 7 }); // '7 hours'\nhumanize({ unit: 'millisecond', value: 0 }); // '0 milliseconds'\nhumanize({ unit: 'day', value: 3 }, { locale: 'ar' }); // '٣ days'\n\n// Typical combined usage\nhumanize(timeDiff(publishedAt)); // '3 days'\n```\n\n## Range and Recurrence\n\n### `dateRange(start, end, step, options?): Generator<Temporal.ZonedDateTime>`\n\n```ts\ndateRange(\n start: TimeInput,\n end: TimeInput,\n step: Temporal.DurationLike,\n options?: TimeOptions,\n): Generator<Temporal.ZonedDateTime>;\n```\n\nLazily generates `ZonedDateTime` values between `start` and `end` (inclusive), advancing by `step`. Returns a generator — use `for...of` for lazy consumption or spread (`[...dateRange(...)]`) to collect into an array. Returns nothing when `start > end`. Throws `RangeError` if `step` does not advance the date forward.\n\nWhen `start` is a `ZonedDateTime`, `options.tz` is inferred from it automatically. If `end` is in a different timezone it is silently re-projected into `start`'s timezone. Pass `options.tz` explicitly to override. For plain inputs, `options.tz` is required.\n\n**Example:**\n\n```ts\nimport { dateRange, parsePlainDate, parseZoned } from '@vielzeug/tempo';\n\nconst start = parseZoned('2026-03-01T00:00:00[UTC]');\nconst end = parseZoned('2026-03-31T00:00:00[UTC]');\n\n// ZonedDateTime inputs — tz inferred, no need to pass options\nfor (const day of dateRange(start, end, { days: 1 })) {\n render(day);\n if (someCondition) break; // safe to break early\n}\n\n// Collect to array\nconst days = [...dateRange(start, end, { days: 1 })];\n// [Mar 1, Mar 2, ..., Mar 31]\n\n// Plain inputs still require tz\nconst days = [...dateRange(parsePlainDate('2026-03-01'), parsePlainDate('2026-03-31'), { days: 1 }, { tz: 'UTC' })];\n```\n\n---\n\n### `recurrence(start, rule, options?): Generator<Temporal.ZonedDateTime>`\n\n```ts\nrecurrence(\n start: TimeInput,\n rule: RecurrenceRule,\n options?: TimeOptions,\n): Generator<Temporal.ZonedDateTime>;\n```\n\nLazily generates `ZonedDateTime` occurrences according to a recurrence rule. Supports `daily`, `weekly`, `monthly`, and `yearly` frequencies.\n\nEither `count` or `until` (or both) **must** be provided — this is enforced at compile time by the `RecurrenceRule` type and validated eagerly at call time for JavaScript callers. When `start` is a `ZonedDateTime`, `options.tz` is inferred automatically.\n\n**Parameters — `RecurrenceRule`:**\n\n| Field | Type | Required | Description |\n| ----------- | ---------------------------------------------- | ------------------------------------------ | ------------------------------------- |\n| `frequency` | `'daily' \\| 'weekly' \\| 'monthly' \\| 'yearly'` | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Recurrence frequency |\n| `interval` | `number` | — | Step multiplier (default `1`) |\n| `count` | `number` | One of these two | Maximum number of occurrences to emit |\n| `until` | `TimeInput` | One of these two | Inclusive end boundary |\n\n**Example:**\n\n```ts\nimport { parseInstant, parseZoned, recurrence } from '@vielzeug/tempo';\n\nconst start = parseZoned('2026-01-05T09:00:00[Europe/Berlin]');\n\n// ZonedDateTime start — tz inferred, no options needed\nconst mondays = [...recurrence(start, { frequency: 'weekly', count: 4 })];\n\n// Bi-weekly meetings until a deadline\nconst deadline = parseZoned('2026-06-30T00:00:00[Europe/Berlin]');\nfor (const meeting of recurrence(start, { frequency: 'weekly', interval: 2, until: deadline })) {\n schedule(meeting);\n}\n\n// Plain input — tz required\nconst quarters = [\n ...recurrence(parseInstant('2026-01-05T09:00:00Z'), { frequency: 'monthly', interval: 3, count: 6 }, { tz: 'UTC' }),\n];\n```\n\n## Errors\n\nAll errors thrown by tempo are instances of `TempoError`. Catch the base class to handle any tempo-originated\nerror, or catch a specific subtype to distinguish failure modes.\n\n```ts\nimport { TempoError, TempoMissingTzError, parse, parsePlainDateTime, toInstant } from '@vielzeug/tempo';\n\ntry {\n parse('not-a-date');\n} catch (e) {\n if (e instanceof TempoError) {\n console.log(e.name); // 'TempoInvalidInputError'\n console.log(e.message); // 'Unable to parse date/time string: \"not-a-date\". ...'\n }\n}\n\ntry {\n toInstant(parsePlainDateTime('2026-03-21T10:00:00'));\n} catch (e) {\n if (e instanceof TempoMissingTzError) {\n // narrow to this specific failure mode\n }\n}\n```\n\n### `TempoError`\n\nBase class for every error tempo throws. Use `TempoError.is()` to catch anything tempo-originated regardless\nof subtype.\n\n```ts\nclass TempoError extends Error {\n constructor(message: string, opts?: ErrorOptions);\n static is(err: unknown): err is TempoError;\n}\n```\n\n---\n\n### `TempoInvalidInputError`\n\nThrown by `parse()`, `parseInstant()`, `parseZoned()`, `parsePlainDate()`, `parsePlainDateTime()`, and\n`parseDuration()` when the input string cannot be understood. Also the default error class for any `fail()`\ncall site that doesn't specify a more specific subtype (e.g. cross-timezone mismatches in `within()` /\n`clamp()` / `difference()`).\n\n### `TempoInvalidTzError`\n\nThrown when a timezone string is not a valid IANA name or UTC offset — from `validateTz()`, used by every\nfunction that resolves a `tz` option (`now()`, `inTz()`, `shift()`, `startOf()`, `endOf()`, etc.).\n\n### `TempoMissingTzError`\n\nThrown when an operation requires a timezone but none could be inferred — a `PlainDate` or `PlainDateTime`\ninput was passed without `options.tz`, or without a shared timezone across two/more `TimeInput` values.\n\n### `TempoUnsupportedInputError`\n\nThrown by `toInstant()` when the input value is not one of the four `TimeInput` types\n(`Instant`, `ZonedDateTime`, `PlainDateTime`, `PlainDate`).\n\n---\n\n## Types\n\n```ts\ntype TimeInput = Temporal.Instant | Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime;\n\ntype RelativeTimeInput = Temporal.Instant | Temporal.ZonedDateTime;\n\ntype DateTimeDisambiguation = 'compatible' | 'earlier' | 'later' | 'reject';\n\n/** Discriminant for the parse() `as` parameter. Controls the expected return type. */\ntype ParseAs = 'instant' | 'plain-date' | 'plain-datetime' | 'zoned';\n\ntype FormatPattern = 'date-only' | 'long' | 'medium' | 'short' | 'time-only';\n\n// Discriminated union — intl and pattern are mutually exclusive\ntype FormatOptions =\n | { intl: Intl.DateTimeFormatOptions; locale?: Intl.LocalesArgument; pattern?: never; tz?: string }\n | { intl?: never; locale?: Intl.LocalesArgument; pattern?: FormatPattern; tz?: string };\n\ntype TempoUnit =\n | 'day'\n | 'hour'\n | 'microsecond'\n | 'millisecond'\n | 'minute'\n | 'month'\n | 'nanosecond'\n | 'second'\n | 'week'\n | 'year';\n\ntype CalendarUnit = Extract<TempoUnit, 'day' | 'month' | 'week' | 'year'>;\ntype BoundaryUnit = Exclude<TempoUnit, 'microsecond' | 'millisecond' | 'nanosecond' | 'second'>;\ntype TimeDiffUnit = Exclude<TempoUnit, 'microsecond' | 'nanosecond'>;\ntype TimeDiffResult = { unit: TimeDiffUnit; value: number };\ntype WeekStartDay = 1 | 2 | 3 | 4 | 5 | 6 | 7;\n\n// Either count or until (or both) must be provided\ntype RecurrenceRule = {\n frequency: 'daily' | 'monthly' | 'weekly' | 'yearly';\n interval?: number;\n} & ({ count: number; until?: TimeInput } | { count?: number; until: TimeInput });\n\ninterface TimeOptions {\n tz?: string;\n}\n\ninterface DisambiguationOptions {\n prefer?: DateTimeDisambiguation;\n}\n\ninterface ShiftOptions extends DisambiguationOptions, TimeOptions {}\n\ninterface DifferenceOptions extends DisambiguationOptions, TimeOptions {\n largestUnit?: Temporal.DateTimeUnit;\n roundingIncrement?: number;\n roundingMode?: Temporal.RoundingMode;\n smallestUnit?: Temporal.DateTimeUnit;\n}\n\ninterface RelativeFormatOptions {\n base?: RelativeTimeInput;\n locale?: Intl.LocalesArgument;\n numeric?: Intl.RelativeTimeFormatNumeric;\n style?: Intl.RelativeTimeFormatStyle;\n}\n\ninterface BoundaryOptions extends TimeOptions {\n weekStartsOn?: WeekStartDay;\n}\n\ninterface CompareOptions extends TimeOptions {\n unit?: BoundaryUnit;\n weekStartsOn?: WeekStartDay;\n}\n\ninterface DurationFormatOptions {\n locale?: Intl.LocalesArgument;\n style?: 'digital' | 'long' | 'narrow' | 'short';\n}\n```\n",
6
- "usage": "---\ntitle: Tempo — Usage Guide\ndescription: Parsing, timezone conversion, arithmetic, boundaries, and formatting with Tempo.\n---\n\n[[toc]]\n\n## Basic Usage\n\nUse named imports from `@vielzeug/tempo` for tree-shaking.\n\n```ts\nimport { format, inTz, now, parsePlainDateTime, shift, toInstant } from '@vielzeug/tempo';\n\n// Current time in a timezone\nconst berlin = now('Europe/Berlin');\n\n// Parse a wall-clock string, then pin it to a timezone\nconst local = parsePlainDateTime('2026-03-21T10:15:30');\nconst instant = toInstant(local, { tz: 'America/New_York' });\n\n// Project to a different timezone\nconst tokyo = inTz(instant, 'Asia/Tokyo');\n\n// Format for display\nformat(instant, { pattern: 'short', locale: 'en-US', tz: 'America/New_York' });\n```\n\n## Parsing and Conversion\n\nAll common Temporal constructors have a tempo equivalent — import only from `@vielzeug/tempo`:\n\n| Instead of… | Use… |\n| ----------------------------------------------------------- | --------------------------------- |\n| `Temporal.Now.instant()` | `nowInstant()` |\n| `Temporal.Now.zonedDateTimeISO(tz)` | `now(tz)` |\n| `Temporal.Instant.from(str)` | `parseInstant(str)` |\n| `Temporal.ZonedDateTime.from(str)` | `parseZoned(str)` |\n| `Temporal.PlainDateTime.from(str)` | `parsePlainDateTime(str)` |\n| `Temporal.PlainDate.from(str)` | `parsePlainDate(str)` |\n| `Temporal.ZonedDateTime.from` / `Temporal.Instant.from` / … | `parse(str)` (unknown format) |\n\n```ts\nimport {\n inTz,\n isValid,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDateTime,\n parsePlainDate,\n parseZoned,\n toInstant,\n} from '@vielzeug/tempo';\n\n// Current instant\nconst t = nowInstant();\n\n// Wall-clock string from user input or database\nconst local = parsePlainDateTime('2026-03-21T10:15:30');\nconst instant = toInstant(local, { tz: 'Europe/Berlin' });\nconst tokyo = inTz(instant, 'Asia/Tokyo');\n\n// UTC ISO string from an API response\nconst ts = parseInstant('2026-03-21T10:15:30Z');\n\n// Zoned date-time string\nconst meeting = parseZoned('2026-03-21T11:00:00+01:00[Europe/Berlin]');\n\n// Date-only string\nconst date = parsePlainDate('2026-03-21');\n\n// Unknown ISO format — picks the most specific type automatically\nparse('2026-03-21T11:00:00+01:00[Europe/Berlin]'); // ZonedDateTime\nparse('2026-03-21T10:00:00Z'); // Instant\nparse('2026-03-21T10:00:00'); // PlainDateTime\nparse('2026-03-21'); // PlainDate\n\n// Type guard — validate before passing to Tempo functions\nif (isValid(externalValue)) {\n format(externalValue, { pattern: 'short', tz: 'UTC' });\n}\n```\n\n## DST-Safe Arithmetic\n\n`shift()` handles DST transitions correctly.\n\n```ts\nimport { parseZoned, shift } from '@vielzeug/tempo';\n\nconst before = parseZoned('2026-03-08T01:30:00-05:00[America/New_York]');\nconst after = shift(before, { hours: 1 });\n\nconsole.log(after.toString());\n// 2026-03-08T03:30:00-04:00[America/New_York]\n```\n\n## Difference and Range Tools\n\n```ts\nimport { clamp, difference, parseInstant, within } from '@vielzeug/tempo';\n\n// difference() returns a signed duration: negative when start is after end\nconst duration = difference(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T12:30:00Z'), {\n tz: 'UTC',\n largestUnit: 'hour',\n smallestUnit: 'minute',\n});\n\nconst inWindow = within(\n parseInstant('2026-03-21T11:00:00Z'),\n parseInstant('2026-03-21T10:00:00Z'),\n parseInstant('2026-03-21T12:00:00Z'),\n);\n\nconst inWindowByDay = within(\n parseInstant('2026-03-22T04:59:00Z'),\n parseInstant('2026-03-21T06:00:00Z'),\n parseInstant('2026-03-22T03:00:00Z'),\n { unit: 'day', tz: 'America/New_York' },\n);\n\n// clamp returns Temporal.Instant — project to a timezone as needed\nconst clamped = clamp(\n parseInstant('2026-03-21T13:00:00Z'),\n parseInstant('2026-03-21T10:00:00Z'),\n parseInstant('2026-03-21T12:00:00Z'),\n);\nconst bounded = clamped.toZonedDateTimeISO('UTC');\n\n// with unit comparison, clamp aligns to the requested unit boundary\nconst clampedByDay = clamp(\n parseInstant('2026-03-23T05:00:00Z'),\n parseInstant('2026-03-21T09:00:00Z'),\n parseInstant('2026-03-22T18:00:00Z'),\n { unit: 'day', tz: 'America/New_York' },\n);\n```\n\n## Comparison Helpers\n\n```ts\nimport { isAfter, isBefore, isSame, parseInstant } from '@vielzeug/tempo';\n\nisBefore(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T11:00:00Z'));\nisAfter(parseInstant('2026-03-21T12:00:00Z'), parseInstant('2026-03-21T11:00:00Z'));\nisSame(parseInstant('2026-03-21T23:30:00Z'), parseInstant('2026-03-22T00:15:00Z'), {\n unit: 'day',\n tz: 'America/New_York',\n});\n\nisBefore(parseInstant('2026-03-21T23:30:00Z'), parseInstant('2026-03-22T00:15:00Z'), {\n unit: 'day',\n tz: 'UTC',\n});\n```\n\n## Start and End Boundaries\n\n```ts\nimport { endOf, parseInstant, startOf } from '@vielzeug/tempo';\n\nconst dayStart = startOf(parseInstant('2026-03-21T10:15:30Z'), 'day', { tz: 'UTC' });\nconst dayEnd = endOf(parseInstant('2026-03-21T10:15:30Z'), 'day', { tz: 'UTC' });\n\nconst weekStart = startOf(parseInstant('2026-03-21T10:15:30Z'), 'week', {\n tz: 'Europe/Berlin',\n weekStartsOn: 1,\n});\n```\n\n## Formatting\n\nUse `format()` for UI, `formatInstant()`/`formatZoned()` for machine output, `formatRelative()` for UX copy.\n\n```ts\nimport {\n format,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n parseInstant,\n} from '@vielzeug/tempo';\n\nconst instant = parseInstant('2026-03-21T10:15:30Z');\n\nformat(instant, { pattern: 'short', locale: 'en-GB', tz: 'UTC' });\nformatInstant(instant);\nformatZoned(instant, { tz: 'Europe/Berlin' });\n\nformatRange(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T12:00:00Z'), {\n pattern: 'short',\n locale: 'en-US',\n tz: 'America/New_York',\n});\n\nformatRelative(parseInstant('2026-03-21T12:00:00Z'), {\n base: parseInstant('2026-03-21T10:00:00Z'),\n locale: 'en-US',\n numeric: 'always',\n});\n\n// formatParts / formatRangeParts — raw Intl parts for custom rendering\nconst parts = formatParts(instant, { pattern: 'date-only', tz: 'UTC' });\n// [{ type: 'month', value: '3' }, { type: 'literal', value: '/' }, ...]\n\nconst rangeParts = formatRangeParts(parseInstant('2026-03-21T10:00:00Z'), parseInstant('2026-03-21T12:00:00Z'), {\n pattern: 'short',\n locale: 'en-US',\n tz: 'UTC',\n});\nconst startOnly = rangeParts.filter((p) => p.source === 'startRange' || p.source === 'shared');\n```\n\n## Duration Helpers\n\n```ts\nimport { formatDuration, parseDuration } from '@vielzeug/tempo';\n\nconst duration = parseDuration('PT2H30M');\nconst text = formatDuration(duration, { locale: 'en-US', style: 'short' });\n```\n\n> **Note:** `formatDuration()` uses `Intl.DurationFormat` when available. In environments that do not support it, it falls back to a plain **English-only** representation (e.g., `'2 hours, 30 minutes'`).\n\n## Expiry and Classification\n\nUse `expires()` to classify a date into a named threshold bucket of your choosing.\n\n```ts\nimport { expires, humanize, now, parseInstant, shift, timeDiff } from '@vielzeug/tempo';\n\nconst THRESHOLDS = {\n longExpired: { days: -30 }, // more than 30 days past\n expired: { days: 0 }, // any past date\n critical: { days: 3 }, // within 3 days\n warning: { days: 14 }, // within 14 days\n safe: { years: 100 },\n} as const;\n\n// Use shift(now(tz), ...) for day-level offsets\nexpires(shift(now('UTC'), { days: -60 }).toInstant(), THRESHOLDS); // 'longExpired'\nexpires(shift(now('UTC'), { hours: 48 }).toInstant(), THRESHOLDS); // 'critical'\nexpires(shift(now('UTC'), { years: 200 }).toInstant(), THRESHOLDS); // null (no match)\n\n// Pin the reference time for deterministic behavior in tests\nconst pinnedNow = parseInstant('2026-06-01T00:00:00Z');\nexpires(parseInstant('2026-06-04T00:00:00Z'), THRESHOLDS, {}, pinnedNow); // 'critical'\n\n// timeDiff — largest-unit human-readable time difference\n// No tz needed when both are Instants\ntimeDiff(parseInstant('2026-01-01T00:00:00Z'), parseInstant('2027-06-01T00:00:00Z')); // { unit: 'year', value: 1 }\n\n// humanize converts a TimeDiffResult to a readable string (English only)\nhumanize(timeDiff(expiresAt)); // '3 days', '1 hour', etc.\n```\n\n## Date Ranges and Recurrence\n\nUse `dateRange()` to lazily generate sequences of `ZonedDateTime` values for calendars, reports, or iteration.\n\nWhen `start` is a `ZonedDateTime`, the timezone is inferred automatically — no need to pass `options`. For plain inputs, pass `options.tz` explicitly.\n\n```ts\nimport { dateRange, parseZoned, recurrence } from '@vielzeug/tempo';\n\n// dateRange returns a Generator — use for...of or spread to collect\nconst start = parseZoned('2026-03-01T00:00:00[UTC]');\nconst end = parseZoned('2026-03-31T00:00:00[UTC]');\n\n// ZonedDateTime inputs — tz inferred, no options needed\nfor (const day of dateRange(start, end, { days: 1 })) {\n render(day);\n}\n\n// Collect to array\nconst days = [...dateRange(start, end, { days: 1 })];\n\n// Every Monday in a date range\nconst mondays = [\n ...dateRange(parseZoned('2026-03-02T00:00:00[UTC]'), parseZoned('2026-03-30T00:00:00[UTC]'), { weeks: 1 }),\n];\n\n// recurrence — repeating dates with count or until\nconst meetingStart = parseZoned('2026-01-05T09:00:00[Europe/Berlin]');\nconst deadline = parseZoned('2026-06-30T00:00:00[Europe/Berlin]');\n\n// ZonedDateTime start — tz inferred, no options needed\nfor (const meeting of recurrence(meetingStart, { frequency: 'weekly', until: deadline })) {\n schedule(meeting);\n}\n\n// Every 3 months for 6 occurrences (tz inferred from ZonedDateTime start)\nconst quarters = [...recurrence(meetingStart, { frequency: 'monthly', interval: 3, count: 6 })];\n```\n\n## Framework Integration\n\nTempo is a pure-utility library with no subscription model. Use its functions directly wherever date/time values are formatted or computed.\n\n::: code-group\n\n```tsx [React]\nimport { format, now, parseInstant, shift } from '@vielzeug/tempo';\n\nfunction DeadlineLabel({ iso }: { iso: string }) {\n const deadline = parseInstant(iso);\n const tomorrow = shift(now('UTC'), { days: 1 });\n const isUrgent = deadline.epochMilliseconds < tomorrow.toInstant().epochMilliseconds;\n\n return <span className={isUrgent ? 'urgent' : ''}>{format(deadline, { locale: navigator.language })}</span>;\n}\n```\n\n```ts [Vue 3]\nimport { computed } from 'vue';\nimport { format, now, parseInstant, shift } from '@vielzeug/tempo';\n\nfunction useDeadlineLabel(iso: string) {\n return computed(() => {\n const deadline = parseInstant(iso);\n const tomorrow = shift(now('UTC'), { days: 1 });\n const isUrgent = deadline.epochMilliseconds < tomorrow.toInstant().epochMilliseconds;\n return { label: format(deadline, { locale: 'en' }), isUrgent };\n });\n}\n```\n\n```svelte [Svelte]\n<script lang=\"ts\">\n import { format, now, parseInstant, shift } from '@vielzeug/tempo';\n\n export let iso: string;\n\n $: deadline = parseInstant(iso);\n $: isUrgent = deadline.epochMilliseconds < shift(now('UTC'), { days: 1 }).toInstant().epochMilliseconds;\n $: label = format(deadline, { locale: 'en' });\n</script>\n\n<span class:urgent={isUrgent}>{label}</span>\n```\n\n:::\n\n## Working with Other Vielzeug Libraries\n\n### With Rune\n\nFormat timestamps for structured log output using Tempo.\n\n```ts\nimport { createLogger } from '@vielzeug/rune';\nimport { formatInstant, now } from '@vielzeug/tempo';\n\nconst log = createLogger({ namespace: 'app' });\n\nlog.info({ timestamp: formatInstant(now('UTC')) }, 'server started');\n```\n\n### With Vault\n\nUse TTL values derived from Tempo duration helpers.\n\n```ts\nimport { createLocalStorage, table, ttl } from '@vielzeug/vault';\nimport { shift, now } from '@vielzeug/tempo';\n\ntype Session = { id: string; token: string };\nconst schema = { sessions: table<Session>('id') };\nconst db = createLocalStorage('app', schema);\n\n// Store session with a 1-hour TTL\nconst expiresIn = shift(now('UTC'), { hours: 1 }).toInstant().epochMilliseconds - Date.now();\nawait db.put('sessions', { id: '1', token: 'abc' }, ttl.ms(expiresIn));\n```\n\n## Best Practices\n\n- Store `Temporal.Instant` values in databases and APIs — never store offset-aware strings.\n- Use `parsePlainDateTime()` at the system boundary when receiving wall-clock strings from external sources; use `parseInstant()` for UTC ISO strings; use `parse()` when the format is unknown.\n- Use `isValid()` as a type guard when accepting `TimeInput` from external data.\n- Convert to `ZonedDateTime` only when rendering to users; keep instants everywhere else.\n- Always pass `tz` when calling `toInstant()`, `shift()`, or `difference()` with plain inputs.\n- Use `format()` for UI labels, `formatInstant()` for transport/logging, and `formatZoned()` for zoned ISO strings.\n- Use `formatParts()` / `formatRangeParts()` when individual date parts need separate styling.\n- Use `formatRelative()` for UX copy (\"3 hours ago\") rather than computing the difference manually.\n- Prefer `dateRange()` over manual `while` loops when generating sequences of dates.\n",
4
+ "index": "---\ntitle: Tempo — Temporal date and time utilities\ndescription: Explicit Temporal parsing, timezone-safe arithmetic, and localized date/time formatting for TypeScript.\npackage: tempo\ncategory: time\nkeywords: [temporal, date-time, timezone, formatting, arithmetic, dst, intl]\nrelated: [rune, vault]\nexports: [Temporal, parse, now, nowInstant, isValid, toInstant, inTimeZone, shift, difference, contains, clamp, isBefore, isAfter, isSame, startOf, endOf, format, formatParts, formatRange, formatRangeParts, formatInstant, formatZoned, formatRelative, parseDuration, formatDuration, classifyExpiry, timeDiff, humanize, dateRange, recurrence, TempoError, TempoInvalidInputError, TempoInvalidTzError, TempoMissingTzError, TempoUnsupportedInputError]\nenvironments: [browser, node, ssr, deno]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"tempo\" />\n\n## Why Tempo?\n\nDate/time bugs come from treating an instant and a wall-clock value as interchangeable. Tempo requires an explicit parse target and requires `timeZone` whenever a wall-clock value becomes an instant.\n\n```ts\n// Before\nconst reminder = new Date(meeting.getTime() - 15 * 60_000);\n\n// After\nimport { parse, shift, toInstant } from '@vielzeug/tempo';\n\nconst localMeeting = parse('2026-03-21T10:30:00', { as: 'plainDateTime' });\nconst meeting = toInstant(localMeeting, { timeZone: 'America/New_York' });\nconst reminder = shift(meeting, { minutes: -15 }, { timeZone: 'America/New_York' });\n```\n\n| Feature | Tempo | date-fns | Native Date |\n| --- | --- | --- | --- |\n| Bundle size | <PackageInfo package=\"tempo\" type=\"size\" /> | ~10 kB | 0 kB |\n| Zero dependencies | <ore-icon name=\"x\" size=\"16\"></ore-icon> `@js-temporal/polyfill` | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Explicit wall-time conversion | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Manual | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| DST-safe arithmetic | <ore-icon name=\"check\" size=\"16\"></ore-icon> | Manual | Manual |\n| Localized formatting | <ore-icon name=\"check\" size=\"16\"></ore-icon> `Intl` | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n\n<div class=\"decision-callout\">\n\n**Use Tempo when** you need Temporal values, explicit timezone rules, and DST-safe operations.\n\n**Consider native `Date` when** your data is only elapsed milliseconds and you do not need calendar or timezone behavior.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/tempo\n```\n\n```sh [npm]\nnpm install @vielzeug/tempo\n```\n\n```sh [yarn]\nyarn add @vielzeug/tempo\n```\n\n:::\n\n## Quick Start\n\nParse a wall-clock input explicitly, attach its timezone, then format it for a user.\n\n```ts\nimport { format, inTimeZone, parse, shift, toInstant } from '@vielzeug/tempo';\n\nconst localMeeting = parse('2026-03-21T10:30:00', { as: 'plainDateTime' });\nconst meeting = toInstant(localMeeting, { timeZone: 'America/New_York' });\nconst reminder = shift(meeting, { minutes: -15 }, { timeZone: 'America/New_York' });\nconst text = format(inTimeZone(reminder, 'America/New_York'), {\n locale: 'en-US',\n pattern: 'short',\n});\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- `parse()` Requires an explicit ISO target: instant, zoned date-time, plain date-time, or plain date.\n- `toInstant()` / `inTimeZone()` — Convert wall-clock and absolute values with explicit timezone semantics.\n- `shift()` / `difference()` Perform DST-safe arithmetic and duration calculation.\n- `contains()` / `clamp()` Use named range fields instead of ambiguous positional inputs.\n- `classifyExpiry()` Classify fixed elapsed-time thresholds in milliseconds or larger units without month or year approximation.\n- `format()` / `formatRelative()` / `formatDuration()` Render UI, relative, and duration values through `Intl`.\n- `dateRange()` / `recurrence()` — Lazily generate zoned calendar sequences.\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Rune](/rune/) — format stable Temporal timestamps before writing structured log records.\n- [Vault](/vault/) — derive explicit expiry moments before storing records with TTL policies.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
5
+ "api": "---\ntitle: Tempo — API Reference\ndescription: Reference for Tempo Temporal parsing, conversion, arithmetic, formatting, and classification APIs.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution mode | Common gotcha |\n| --- | --- | --- | --- |\n| `parse()` | Parse ISO text to an explicit Temporal kind | Sync | `as` is required |\n| `isValid()` | Narrow an unknown runtime value to `TimeInput` | Sync | Does not parse strings |\n| `toInstant()` | Resolve a value as an absolute instant | Sync | Plain values require `timeZone` |\n| `inTimeZone()` | Project a value to a zone | Sync | Preserves instant, changes wall-clock fields |\n| `shift()` / `difference()` | DST-safe arithmetic | Sync | Calendar work needs a timezone |\n| `contains()` / `clamp()` | Named range operations | Sync | Bounds normalize automatically |\n| `classifyExpiry()` | Classify fixed elapsed-time thresholds | Sync | Use milliseconds or larger units; months and years are rejected |\n| `format()` family | Localized and machine formatting | Sync | Use `timeZone`, not `tz` |\n| `dateRange()` / `recurrence()` | Lazy zoned sequences | Sync | Plain inputs need `timeZone` |\n\n## Package Entry Point\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/tempo` | Tempo utilities, errors, types, and shared `Temporal` namespace |\n\n## Core Functions\n\n### `parse(input, { as })`\n\n```ts\nparse(input: string, options: { as: 'instant' }): Temporal.Instant;\nparse(input: string, options: { as: 'zonedDateTime' }): Temporal.ZonedDateTime;\nparse(input: string, options: { as: 'plainDateTime' }): Temporal.PlainDateTime;\nparse(input: string, options: { as: 'plainDate' }): Temporal.PlainDate;\n```\n\nParses an ISO 8601 string as the requested temporal kind.\n\n**Parameters**\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `input` | `string` | ISO 8601 input |\n| `options.as` | `ParseAs` | Required result kind |\n\n**Returns:** Requested Temporal value.\n\n**Example:**\n\n```ts\nimport { parse } from '@vielzeug/tempo';\n\nconst instant = parse('2026-03-21T10:15:30Z', { as: 'instant' });\n```\n\n---\n\n### `isValid(value)`\n\n```ts\nisValid(value: unknown): value is TimeInput;\n```\n\nReturns whether `value` is a Tempo-supported Temporal value. It does not parse ISO strings.\n\n**Example:**\n\n```ts\nimport { isValid, parse } from '@vielzeug/tempo';\n\nconst value: unknown = parse('2026-03-21T10:15:30Z', { as: 'instant' });\nconst valid = isValid(value); // true\n```\n\n---\n\n### `now({ timeZone })` / `nowInstant()`\n\n```ts\nnow(options: { timeZone: string }): Temporal.ZonedDateTime;\nnowInstant(): Temporal.Instant;\n```\n\nReturns current zoned or absolute time.\n\n**Example:**\n\n```ts\nimport { now, nowInstant } from '@vielzeug/tempo';\n\nnow({ timeZone: 'Europe/Berlin' });\nnowInstant();\n```\n\n---\n\n### `toInstant(input, options?)` / `inTimeZone(input, timeZone)`\n\n```ts\ntoInstant(input: AbsoluteTime): Temporal.Instant;\ntoInstant(input: WallTime, options: { timeZone: string; disambiguation?: Disambiguation }): Temporal.Instant;\ninTimeZone(input: TimeInput, timeZone: string): Temporal.ZonedDateTime;\n```\n\n`toInstant()` resolves wall-clock values. `inTimeZone()` projects a value into a requested timezone.\n\n**Example:**\n\n```ts\nimport { inTimeZone, parse, toInstant } from '@vielzeug/tempo';\n\nconst local = parse('2026-11-01T01:30:00', { as: 'plainDateTime' });\nconst instant = toInstant(local, { disambiguation: 'later', timeZone: 'America/New_York' });\ninTimeZone(instant, 'Europe/Berlin');\n```\n\n---\n\n### `shift(input, duration, options?)`\n\n```ts\nshift(input: TimeInput, duration: Temporal.DurationLike, options?: ShiftOptions): Temporal.ZonedDateTime;\n```\n\nAdds a duration through Temporal calendar rules and returns a zoned value.\n\n**Returns:** `Temporal.ZonedDateTime`.\n\n**Example:**\n\n```ts\nimport { parse, shift } from '@vielzeug/tempo';\n\nconst before = parse('2026-03-08T01:30:00-05:00[America/New_York]', { as: 'zonedDateTime' });\nshift(before, { hours: 1 });\n```\n\n---\n\n### `difference({ start, end, ...options })`\n\n```ts\ndifference(input: DifferenceInput): Temporal.Duration;\n```\n\nReturns duration from `start` to `end`.\n\n**Example:**\n\n```ts\nimport { difference, parse } from '@vielzeug/tempo';\n\nconst start = parse('2026-03-21T10:00:00Z', { as: 'instant' });\nconst end = parse('2026-03-21T12:00:00Z', { as: 'instant' });\ndifference({ end, largestUnit: 'hour', start });\n```\n\n## Range and Comparison\n\n### `contains({ value, start, end, ...options })`\n\n```ts\ncontains(input: ContainsInput): boolean;\n```\n\nReturns whether `value` lies in inclusive normalized bounds.\n\n### `clamp({ value, start, end, ...options })`\n\n```ts\nclamp(input: ClampInput): Temporal.Instant | Temporal.ZonedDateTime;\n```\n\nReturns the nearest bound when `value` falls outside the range.\n\n### `isBefore(a, b, options?)` / `isAfter(a, b, options?)` / `isSame(a, b, options?)`\n\n```ts\nisBefore(a: TimeInput, b: TimeInput, options?: CompareOptions): boolean;\nisAfter(a: TimeInput, b: TimeInput, options?: CompareOptions): boolean;\nisSame(a: TimeInput, b: TimeInput, options?: CompareOptions): boolean;\n```\n\nCompare absolute values or calendar boundaries when `unit` is supplied.\n\n### `startOf(input, unit, options?)` / `endOf(input, unit, options?)`\n\n```ts\nstartOf(input: TimeInput, unit: BoundaryUnit, options?: BoundaryOptions): Temporal.ZonedDateTime;\nendOf(input: TimeInput, unit: BoundaryUnit, options?: BoundaryOptions): Temporal.ZonedDateTime;\n```\n\nReturns the first or last nanosecond of the requested boundary unit.\n\n## Formatting\n\n### `format(input, options?)`\n\n```ts\nformat(input: TimeInput, options?: FormatOptions): string;\n```\n\nFormats a value through `Intl.DateTimeFormat`.\n\n**Example:**\n\n```ts\nimport { format, parse } from '@vielzeug/tempo';\n\nformat(parse('2026-03-21T10:15:30Z', { as: 'instant' }), {\n locale: 'en-GB',\n pattern: 'short',\n timeZone: 'UTC',\n});\n```\n\n### `formatInstant()` / `formatZoned()` / `formatRelative()` / `formatDuration()`\n\n```ts\nformatInstant(input: TimeInput, options?: TimeZoneOptions): string;\nformatZoned(input: TimeInput, options?: TimeZoneOptions): string;\nformatRelative(input: RelativeTimeInput, options?: RelativeFormatOptions): string;\nformatDuration(input: string | Temporal.DurationLike, options?: DurationFormatOptions): string;\n```\n\n`formatInstant()` produces UTC transport text. `formatZoned()` produces zoned ISO text. `formatDuration()` falls back to English when `Intl.DurationFormat` is unavailable.\n\n### `formatParts()` / `formatRange()` / `formatRangeParts()`\n\n```ts\nformatParts(input: TimeInput, options?: FormatOptions): Intl.DateTimeFormatPart[];\nformatRange(start: TimeInput, end: TimeInput, options?: FormatOptions): string;\nformatRangeParts(\n start: TimeInput,\n end: TimeInput,\n options?: FormatOptions,\n): ReturnType<Intl.DateTimeFormat['formatRangeToParts']>;\n```\n\nReturn `Intl` parts or localized range strings using `FormatOptions`.\n\n### `parseDuration()` / `humanize()`\n\n```ts\nparseDuration(input: string | Temporal.DurationLike): Temporal.Duration;\nhumanize(diff: TimeDiffResult, options?: { locale?: Intl.LocalesArgument }): string;\n```\n\n`humanize()` localizes numbers only. Unit names remain English.\n\n## Classification and Sequences\n\n### `classifyExpiry({ value, thresholds, relativeTo?, timeZone? })`\n\n```ts\nclassifyExpiry<K extends string>(input: ClassifyExpiryInput<K>): K | null;\n```\n\nClassifies an expiry against fixed elapsed-time thresholds in milliseconds or larger units. Months and years throw `TempoInvalidInputError`.\n\n### `timeDiff(a, b?, options?)`\n\n```ts\ntimeDiff(a: TimeInput, b?: TimeInput, options?: TimeZoneOptions): TimeDiffResult;\n```\n\nReturns absolute calendar difference in its largest meaningful unit.\n\n### `dateRange()` / `recurrence()`\n\n```ts\ndateRange(start: TimeInput, end: TimeInput, step: Temporal.DurationLike, options?: TimeZoneOptions): Generator<Temporal.ZonedDateTime>;\nrecurrence(start: TimeInput, rule: RecurrenceRule, options?: TimeZoneOptions): Generator<Temporal.ZonedDateTime>;\n```\n\nReturns lazy `ZonedDateTime` sequences.\n\n## Types\n\n```ts\ntype AbsoluteTime = Temporal.Instant | Temporal.ZonedDateTime;\ntype WallTime = Temporal.PlainDate | Temporal.PlainDateTime;\ntype TimeInput = AbsoluteTime | WallTime;\ntype RelativeTimeInput = AbsoluteTime;\ntype ParseAs = 'instant' | 'plainDate' | 'plainDateTime' | 'zonedDateTime';\ntype Disambiguation = 'compatible' | 'earlier' | 'later' | 'reject';\ntype FormatPattern = 'date-only' | 'long' | 'medium' | 'short' | 'time-only';\ntype TempoUnit = 'day' | 'hour' | 'microsecond' | 'millisecond' | 'minute' | 'month' | 'nanosecond' | 'second' | 'week' | 'year';\ntype CalendarUnit = Extract<TempoUnit, 'day' | 'month' | 'week' | 'year'>;\ntype BoundaryUnit = Exclude<TempoUnit, 'microsecond' | 'millisecond' | 'nanosecond' | 'second'>;\ntype WeekStartDay = 1 | 2 | 3 | 4 | 5 | 6 | 7;\ntype FixedDuration = Pick<Temporal.DurationLike, 'days' | 'hours' | 'microseconds' | 'milliseconds' | 'minutes' | 'nanoseconds' | 'seconds' | 'weeks'>;\ntype ExpiryThresholds<K extends string> = Record<K, FixedDuration>;\ntype TimeDiffUnit = Exclude<TempoUnit, 'microsecond' | 'nanosecond'>;\ntype TimeDiffResult = { unit: TimeDiffUnit; value: number };\ntype RecurrenceRule =\n | { frequency: 'daily' | 'monthly' | 'weekly' | 'yearly'; interval?: number; count: number; until?: TimeInput }\n | { frequency: 'daily' | 'monthly' | 'weekly' | 'yearly'; interval?: number; count?: number; until: TimeInput };\n\ninterface TimeZoneOptions { timeZone?: string }\ninterface DisambiguationOptions { disambiguation?: Disambiguation }\ninterface ShiftOptions extends DisambiguationOptions, TimeZoneOptions {}\ninterface DifferenceInput extends DisambiguationOptions, TimeZoneOptions {\n start: TimeInput;\n end: TimeInput;\n largestUnit?: Temporal.DateTimeUnit;\n smallestUnit?: Temporal.DateTimeUnit;\n roundingIncrement?: number;\n roundingMode?: Temporal.RoundingMode;\n}\ntype FormatOptions =\n | { intl: Intl.DateTimeFormatOptions; locale?: Intl.LocalesArgument; pattern?: never; timeZone?: string }\n | { intl?: never; locale?: Intl.LocalesArgument; pattern?: FormatPattern; timeZone?: string };\ninterface RelativeFormatOptions {\n base?: RelativeTimeInput;\n locale?: Intl.LocalesArgument;\n numeric?: Intl.RelativeTimeFormatNumeric;\n style?: Intl.RelativeTimeFormatStyle;\n}\ninterface DurationFormatOptions {\n locale?: Intl.LocalesArgument;\n style?: 'digital' | 'long' | 'narrow' | 'short';\n}\ninterface BoundaryOptions extends TimeZoneOptions { weekStartsOn?: WeekStartDay }\ninterface CompareOptions extends TimeZoneOptions { unit?: BoundaryUnit; weekStartsOn?: WeekStartDay }\ninterface ContainsInput extends CompareOptions { value: TimeInput; start: TimeInput; end: TimeInput }\ninterface ClampInput extends CompareOptions { value: TimeInput; start: TimeInput; end: TimeInput }\ninterface ClassifyExpiryInput<K extends string> extends TimeZoneOptions {\n value: TimeInput;\n thresholds: ExpiryThresholds<K>;\n relativeTo?: Temporal.Instant;\n}\n```\n\n## Errors\n\n| Error | Trigger | Notable properties |\n| --- | --- | --- |\n| `TempoError` | Base Tempo error | `TempoError.is(value)` narrows every subtype |\n| `TempoInvalidInputError` | Invalid parse, duration, or fixed-threshold input | Extends `TempoError` |\n| `TempoInvalidTzError` | Invalid IANA zone or offset | Extends `TempoError` |\n| `TempoMissingTzError` | Wall time without required `timeZone` | Extends `TempoError` |\n| `TempoUnsupportedInputError` | Non-Temporal input passed to conversion | Extends `TempoError` |\n",
6
+ "usage": "---\ntitle: Tempo — Usage Guide\ndescription: Parse explicit Temporal values, resolve wall-clock time, compare ranges, and format dates with Tempo.\n---\n\n[[toc]]\n\n## Basic Usage\n\nParse ISO input with a declared target. Convert plain values with `timeZone` before treating them as an instant.\n\n```ts\nimport { format, inTimeZone, parse, shift, toInstant } from '@vielzeug/tempo';\n\nconst local = parse('2026-03-21T10:15:30', { as: 'plainDateTime' });\nconst instant = toInstant(local, { timeZone: 'America/New_York' });\nconst reminder = shift(instant, { minutes: -15 }, { timeZone: 'America/New_York' });\n\nformat(inTimeZone(reminder, 'America/New_York'), { locale: 'en-US', pattern: 'short' });\n```\n\n## Parse ISO Values\n\nChoose the value your boundary actually represents. Tempo does not auto-detect ISO strings.\n\n```ts\nimport { parse } from '@vielzeug/tempo';\n\nconst occurredAt = parse('2026-03-21T10:15:30Z', { as: 'instant' });\nconst meeting = parse('2026-03-21T10:15:30+01:00[Europe/Berlin]', { as: 'zonedDateTime' });\nconst localStart = parse('2026-03-21T10:15:30', { as: 'plainDateTime' });\nconst birthday = parse('2026-03-21', { as: 'plainDate' });\n```\n\n## Convert Timezones\n\nUse `inTimeZone()` to project an absolute value. Use `toInstant()` only when resolving a wall-clock value.\n\n```ts\nimport { inTimeZone, parse, toInstant } from '@vielzeug/tempo';\n\nconst local = parse('2026-11-01T01:30:00', { as: 'plainDateTime' });\nconst firstOccurrence = toInstant(local, {\n disambiguation: 'earlier',\n timeZone: 'America/New_York',\n});\n\nconst berlin = inTimeZone(firstOccurrence, 'Europe/Berlin');\n```\n\n## Calculate and Compare\n\nUse object inputs for operations with multiple time values.\n\n```ts\nimport { clamp, contains, difference, parse } from '@vielzeug/tempo';\n\nconst start = parse('2026-03-21T10:00:00Z', { as: 'instant' });\nconst end = parse('2026-03-21T12:00:00Z', { as: 'instant' });\nconst value = parse('2026-03-21T13:00:00Z', { as: 'instant' });\n\nconst duration = difference({ end, largestUnit: 'hour', start });\nconst isScheduled = contains({ end, start, value });\nconst bounded = clamp({ end, start, value });\n```\n\n## Classify Expiry\n\nUse fixed elapsed-time thresholds in milliseconds or larger units. Handle `null` as the unclassified state instead of adding a far-future catch-all.\n\n```ts\nimport { classifyExpiry, parse } from '@vielzeug/tempo';\n\nconst status = classifyExpiry({\n relativeTo: parse('2026-06-01T00:00:00Z', { as: 'instant' }),\n thresholds: {\n expired: { days: 0 },\n critical: { days: 3 },\n warning: { days: 14 },\n },\n value: parse('2026-06-04T00:00:00Z', { as: 'instant' }),\n});\n\nconst label = status ?? 'safe';\n```\n\n## Format Values\n\nUse `format()` for UI, `formatInstant()` for transport, and `formatZoned()` for a zoned ISO string.\n\n```ts\nimport { format, formatInstant, formatRelative, formatZoned, parse } from '@vielzeug/tempo';\n\nconst instant = parse('2026-03-21T10:15:30Z', { as: 'instant' });\n\nformat(instant, { locale: 'en-GB', pattern: 'short', timeZone: 'UTC' });\nformatInstant(instant);\nformatZoned(instant, { timeZone: 'Europe/Berlin' });\nformatRelative(instant, { base: parse('2026-03-21T09:15:30Z', { as: 'instant' }) });\n```\n\n## Generate Calendar Sequences\n\nUse zoned inputs for date sequences so the timezone is inferred.\n\n```ts\nimport { dateRange, parse, recurrence } from '@vielzeug/tempo';\n\nconst start = parse('2026-03-01T00:00:00[UTC]', { as: 'zonedDateTime' });\nconst end = parse('2026-03-31T00:00:00[UTC]', { as: 'zonedDateTime' });\n\nconst days = [...dateRange(start, end, { days: 1 })];\nconst meetings = [...recurrence(start, { count: 4, frequency: 'weekly' })];\n```\n\n## Testing\n\nPin the reference instant for deterministic expiry tests.\n\n```ts\nimport { classifyExpiry, parse } from '@vielzeug/tempo';\n\nconst relativeTo = parse('2026-06-01T00:00:00Z', { as: 'instant' });\nconst value = parse('2026-05-31T00:00:00Z', { as: 'instant' });\n\nclassifyExpiry({ relativeTo, thresholds: { expired: { days: 0 } }, value });\n```\n\n## Framework Integration\n\nPass ISO strings through component props. Parse and format at the rendering boundary.\n\n::: code-group\n\n```tsx [React]\nimport { format, parse } from '@vielzeug/tempo';\n\nconst label = format(parse(iso, { as: 'instant' }), { locale: 'en-US', pattern: 'medium', timeZone: 'UTC' });\n```\n\n```vue [Vue 3]\n<script setup lang=\"ts\">\nimport { format, parse } from '@vielzeug/tempo';\n\nconst props = defineProps<{ iso: string }>();\nconst label = format(parse(props.iso, { as: 'instant' }), { locale: 'en-US', pattern: 'medium', timeZone: 'UTC' });\n</script>\n```\n\n```svelte [Svelte]\n<script lang=\"ts\">\n import { format, parse } from '@vielzeug/tempo';\n export let iso: string;\n $: label = format(parse(iso, { as: 'instant' }), { locale: 'en-US', pattern: 'medium', timeZone: 'UTC' });\n</script>\n```\n\n:::\n\n## Working with Other Vielzeug Libraries\n\n### With Rune\n\nWrite stable UTC timestamps to structured logs.\n\n```ts\nimport { formatInstant, nowInstant } from '@vielzeug/tempo';\n\nlogger.info({ timestamp: formatInstant(nowInstant()) }, 'server started');\n```\n\n### With Vault\n\nCalculate an explicit instant before storing an expiring record.\n\n```ts\nimport { now, shift } from '@vielzeug/tempo';\n\nconst expiresAt = shift(now({ timeZone: 'UTC' }), { minutes: 30 }).toInstant();\n```\n\n## Best Practices\n\n- Parse each string with its actual temporal meaning.\n- Pass `timeZone` when converting a plain date or plain date-time.\n- Use `disambiguation` for DST overlap and gap handling.\n- Pass named fields to `difference()`, `contains()`, `clamp()`, and `classifyExpiry()`.\n- Use fixed duration units for expiry thresholds.\n- Store instants for transport and database values.\n- Use `formatInstant()` for machine output and `format()` for user-facing text.\n",
7
7
  "examples": "---\ntitle: Tempo — Examples\ndescription: Practical examples and recipes for tempo.\n---\n\n## Examples\n\n- [DST-Safe Arithmetic](./examples/dst-safe-arithmetic.md)\n- [Locale Formatting](./examples/locale-formatting.md)\n- [Timezone Conversion](./examples/timezone-conversion.md)\n- [Expiry Classification](./examples/expiry-classification.md)\n- [Date Ranges and Recurrence](./examples/date-ranges-and-recurrence.md)\n"
8
8
  },
9
9
  "examples": [
10
- {
11
- "id": "boundary-and-relative",
12
- "code": "import { endOf, formatRelative, isBefore, isSame, parseInstant, startOf } from '@vielzeug/tempo'\n\n// Snap to calendar boundaries (tz required for non-ZonedDateTime inputs)\nconst event = parseInstant('2026-03-21T10:15:30Z')\n\nconst dayStart = startOf(event, 'day', { tz: 'UTC' })\nconst dayEnd = endOf(event, 'day', { tz: 'UTC' })\nconst weekStart = startOf(event, 'week', { tz: 'UTC', weekStartsOn: 1 })\n\nconsole.log('Day start:', dayStart.toString())\nconsole.log('Day end:', dayEnd.toString())\nconsole.log('Week start:', weekStart.toString())\n\n// Comparison helpers\nconst a = parseInstant('2026-03-21T10:00:00Z')\nconst b = parseInstant('2026-03-21T12:00:00Z')\n\nconsole.log('a < b:', isBefore(a, b))\nconsole.log('same day:', isSame(a, b, { unit: 'day', tz: 'UTC' }))\n\n// Relative formatting with a pinned base\nconst base = parseInstant('2026-03-21T10:00:00Z')\nconsole.log(formatRelative(b, { base, locale: 'en-US', numeric: 'always' }))\n// → 'in 2 hours'\nconsole.log(formatRelative(a, { base, locale: 'en-US' }))\n// → 'now'",
13
- "name": "Boundary & Relative Time"
14
- },
15
- {
16
- "id": "dst-safe-arithmetic",
17
- "code": "import { formatInstant, parseInstant, parseZoned, shift } from '@vielzeug/tempo'\n\nconst beforeDst = parseZoned('2026-03-08T01:30:00-05:00[America/New_York]')\nconst plusOneHour = shift(beforeDst, { hours: 1 })\n\nconsole.log('Before:', beforeDst.toString())\nconsole.log('After +1h:', plusOneHour.toString())\n// shift() always returns ZonedDateTime — call .toInstant() if you need an Instant\nconsole.log('As Instant:', plusOneHour.toInstant().toString())\nconsole.log('Formatted:', formatInstant(plusOneHour))\n\n// Works with Instant input too (tz required)\nconst instant = parseInstant('2026-03-08T06:30:00Z')\nconst shifted = shift(instant, { hours: 2 }, { tz: 'America/New_York' })\nconsole.log('Shifted ZDT:', shifted.toString())\nconsole.log('Back to Instant:', shifted.toInstant().toString())",
18
- "name": "DST-Safe Arithmetic"
19
- },
20
- {
21
- "id": "duration-and-projection",
22
- "code": "import { difference, formatDuration, inTz, parseDuration, parseZoned } from '@vielzeug/tempo'\n\n// --- formatDuration() ---\n// ISO 8601 string → human-readable\nconsole.log(formatDuration('P1Y2M3DT4H')) // '1 year, 2 months, 3 days, 4 hours'\nconsole.log(formatDuration('PT30M')) // '30 minutes'\nconsole.log(formatDuration({ seconds: 90 })) // '1 minute, 30 seconds'\nconsole.log(formatDuration({ microseconds: 500, nanoseconds: 250 }))\n// → '500 microseconds, 250 nanoseconds' (sub-ms units fully supported)\n\n// --- parseDuration() ---\nconst dur = parseDuration('P0Y2M3DT0H5M10S')\nconsole.log('months:', dur.months, 'days:', dur.days, 'minutes:', dur.minutes)\n\n// --- difference() produces a Duration ---\nconst a = parseZoned('2026-01-01T00:00:00[UTC]')\nconst b = parseZoned('2026-06-15T09:30:00[UTC]')\nconst d = difference(a, b, { largestUnit: 'month' })\nconsole.log(formatDuration(d)) // '5 months, 14 days, 9 hours, 30 minutes'\n\n// --- inTz() re-projection ---\n// Same absolute instant, different wall-clock\nconst berlin = parseZoned('2026-03-21T11:00:00+01:00[Europe/Berlin]')\nconst utc = inTz(berlin, 'UTC')\nconst tokyo = inTz(berlin, 'Asia/Tokyo')\n\nconsole.log('Berlin:', berlin.toString())\nconsole.log('UTC:', utc.toString()) // wall-clock: 10:00 UTC\nconsole.log('Tokyo:', tokyo.toString()) // wall-clock: 19:00 JST\nconsole.log('Same instant?', berlin.toInstant().epochMilliseconds === utc.toInstant().epochMilliseconds)",
23
- "name": "Duration & Timezone Projection"
24
- },
25
- {
26
- "id": "error-handling",
27
- "code": "import { TempoError, TempoInvalidTzError, TempoMissingTzError, inTz, parse, parsePlainDateTime, toInstant } from '@vielzeug/tempo';\n\n// ── TempoInvalidInputError: bad parse string ─────────────────────────────────\ntry {\n parse('not-a-date');\n} catch (e) {\n if (e instanceof TempoError) {\n console.log(e.name); // 'TempoInvalidInputError'\n console.log(e.message); // 'Unable to parse date/time string: \"not-a-date\". ...'\n }\n}\n\n// ── TempoMissingTzError: plain input without timezone ────────────────────────\ntry {\n toInstant(parsePlainDateTime('2026-03-21T10:00:00'));\n} catch (e) {\n if (e instanceof TempoMissingTzError) {\n console.log(e.name); // 'TempoMissingTzError'\n }\n}\n\n// ── TempoInvalidTzError: bad timezone string ─────────────────────────────────\ntry {\n inTz(parse('2026-03-21T10:00:00Z', 'instant'), 'Not/AZone');\n} catch (e) {\n if (e instanceof TempoInvalidTzError) {\n console.log(e.name); // 'TempoInvalidTzError'\n }\n}\n\n// ── Every subtype is also a TempoError (single catch-all) ───────────────────\ntry {\n parse('bad');\n} catch (e) {\n console.log(e instanceof Error); // true\n console.log(e instanceof TempoError); // true\n console.log(TempoError.is(e)); // true — static type guard, same check\n}\n",
28
- "name": "TempoError — instanceof checks across the error hierarchy"
29
- },
30
- {
31
- "id": "expires-and-date-range",
32
- "code": "import { dateRange, expires, humanize, now, parseInstant, parseZoned, recurrence, shift, timeDiff } from '@vielzeug/tempo'\n\n// --- expires() ---\nconst THRESHOLDS = {\n longExpired: { days: -30 },\n expired: { days: 0 },\n critical: { days: 3 },\n warning: { days: 14 },\n safe: { years: 100 },\n}\n\n// Use tempo helpers — no Temporal.* needed\nconst past = shift(now('UTC'), { hours: -1 }).toInstant()\nconst soon = shift(now('UTC'), { hours: 48 }).toInstant()\nconst later = shift(now('UTC'), { days: 10 }).toInstant()\n\nconsole.log('past:', expires(past, THRESHOLDS)) // 'expired'\nconsole.log('soon:', expires(soon, THRESHOLDS)) // 'critical'\nconsole.log('later:', expires(later, THRESHOLDS)) // 'warning'\n\n// --- expires() + timeDiff() composition ---\nconst key = expires(soon, THRESHOLDS)\nconst diff = timeDiff(now('UTC').toInstant(), soon)\nconsole.log('key:', key, '|', humanize(diff)) // 'critical | 2 days'\nconsole.log('localized:', humanize(diff, { locale: 'ar-EG' })) // Arabic numerals\n\n// --- timeDiff() ---\nconst a = parseInstant('2026-01-01T00:00:00Z')\nconst b = parseInstant('2027-06-15T00:00:00Z')\nconsole.log('timeDiff:', timeDiff(a, b).value, timeDiff(a, b).unit) // 1 year\n\n// --- dateRange() — tz inferred from ZonedDateTime, no options needed ---\nconst start = parseZoned('2026-03-01T00:00:00[America/New_York]')\nconst end = parseZoned('2026-03-05T00:00:00[America/New_York]')\n\nfor (const day of dateRange(start, end, { days: 1 })) {\n console.log(day.toPlainDate().toString(), day.timeZoneId)\n}\n\n// --- recurrence() — tz inferred from ZonedDateTime start ---\nconst weekly = recurrence(start, { frequency: 'weekly', count: 3 })\nfor (const date of weekly) {\n console.log('weekly:', date.toPlainDate().toString())\n}",
33
- "name": "Expires & Date Range"
34
- },
35
10
  {
36
11
  "id": "meeting-duration",
37
- "code": "import { difference, parseInstant, timeDiff, within } from '@vielzeug/tempo'\n\nconst start = parseInstant('2026-03-21T10:00:00Z')\nconst end = parseInstant('2026-03-21T12:45:00Z')\n\n// Two Instants with sub-day units no tz needed\nconst duration = difference(start, end, {\n largestUnit: 'hour',\n smallestUnit: 'minute',\n})\n\nconsole.log('Duration ISO:', duration.toString())\nconsole.log('11:00 in range:', within(parseInstant('2026-03-21T11:00:00Z'), start, end))\n\n// Human-readable largest-unit diff\nconst diff = timeDiff(start, end)\nconsole.log('timeDiff:', diff.value, diff.unit)",
38
- "name": "Meeting Duration"
39
- },
40
- {
41
- "id": "timezone-aware-scheduling",
42
- "code": "import { format, formatZoned, inTz, parsePlainDateTime, toInstant } from '@vielzeug/tempo'\n\nconst meetingUtc = toInstant(parsePlainDateTime('2026-04-15T14:00:00'), { tz: 'UTC' })\nconst attendees = [\n { name: 'Alice', tz: 'America/New_York' },\n { name: 'Bruno', tz: 'Europe/Berlin' },\n { name: 'Keiko', tz: 'Asia/Tokyo' },\n]\n\nfor (const attendee of attendees) {\n const local = inTz(meetingUtc, attendee.tz)\n console.log(attendee.name + ':', format(local, { pattern: 'long', locale: 'en-US' }))\n console.log(' zoned:', formatZoned(meetingUtc, { tz: attendee.tz }))\n}",
43
- "name": "Timezone-Aware Scheduling"
44
- },
45
- {
46
- "id": "timezone-conversion",
47
- "code": "import { format, formatInstant, formatZoned, inTz, parse } from '@vielzeug/tempo'\n\n// parse() auto-detects the type; 'instant' narrows the return type\nconst utc = parse('2026-03-21T10:15:30Z', 'instant')\nconst tokyo = inTz(utc, 'Asia/Tokyo')\nconst berlin = inTz(utc, 'Europe/Berlin')\n\nconsole.log('UTC instant:', formatInstant(utc))\nconsole.log('Tokyo zoned:', formatZoned(tokyo))\nconsole.log('Berlin wall-clock:', format(berlin, { pattern: 'short', locale: 'de-DE' }))\n\n// Re-projecting a ZonedDateTime: same instant, new wall-clock\nconst berlinToNY = inTz(berlin, 'America/New_York')\nconsole.log('Berlin → New York:', berlinToNY.toString())",
48
- "name": "Timezone Projection with inTz"
12
+ "code": "import { classifyExpiry, contains, difference, format, inTimeZone, parse, shift, toInstant } from '@vielzeug/tempo'\n\nconst local = parse('2026-03-21T10:00:00', { as: 'plainDateTime' })\nconst start = toInstant(local, { timeZone: 'America/New_York' })\nconst end = shift(start, { hours: 2 }, { timeZone: 'America/New_York' }).toInstant()\nconst check = parse('2026-03-21T11:00:00Z', { as: 'instant' })\n\nconsole.log('Duration:', difference({ end, largestUnit: 'hour', start }).toString())\nconsole.log('Contains check:', contains({ end, start, value: check }))\nconsole.log('New York:', format(inTimeZone(start, 'America/New_York'), { locale: 'en-US', pattern: 'short' }))\nconsole.log('Expiry:', classifyExpiry({ thresholds: { soon: { days: 3 } }, value: end }))",
13
+ "name": "Explicit Parsing and Timezone Arithmetic"
49
14
  }
50
15
  ],
51
16
  "typeSignatures": {
@@ -55,25 +20,21 @@
55
20
  "TempoInvalidTzError": "export {\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n} from './errors';",
56
21
  "TempoMissingTzError": "export {\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n} from './errors';",
57
22
  "TempoUnsupportedInputError": "export {\n TempoError,\n TempoInvalidInputError,\n TempoInvalidTzError,\n TempoMissingTzError,\n TempoUnsupportedInputError,\n} from './errors';",
58
- "difference": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
59
- "isValid": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
60
- "now": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
61
- "nowInstant": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
62
- "parse": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
63
- "parseInstant": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
64
- "parsePlainDate": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
65
- "parsePlainDateTime": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
66
- "parseZoned": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
67
- "shift": "export {\n difference,\n isValid,\n now,\n nowInstant,\n parse,\n parseInstant,\n parsePlainDate,\n parsePlainDateTime,\n parseZoned,\n shift,\n} from './core';",
68
- "inTz": "export { inTz, toInstant } from './_convert';",
69
- "toInstant": "export { inTz, toInstant } from './_convert';",
23
+ "difference": "export { difference, isValid, now, nowInstant, parse, shift } from './core';",
24
+ "isValid": "export { difference, isValid, now, nowInstant, parse, shift } from './core';",
25
+ "now": "export { difference, isValid, now, nowInstant, parse, shift } from './core';",
26
+ "nowInstant": "export { difference, isValid, now, nowInstant, parse, shift } from './core';",
27
+ "parse": "export { difference, isValid, now, nowInstant, parse, shift } from './core';",
28
+ "shift": "export { difference, isValid, now, nowInstant, parse, shift } from './core';",
29
+ "inTimeZone": "export { inTimeZone, toInstant } from './_convert';",
30
+ "toInstant": "export { inTimeZone, toInstant } from './_convert';",
70
31
  "endOf": "export { endOf, startOf } from './boundary';",
71
32
  "startOf": "export { endOf, startOf } from './boundary';",
72
- "clamp": "export { clamp, isAfter, isBefore, isSame, within } from './compare';",
73
- "isAfter": "export { clamp, isAfter, isBefore, isSame, within } from './compare';",
74
- "isBefore": "export { clamp, isAfter, isBefore, isSame, within } from './compare';",
75
- "isSame": "export { clamp, isAfter, isBefore, isSame, within } from './compare';",
76
- "within": "export { clamp, isAfter, isBefore, isSame, within } from './compare';",
33
+ "clamp": "export { clamp, contains, isAfter, isBefore, isSame } from './compare';",
34
+ "contains": "export { clamp, contains, isAfter, isBefore, isSame } from './compare';",
35
+ "isAfter": "export { clamp, contains, isAfter, isBefore, isSame } from './compare';",
36
+ "isBefore": "export { clamp, contains, isAfter, isBefore, isSame } from './compare';",
37
+ "isSame": "export { clamp, contains, isAfter, isBefore, isSame } from './compare';",
77
38
  "format": "export {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';",
78
39
  "formatDuration": "export {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';",
79
40
  "formatInstant": "export {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';",
@@ -84,30 +45,37 @@
84
45
  "formatZoned": "export {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';",
85
46
  "humanize": "export {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';",
86
47
  "parseDuration": "export {\n format,\n formatDuration,\n formatInstant,\n formatParts,\n formatRange,\n formatRangeParts,\n formatRelative,\n formatZoned,\n humanize,\n parseDuration,\n} from './format';",
87
- "expires": "export { expires, timeDiff } from './classify';",
88
- "timeDiff": "export { expires, timeDiff } from './classify';",
48
+ "classifyExpiry": "export { classifyExpiry, timeDiff } from './classify';",
49
+ "timeDiff": "export { classifyExpiry, timeDiff } from './classify';",
89
50
  "dateRange": "export { dateRange, recurrence } from './range';",
90
51
  "recurrence": "export { dateRange, recurrence } from './range';",
91
- "BoundaryOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
92
- "BoundaryUnit": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
93
- "CalendarUnit": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
94
- "CompareOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
95
- "DateTimeDisambiguation": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
96
- "DifferenceOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
97
- "DisambiguationOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
98
- "DurationFormatOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
99
- "FormatOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
100
- "FormatPattern": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
101
- "ParseAs": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
102
- "RecurrenceRule": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
103
- "RelativeFormatOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
104
- "RelativeTimeInput": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
105
- "ShiftOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
106
- "TempoUnit": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
107
- "TimeDiffResult": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
108
- "TimeDiffUnit": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
109
- "TimeInput": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
110
- "TimeOptions": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';",
111
- "WeekStartDay": "export type {\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n CompareOptions,\n DateTimeDisambiguation,\n DifferenceOptions,\n DisambiguationOptions,\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeOptions,\n WeekStartDay,\n} from './types';"
52
+ "AbsoluteTime": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
53
+ "BoundaryOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
54
+ "BoundaryUnit": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
55
+ "CalendarUnit": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
56
+ "ClampInput": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
57
+ "ClassifyExpiryInput": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
58
+ "CompareOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
59
+ "ContainsInput": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
60
+ "DifferenceInput": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
61
+ "Disambiguation": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
62
+ "DisambiguationOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
63
+ "DurationFormatOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
64
+ "ExpiryThresholds": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
65
+ "FixedDuration": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
66
+ "FormatOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
67
+ "FormatPattern": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
68
+ "ParseAs": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
69
+ "RecurrenceRule": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
70
+ "RelativeFormatOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
71
+ "RelativeTimeInput": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
72
+ "ShiftOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
73
+ "TempoUnit": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
74
+ "TimeDiffResult": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
75
+ "TimeDiffUnit": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
76
+ "TimeInput": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
77
+ "TimeZoneOptions": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
78
+ "WallTime": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';",
79
+ "WeekStartDay": "export type {\n AbsoluteTime,\n BoundaryOptions,\n BoundaryUnit,\n CalendarUnit,\n ClampInput,\n ClassifyExpiryInput,\n CompareOptions,\n ContainsInput,\n DifferenceInput,\n Disambiguation,\n DisambiguationOptions,\n DurationFormatOptions,\n ExpiryThresholds,\n FixedDuration,\n FormatOptions,\n FormatPattern,\n ParseAs,\n RecurrenceRule,\n RelativeFormatOptions,\n RelativeTimeInput,\n ShiftOptions,\n TempoUnit,\n TimeDiffResult,\n TimeDiffUnit,\n TimeInput,\n TimeZoneOptions,\n WallTime,\n WeekStartDay,\n} from './types';"
112
80
  }
113
81
  }