@mostlyrightmd/core 1.1.3 → 1.2.0

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 (43) hide show
  1. package/README.md +1 -1
  2. package/dist/discovery/index.cjs +44 -7
  3. package/dist/discovery/index.cjs.map +1 -1
  4. package/dist/discovery/index.d.cts +34 -6
  5. package/dist/discovery/index.d.ts +34 -6
  6. package/dist/discovery/index.mjs +44 -7
  7. package/dist/discovery/index.mjs.map +1 -1
  8. package/dist/index.cjs +39 -1
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +16 -2
  11. package/dist/index.d.ts +16 -2
  12. package/dist/index.global.js +37 -1
  13. package/dist/index.global.js.map +1 -1
  14. package/dist/index.mjs +37 -1
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/internal/cache/index.browser.cjs +77 -4
  17. package/dist/internal/cache/index.browser.cjs.map +1 -1
  18. package/dist/internal/cache/index.browser.d.cts +8 -2
  19. package/dist/internal/cache/index.browser.d.ts +8 -2
  20. package/dist/internal/cache/index.browser.mjs +10 -5
  21. package/dist/internal/cache/index.browser.mjs.map +1 -1
  22. package/dist/internal/cache/index.cjs +79 -2
  23. package/dist/internal/cache/index.cjs.map +1 -1
  24. package/dist/internal/cache/index.d.cts +12 -6
  25. package/dist/internal/cache/index.d.ts +12 -6
  26. package/dist/internal/cache/index.mjs +12 -3
  27. package/dist/internal/cache/index.mjs.map +1 -1
  28. package/dist/internal/{chunk-PKJXHY27.mjs → chunk-IPC4XUYW.mjs} +70 -1
  29. package/dist/internal/chunk-IPC4XUYW.mjs.map +1 -0
  30. package/dist/internal/{keys-B7C8C88N.d.cts → versionedCacheStore-DyHDqFIC.d.cts} +23 -1
  31. package/dist/internal/{keys-B7C8C88N.d.ts → versionedCacheStore-DyHDqFIC.d.ts} +23 -1
  32. package/dist/preprocessing/index.cjs +150 -0
  33. package/dist/preprocessing/index.cjs.map +1 -0
  34. package/dist/preprocessing/index.d.cts +111 -0
  35. package/dist/preprocessing/index.d.ts +111 -0
  36. package/dist/preprocessing/index.mjs +121 -0
  37. package/dist/preprocessing/index.mjs.map +1 -0
  38. package/dist/temporal/index.cjs.map +1 -1
  39. package/dist/temporal/index.mjs.map +1 -1
  40. package/dist/validator.cjs.map +1 -1
  41. package/dist/validator.mjs.map +1 -1
  42. package/package.json +25 -2
  43. package/dist/internal/chunk-PKJXHY27.mjs.map +0 -1
package/package.json CHANGED
@@ -1,7 +1,25 @@
1
1
  {
2
2
  "name": "@mostlyrightmd/core",
3
- "version": "1.1.3",
4
- "description": "Local-first TypeScript SDK core for prediction-market research over public data: types, schemas, validators, temporal-safety primitives, and the research() join.",
3
+ "version": "1.2.0",
4
+ "description": "TypeScript SDK core for quants, ML pipelines, and AI agents: types, schemas, validators, temporal-safety primitives, and the research() join over weather data + prediction-market settlements. Local-first, no hosted backend.",
5
+ "keywords": [
6
+ "weather",
7
+ "weather-data",
8
+ "prediction-markets",
9
+ "kalshi",
10
+ "polymarket",
11
+ "machine-learning",
12
+ "ml-training",
13
+ "ai-agents",
14
+ "backtesting",
15
+ "quant-research",
16
+ "time-series",
17
+ "schema-versioned",
18
+ "json-schema",
19
+ "local-first",
20
+ "typescript",
21
+ "sdk"
22
+ ],
5
23
  "license": "MIT",
6
24
  "homepage": "https://mostlyright.md/docs/sdk/",
7
25
  "repository": {
@@ -89,6 +107,11 @@
89
107
  "types": "./dist/discovery/index.d.ts",
90
108
  "import": "./dist/discovery/index.mjs",
91
109
  "require": "./dist/discovery/index.cjs"
110
+ },
111
+ "./preprocessing": {
112
+ "types": "./dist/preprocessing/index.d.ts",
113
+ "import": "./dist/preprocessing/index.mjs",
114
+ "require": "./dist/preprocessing/index.cjs"
92
115
  }
93
116
  },
94
117
  "files": [
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/internal/cache/types.ts","../../src/internal/cache/memory.ts","../../src/internal/cache/indexeddb.ts","../../src/data/generated/stations.ts","../../src/snapshot.ts","../../src/internal/cache/skip-rules.ts","../../src/internal/cache/keys.ts"],"sourcesContent":["// CacheStore — pluggable key/value contract for the @mostlyrightmd/core cache\n// layer. Three concrete implementations land in TS-W3:\n// - MemoryStore — Map-backed, no persistence (Cloudflare Workers default).\n// - FsStore — node:fs/promises + proper-lockfile (Node default).\n// - IndexedDBStore — idb + Web Locks API (browser; plan 02).\n//\n// `defaultCacheStore()` (plan 02) auto-detects at runtime per\n// TS-SDK-DESIGN §5.4.\n\n/** Cache entry envelope with optional TTL. */\nexport interface CacheEntry<T = unknown> {\n readonly value: T;\n /** Epoch ms when the entry expires. Absence = no expiry. */\n readonly expiresAt?: number;\n}\n\n/** Optional setters for cache writes. */\nexport interface CacheSetOptions {\n /** Time-to-live in milliseconds. Implementations may honor or ignore. */\n readonly ttlMs?: number;\n}\n\n/**\n * Pluggable key/value cache contract used throughout the SDK.\n *\n * All methods are async — concrete implementations may resolve immediately\n * (MemoryStore) or do I/O (FsStore / IndexedDBStore).\n *\n * Semantic contract:\n * - `get<T>(key)` returns the stored value or `null` on miss. NEVER throws\n * on miss.\n * - `set<T>(key, value, opts?)` overwrites. ttlMs is implementation-honored\n * (MemoryStore + IndexedDBStore honor it; FsStore ignores in v0.1).\n * - `delete(key)` is a no-op on miss; returns void.\n * - `withLock<T>(key, fn)` runs `fn` under a key-scoped exclusive lock and\n * releases on settle (resolve OR throw). Nested calls to the same key\n * serialize; calls to different keys MAY run in parallel.\n */\nexport interface CacheStore {\n get<T = unknown>(key: string): Promise<T | null>;\n set<T = unknown>(key: string, value: T, opts?: CacheSetOptions): Promise<void>;\n delete(key: string): Promise<void>;\n withLock<T>(key: string, fn: () => Promise<T>): Promise<T>;\n}\n\n/**\n * Canonical lock identifier for a given cache key.\n *\n * Pure — same key → same lock id. Used by FsStore (proper-lockfile sidecar)\n * and IndexedDBStore (`navigator.locks.request(...)` name).\n */\nexport function lockKeyFor(key: string): string {\n return `mostlyright:cache:lock:${key}`;\n}\n","// MemoryStore — Map-backed CacheStore for ephemeral runtimes (Cloudflare\n// Workers, jsdom test envs without persistence). NOT shared across\n// processes — per-instance state.\n//\n// Value isolation via `structuredClone`: callers can mutate stored objects\n// after `.set()` without leaking changes back. Honors ttlMs with lazy\n// eviction at `.get()` time.\n//\n// withLock uses a per-key promise chain — pending lock-acquisitions queue\n// behind the current holder and run in FIFO order on settle.\n\nimport type { CacheEntry, CacheSetOptions, CacheStore } from \"./types.js\";\n\n/**\n * In-memory cache. Per-instance state; two MemoryStore instances do NOT\n * share state.\n *\n * - Values cloned via `structuredClone` so post-`set` mutation can't leak.\n * - ttlMs honored with lazy eviction on `get`.\n * - withLock serializes nested calls via a per-key promise chain.\n */\nexport class MemoryStore implements CacheStore {\n readonly #entries = new Map<string, CacheEntry<unknown>>();\n readonly #chain = new Map<string, Promise<unknown>>();\n\n async get<T = unknown>(key: string): Promise<T | null> {\n const e = this.#entries.get(key);\n if (e === undefined) return null;\n if (e.expiresAt !== undefined && Date.now() >= e.expiresAt) {\n this.#entries.delete(key);\n return null;\n }\n // Defensive clone on read too — callers can't mutate stored value via\n // the returned reference either.\n return structuredClone(e.value) as T;\n }\n\n async set<T = unknown>(key: string, value: T, opts?: CacheSetOptions): Promise<void> {\n const cloned = structuredClone(value);\n const entry: CacheEntry<unknown> =\n opts?.ttlMs !== undefined\n ? { value: cloned, expiresAt: Date.now() + opts.ttlMs }\n : { value: cloned };\n this.#entries.set(key, entry);\n }\n\n async delete(key: string): Promise<void> {\n this.#entries.delete(key);\n }\n\n /**\n * Enumerate live (non-expired) keys with the given prefix.\n *\n * TS-W6 Wave 1: `availability()` uses this to count cached observation\n * months and climate years per station. Expired entries are evicted as a\n * side effect (same lazy-eviction policy as `.get`).\n */\n async listKeys(prefix: string): Promise<ReadonlyArray<string>> {\n const now = Date.now();\n const out: string[] = [];\n for (const [key, entry] of this.#entries) {\n if (entry.expiresAt !== undefined && now >= entry.expiresAt) {\n this.#entries.delete(key);\n continue;\n }\n if (key.startsWith(prefix)) {\n out.push(key);\n }\n }\n return Object.freeze(out);\n }\n\n async withLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const prev = this.#chain.get(key) ?? Promise.resolve();\n // Chain `fn` after `prev` regardless of whether `prev` resolved or\n // rejected — the lock holder's failure shouldn't poison the queue.\n const next = prev.then(\n () => fn(),\n () => fn(),\n );\n // Store an absorber as the new tail so a later prev.then() handles\n // both branches without producing an unhandled-rejection warning. The\n // caller still receives the original `next` promise (including any\n // rejection from `fn`).\n const absorbed = next.then(\n () => undefined,\n () => undefined,\n );\n this.#chain.set(key, absorbed);\n absorbed.finally(() => {\n if (this.#chain.get(key) === absorbed) {\n this.#chain.delete(key);\n }\n });\n return next;\n }\n}\n","// IndexedDBStore — idb + Web Locks API CacheStore for browsers.\n//\n// Per TS-CACHE-02, the canonical IndexedDB DB name is `mostlyright-cache-v1`.\n// Object store: `entries`. Schema: key = string, value = CacheEntry<T>.\n//\n// withLock prefers `navigator.locks.request(name, ...)` (Web Locks API,\n// Chrome 69+, Firefox 96+, Safari 15.4+; all production-browser baselines).\n// When `navigator.locks` is unavailable (jsdom default), falls back to the\n// same per-key in-process promise chain used by MemoryStore / FsStore —\n// edge runtimes (Workers without web-locks polyfills) get the in-process\n// guarantee at least.\n//\n// ttlMs is honored via lazy eviction at `get` time (matches FsStore).\n\nimport { type IDBPDatabase, openDB } from \"idb\";\n\nimport type { CacheEntry, CacheSetOptions, CacheStore } from \"./types.js\";\nimport { lockKeyFor } from \"./types.js\";\n\n/** Canonical DB name. Re-exported via the cache barrel. */\nexport const DB_NAME = \"mostlyright-cache-v1\";\n\nconst STORE_NAME = \"entries\";\nconst SCHEMA_VERSION = 1;\n\nexport interface IndexedDBStoreOptions {\n /** Override the DB name. Tests pass unique values per case so they don't pollute each other. */\n readonly dbName?: string;\n}\n\ninterface WebLocksApi {\n request: <T>(\n name: string,\n options: { mode: \"exclusive\" },\n fn: () => Promise<T> | T,\n ) => Promise<T>;\n}\n\nfunction getWebLocks(): WebLocksApi | null {\n if (typeof navigator === \"undefined\") return null;\n const nav = navigator as unknown as { locks?: WebLocksApi };\n return nav.locks ?? null;\n}\n\n/**\n * Browser CacheStore backed by IndexedDB (via idb) + Web Locks API.\n *\n * When `navigator.locks` is unavailable (jsdom, edge runtimes without\n * Web Locks), falls back to a per-key in-process promise chain.\n */\nexport class IndexedDBStore implements CacheStore {\n readonly #dbName: string;\n readonly #dbPromise: Promise<IDBPDatabase>;\n readonly #chain = new Map<string, Promise<unknown>>();\n\n constructor(opts: IndexedDBStoreOptions = {}) {\n this.#dbName = opts.dbName ?? DB_NAME;\n this.#dbPromise = openDB(this.#dbName, SCHEMA_VERSION, {\n upgrade(db) {\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n },\n });\n }\n\n async get<T = unknown>(key: string): Promise<T | null> {\n const db = await this.#dbPromise;\n const entry = (await db.get(STORE_NAME, key)) as CacheEntry<T> | undefined;\n if (entry === undefined) return null;\n if (entry.expiresAt !== undefined && Date.now() >= entry.expiresAt) {\n // Lazy-evict — best-effort; ignore failures.\n try {\n await db.delete(STORE_NAME, key);\n } catch {\n // ignore\n }\n return null;\n }\n return entry.value as T;\n }\n\n async set<T = unknown>(key: string, value: T, opts?: CacheSetOptions): Promise<void> {\n const db = await this.#dbPromise;\n const entry: CacheEntry<T> =\n opts?.ttlMs !== undefined ? { value, expiresAt: Date.now() + opts.ttlMs } : { value };\n await db.put(STORE_NAME, entry, key);\n }\n\n async delete(key: string): Promise<void> {\n const db = await this.#dbPromise;\n await db.delete(STORE_NAME, key);\n }\n\n /**\n * Enumerate keys with the given prefix using IndexedDB's bounded range\n * query. Live keys only — expired entries are lazy-evicted on read by\n * `get()`, so a stale-but-not-yet-evicted entry can appear here; callers\n * who care about expiration should `get()` to confirm.\n *\n * TS-W6 Wave 1: `availability()` uses this to count observation months and\n * climate years for a station.\n */\n async listKeys(prefix: string): Promise<ReadonlyArray<string>> {\n const db = await this.#dbPromise;\n // Build an inclusive lower bound and an exclusive upper bound using the\n // next-codepoint trick. IndexedDB's IDBKeyRange handles string ordering\n // by UTF-16 code units, which matches JS string comparison; we use the\n // Unicode max-codepoint as the upper sentinel so any key starting with\n // `prefix` lands inside the range.\n const range = IDBKeyRange.bound(prefix, `${prefix}￿`, false, false);\n const keys = (await db.getAllKeys(STORE_NAME, range)) as IDBValidKey[];\n const out: string[] = [];\n for (const k of keys) {\n if (typeof k === \"string\" && k.startsWith(prefix)) {\n out.push(k);\n }\n }\n return Object.freeze(out);\n }\n\n async withLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const locks = getWebLocks();\n if (locks !== null) {\n // Web Locks API — production-browser path. Cross-tab safe.\n return locks.request<T>(lockKeyFor(key), { mode: \"exclusive\" }, () => fn());\n }\n // Fallback for jsdom / edge runtimes without navigator.locks: in-process\n // per-key promise chain (FIFO; matches MemoryStore semantics).\n const prev = this.#chain.get(key) ?? Promise.resolve();\n const next = prev.then(\n () => fn(),\n () => fn(),\n );\n const absorbed = next.then(\n () => undefined,\n () => undefined,\n );\n this.#chain.set(key, absorbed);\n absorbed.finally(() => {\n if (this.#chain.get(key) === absorbed) this.#chain.delete(key);\n });\n return next;\n }\n}\n","// AUTO-GENERATED by @mostlyrightmd/codegen from schemas/stations.json.\n// DO NOT EDIT — regenerate with: pnpm codegen\n// Last manifest SHA recorded in schemas/EXPORT_MANIFEST.json\n\nexport interface StationInfo {\n code: string | null;\n ghcnh_id: string | null;\n icao: string;\n name: string | null;\n tz: string;\n latitude: number | null;\n longitude: number | null;\n country: string | null;\n}\n\nexport const STATIONS: ReadonlyArray<StationInfo> = [\n {\n code: \"EDDB\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDB\",\n latitude: 52.3667,\n longitude: 13.5033,\n name: \"Berlin Brandenburg\",\n tz: \"Europe/Berlin\",\n },\n {\n code: \"EDDF\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDF\",\n latitude: 50.0379,\n longitude: 8.5622,\n name: \"Frankfurt am Main\",\n tz: \"Europe/Berlin\",\n },\n {\n code: \"EDDM\",\n country: \"DE\",\n ghcnh_id: null,\n icao: \"EDDM\",\n latitude: 48.3538,\n longitude: 11.7861,\n name: \"Munich Franz Josef Strauss\",\n tz: \"Europe/Berlin\",\n },\n {\n code: \"EFHK\",\n country: \"FI\",\n ghcnh_id: null,\n icao: \"EFHK\",\n latitude: 60.3172,\n longitude: 24.9633,\n name: \"Helsinki-Vantaa\",\n tz: \"Europe/Helsinki\",\n },\n {\n code: \"EGKK\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGKK\",\n latitude: 51.1481,\n longitude: -0.1903,\n name: \"London Gatwick\",\n tz: \"Europe/London\",\n },\n {\n code: \"EGLL\",\n country: \"GB\",\n ghcnh_id: null,\n icao: \"EGLL\",\n latitude: 51.4706,\n longitude: -0.4619,\n name: \"London Heathrow\",\n tz: \"Europe/London\",\n },\n {\n code: \"EHAM\",\n country: \"NL\",\n ghcnh_id: null,\n icao: \"EHAM\",\n latitude: 52.3086,\n longitude: 4.7639,\n name: \"Amsterdam Schiphol\",\n tz: \"Europe/Amsterdam\",\n },\n {\n code: \"EKCH\",\n country: \"DK\",\n ghcnh_id: null,\n icao: \"EKCH\",\n latitude: 55.6181,\n longitude: 12.6561,\n name: \"Copenhagen Kastrup\",\n tz: \"Europe/Copenhagen\",\n },\n {\n code: \"EPWA\",\n country: \"PL\",\n ghcnh_id: null,\n icao: \"EPWA\",\n latitude: 52.1657,\n longitude: 20.9671,\n name: \"Warsaw Chopin\",\n tz: \"Europe/Warsaw\",\n },\n {\n code: \"ESSA\",\n country: \"SE\",\n ghcnh_id: null,\n icao: \"ESSA\",\n latitude: 59.6519,\n longitude: 17.9186,\n name: \"Stockholm Arlanda\",\n tz: \"Europe/Stockholm\",\n },\n {\n code: \"ATL\",\n country: \"US\",\n ghcnh_id: \"USW00013874\",\n icao: \"KATL\",\n latitude: 33.6407,\n longitude: -84.4277,\n name: \"Hartsfield-Jackson Atlanta International\",\n tz: \"America/New_York\",\n },\n {\n code: \"AUS\",\n country: \"US\",\n ghcnh_id: \"USW00013904\",\n icao: \"KAUS\",\n latitude: 30.1975,\n longitude: -97.6664,\n name: \"Austin-Bergstrom International\",\n tz: \"America/Chicago\",\n },\n {\n code: \"BOS\",\n country: \"US\",\n ghcnh_id: \"USW00014739\",\n icao: \"KBOS\",\n latitude: 42.3656,\n longitude: -71.0096,\n name: \"Boston Logan International\",\n tz: \"America/New_York\",\n },\n {\n code: \"DCA\",\n country: \"US\",\n ghcnh_id: \"USW00013743\",\n icao: \"KDCA\",\n latitude: 38.8512,\n longitude: -77.0402,\n name: \"Washington Reagan National\",\n tz: \"America/New_York\",\n },\n {\n code: \"DEN\",\n country: \"US\",\n ghcnh_id: \"USW00003017\",\n icao: \"KDEN\",\n latitude: 39.8561,\n longitude: -104.6737,\n name: \"Denver International\",\n tz: \"America/Denver\",\n },\n {\n code: \"DFW\",\n country: \"US\",\n ghcnh_id: \"USW00003927\",\n icao: \"KDFW\",\n latitude: 32.8998,\n longitude: -97.0403,\n name: \"Dallas-Fort Worth International\",\n tz: \"America/Chicago\",\n },\n {\n code: \"HOU\",\n country: \"US\",\n ghcnh_id: \"USW00012918\",\n icao: \"KHOU\",\n latitude: 29.6454,\n longitude: -95.2789,\n name: \"Houston Hobby\",\n tz: \"America/Chicago\",\n },\n {\n code: \"LAS\",\n country: \"US\",\n ghcnh_id: \"USW00023169\",\n icao: \"KLAS\",\n latitude: 36.084,\n longitude: -115.1537,\n name: \"Harry Reid (McCarran) International\",\n tz: \"America/Los_Angeles\",\n },\n {\n code: \"LAX\",\n country: \"US\",\n ghcnh_id: \"USW00023174\",\n icao: \"KLAX\",\n latitude: 33.9425,\n longitude: -118.4081,\n name: \"Los Angeles International\",\n tz: \"America/Los_Angeles\",\n },\n {\n code: \"MDW\",\n country: \"US\",\n ghcnh_id: \"USW00014819\",\n icao: \"KMDW\",\n latitude: 41.7868,\n longitude: -87.7522,\n name: \"Chicago Midway International\",\n tz: \"America/Chicago\",\n },\n {\n code: \"MIA\",\n country: \"US\",\n ghcnh_id: \"USW00012839\",\n icao: \"KMIA\",\n latitude: 25.7959,\n longitude: -80.287,\n name: \"Miami International\",\n tz: \"America/New_York\",\n },\n {\n code: \"MSP\",\n country: \"US\",\n ghcnh_id: \"USW00014922\",\n icao: \"KMSP\",\n latitude: 44.8848,\n longitude: -93.2223,\n name: \"Minneapolis-St Paul International\",\n tz: \"America/Chicago\",\n },\n {\n code: \"MSY\",\n country: \"US\",\n ghcnh_id: \"USW00012916\",\n icao: \"KMSY\",\n latitude: 29.9934,\n longitude: -90.258,\n name: \"New Orleans Louis Armstrong International\",\n tz: \"America/Chicago\",\n },\n {\n code: \"NYC\",\n country: \"US\",\n ghcnh_id: \"USW00094728\",\n icao: \"KNYC\",\n latitude: 40.7789,\n longitude: -73.9692,\n name: \"Central Park, New York\",\n tz: \"America/New_York\",\n },\n {\n code: \"OKC\",\n country: \"US\",\n ghcnh_id: \"USW00013967\",\n icao: \"KOKC\",\n latitude: 35.3931,\n longitude: -97.6007,\n name: \"Oklahoma City Will Rogers World\",\n tz: \"America/Chicago\",\n },\n {\n code: \"PHL\",\n country: \"US\",\n ghcnh_id: \"USW00013739\",\n icao: \"KPHL\",\n latitude: 39.8721,\n longitude: -75.2411,\n name: \"Philadelphia International\",\n tz: \"America/New_York\",\n },\n {\n code: \"PHX\",\n country: \"US\",\n ghcnh_id: \"USW00023183\",\n icao: \"KPHX\",\n latitude: 33.4373,\n longitude: -112.0078,\n name: \"Phoenix Sky Harbor International\",\n tz: \"America/Phoenix\",\n },\n {\n code: \"SAT\",\n country: \"US\",\n ghcnh_id: \"USW00012921\",\n icao: \"KSAT\",\n latitude: 29.5337,\n longitude: -98.4698,\n name: \"San Antonio International\",\n tz: \"America/Chicago\",\n },\n {\n code: \"SEA\",\n country: \"US\",\n ghcnh_id: \"USW00024233\",\n icao: \"KSEA\",\n latitude: 47.4502,\n longitude: -122.3088,\n name: \"Seattle-Tacoma International\",\n tz: \"America/Los_Angeles\",\n },\n {\n code: \"SFO\",\n country: \"US\",\n ghcnh_id: \"USW00023234\",\n icao: \"KSFO\",\n latitude: 37.6213,\n longitude: -122.379,\n name: \"San Francisco International\",\n tz: \"America/Los_Angeles\",\n },\n {\n code: \"LEBL\",\n country: \"ES\",\n ghcnh_id: null,\n icao: \"LEBL\",\n latitude: 41.2974,\n longitude: 2.0833,\n name: \"Barcelona El Prat\",\n tz: \"Europe/Madrid\",\n },\n {\n code: \"LEMD\",\n country: \"ES\",\n ghcnh_id: null,\n icao: \"LEMD\",\n latitude: 40.4719,\n longitude: -3.5626,\n name: \"Madrid Barajas\",\n tz: \"Europe/Madrid\",\n },\n {\n code: \"LFPB\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPB\",\n latitude: 48.9694,\n longitude: 2.4414,\n name: \"Paris Le Bourget\",\n tz: \"Europe/Paris\",\n },\n {\n code: \"LFPG\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPG\",\n latitude: 49.0097,\n longitude: 2.5479,\n name: \"Paris Charles de Gaulle\",\n tz: \"Europe/Paris\",\n },\n {\n code: \"LFPO\",\n country: \"FR\",\n ghcnh_id: null,\n icao: \"LFPO\",\n latitude: 48.7233,\n longitude: 2.3794,\n name: \"Paris Orly\",\n tz: \"Europe/Paris\",\n },\n {\n code: \"LIMC\",\n country: \"IT\",\n ghcnh_id: null,\n icao: \"LIMC\",\n latitude: 45.6306,\n longitude: 8.7281,\n name: \"Milan Malpensa\",\n tz: \"Europe/Rome\",\n },\n {\n code: \"LIRF\",\n country: \"IT\",\n ghcnh_id: null,\n icao: \"LIRF\",\n latitude: 41.8003,\n longitude: 12.2389,\n name: \"Rome Fiumicino\",\n tz: \"Europe/Rome\",\n },\n {\n code: \"LOWW\",\n country: \"AT\",\n ghcnh_id: null,\n icao: \"LOWW\",\n latitude: 48.1103,\n longitude: 16.5697,\n name: \"Vienna International\",\n tz: \"Europe/Vienna\",\n },\n {\n code: \"LSZH\",\n country: \"CH\",\n ghcnh_id: null,\n icao: \"LSZH\",\n latitude: 47.4647,\n longitude: 8.5492,\n name: \"Zurich\",\n tz: \"Europe/Zurich\",\n },\n {\n code: \"NZAA\",\n country: \"NZ\",\n ghcnh_id: null,\n icao: \"NZAA\",\n latitude: -37.0081,\n longitude: 174.7917,\n name: \"Auckland\",\n tz: \"Pacific/Auckland\",\n },\n {\n code: \"NZWN\",\n country: \"NZ\",\n ghcnh_id: null,\n icao: \"NZWN\",\n latitude: -41.3272,\n longitude: 174.8053,\n name: \"Wellington\",\n tz: \"Pacific/Auckland\",\n },\n {\n code: \"OERK\",\n country: \"SA\",\n ghcnh_id: null,\n icao: \"OERK\",\n latitude: 24.9576,\n longitude: 46.6988,\n name: \"Riyadh King Khalid International\",\n tz: \"Asia/Riyadh\",\n },\n {\n code: \"OMDB\",\n country: \"AE\",\n ghcnh_id: null,\n icao: \"OMDB\",\n latitude: 25.2532,\n longitude: 55.3657,\n name: \"Dubai International\",\n tz: \"Asia/Dubai\",\n },\n {\n code: \"OTHH\",\n country: \"QA\",\n ghcnh_id: null,\n icao: \"OTHH\",\n latitude: 25.2731,\n longitude: 51.608,\n name: \"Doha Hamad International\",\n tz: \"Asia/Qatar\",\n },\n {\n code: \"RCTP\",\n country: \"TW\",\n ghcnh_id: null,\n icao: \"RCTP\",\n latitude: 25.0777,\n longitude: 121.2328,\n name: \"Taipei Taoyuan\",\n tz: \"Asia/Taipei\",\n },\n {\n code: \"RJAA\",\n country: \"JP\",\n ghcnh_id: null,\n icao: \"RJAA\",\n latitude: 35.7647,\n longitude: 140.3864,\n name: \"Tokyo Narita\",\n tz: \"Asia/Tokyo\",\n },\n {\n code: \"RJTT\",\n country: \"JP\",\n ghcnh_id: null,\n icao: \"RJTT\",\n latitude: 35.5522,\n longitude: 139.78,\n name: \"Tokyo Haneda\",\n tz: \"Asia/Tokyo\",\n },\n {\n code: \"RKSI\",\n country: \"KR\",\n ghcnh_id: null,\n icao: \"RKSI\",\n latitude: 37.4691,\n longitude: 126.4505,\n name: \"Seoul Incheon\",\n tz: \"Asia/Seoul\",\n },\n {\n code: \"SAEZ\",\n country: \"AR\",\n ghcnh_id: null,\n icao: \"SAEZ\",\n latitude: -34.8222,\n longitude: -58.5358,\n name: \"Buenos Aires Ezeiza\",\n tz: \"America/Argentina/Buenos_Aires\",\n },\n {\n code: \"SBGR\",\n country: \"BR\",\n ghcnh_id: null,\n icao: \"SBGR\",\n latitude: -23.4356,\n longitude: -46.4731,\n name: \"São Paulo Guarulhos\",\n tz: \"America/Sao_Paulo\",\n },\n {\n code: \"UUEE\",\n country: \"RU\",\n ghcnh_id: null,\n icao: \"UUEE\",\n latitude: 55.9728,\n longitude: 37.4147,\n name: \"Moscow Sheremetyevo\",\n tz: \"Europe/Moscow\",\n },\n {\n code: \"VABB\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VABB\",\n latitude: 19.0887,\n longitude: 72.8679,\n name: \"Mumbai Chhatrapati Shivaji\",\n tz: \"Asia/Kolkata\",\n },\n {\n code: \"VHHH\",\n country: \"HK\",\n ghcnh_id: null,\n icao: \"VHHH\",\n latitude: 22.308,\n longitude: 113.9185,\n name: \"Hong Kong International\",\n tz: \"Asia/Hong_Kong\",\n },\n {\n code: \"VIDP\",\n country: \"IN\",\n ghcnh_id: null,\n icao: \"VIDP\",\n latitude: 28.5562,\n longitude: 77.1,\n name: \"Delhi Indira Gandhi\",\n tz: \"Asia/Kolkata\",\n },\n {\n code: \"VTBS\",\n country: \"TH\",\n ghcnh_id: null,\n icao: \"VTBS\",\n latitude: 13.69,\n longitude: 100.7501,\n name: \"Bangkok Suvarnabhumi\",\n tz: \"Asia/Bangkok\",\n },\n {\n code: \"WSSS\",\n country: \"SG\",\n ghcnh_id: null,\n icao: \"WSSS\",\n latitude: 1.3644,\n longitude: 103.9915,\n name: \"Singapore Changi\",\n tz: \"Asia/Singapore\",\n },\n {\n code: \"YBBN\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YBBN\",\n latitude: -27.3842,\n longitude: 153.1175,\n name: \"Brisbane\",\n tz: \"Australia/Brisbane\",\n },\n {\n code: \"YMML\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YMML\",\n latitude: -37.6733,\n longitude: 144.8433,\n name: \"Melbourne Tullamarine\",\n tz: \"Australia/Melbourne\",\n },\n {\n code: \"YSSY\",\n country: \"AU\",\n ghcnh_id: null,\n icao: \"YSSY\",\n latitude: -33.9461,\n longitude: 151.1772,\n name: \"Sydney Kingsford Smith\",\n tz: \"Australia/Sydney\",\n },\n {\n code: \"ZBAA\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZBAA\",\n latitude: 40.0801,\n longitude: 116.5846,\n name: \"Beijing Capital\",\n tz: \"Asia/Shanghai\",\n },\n {\n code: \"ZSPD\",\n country: \"CN\",\n ghcnh_id: null,\n icao: \"ZSPD\",\n latitude: 31.1443,\n longitude: 121.8083,\n name: \"Shanghai Pudong\",\n tz: \"Asia/Shanghai\",\n },\n] as const;\n\nexport const STATION_BY_CODE: ReadonlyMap<string, StationInfo> = new Map<string, StationInfo>([\n [\"ATL\", STATIONS[10]!],\n [\"AUS\", STATIONS[11]!],\n [\"BOS\", STATIONS[12]!],\n [\"DCA\", STATIONS[13]!],\n [\"DEN\", STATIONS[14]!],\n [\"DFW\", STATIONS[15]!],\n [\"EDDB\", STATIONS[0]!],\n [\"EDDF\", STATIONS[1]!],\n [\"EDDM\", STATIONS[2]!],\n [\"EFHK\", STATIONS[3]!],\n [\"EGKK\", STATIONS[4]!],\n [\"EGLL\", STATIONS[5]!],\n [\"EHAM\", STATIONS[6]!],\n [\"EKCH\", STATIONS[7]!],\n [\"EPWA\", STATIONS[8]!],\n [\"ESSA\", STATIONS[9]!],\n [\"HOU\", STATIONS[16]!],\n [\"LAS\", STATIONS[17]!],\n [\"LAX\", STATIONS[18]!],\n [\"LEBL\", STATIONS[30]!],\n [\"LEMD\", STATIONS[31]!],\n [\"LFPB\", STATIONS[32]!],\n [\"LFPG\", STATIONS[33]!],\n [\"LFPO\", STATIONS[34]!],\n [\"LIMC\", STATIONS[35]!],\n [\"LIRF\", STATIONS[36]!],\n [\"LOWW\", STATIONS[37]!],\n [\"LSZH\", STATIONS[38]!],\n [\"MDW\", STATIONS[19]!],\n [\"MIA\", STATIONS[20]!],\n [\"MSP\", STATIONS[21]!],\n [\"MSY\", STATIONS[22]!],\n [\"NYC\", STATIONS[23]!],\n [\"NZAA\", STATIONS[39]!],\n [\"NZWN\", STATIONS[40]!],\n [\"OERK\", STATIONS[41]!],\n [\"OKC\", STATIONS[24]!],\n [\"OMDB\", STATIONS[42]!],\n [\"OTHH\", STATIONS[43]!],\n [\"PHL\", STATIONS[25]!],\n [\"PHX\", STATIONS[26]!],\n [\"RCTP\", STATIONS[44]!],\n [\"RJAA\", STATIONS[45]!],\n [\"RJTT\", STATIONS[46]!],\n [\"RKSI\", STATIONS[47]!],\n [\"SAEZ\", STATIONS[48]!],\n [\"SAT\", STATIONS[27]!],\n [\"SBGR\", STATIONS[49]!],\n [\"SEA\", STATIONS[28]!],\n [\"SFO\", STATIONS[29]!],\n [\"UUEE\", STATIONS[50]!],\n [\"VABB\", STATIONS[51]!],\n [\"VHHH\", STATIONS[52]!],\n [\"VIDP\", STATIONS[53]!],\n [\"VTBS\", STATIONS[54]!],\n [\"WSSS\", STATIONS[55]!],\n [\"YBBN\", STATIONS[56]!],\n [\"YMML\", STATIONS[57]!],\n [\"YSSY\", STATIONS[58]!],\n [\"ZBAA\", STATIONS[59]!],\n [\"ZSPD\", STATIONS[60]!],\n]);\n\nexport const STATION_BY_ICAO: ReadonlyMap<string, StationInfo> = new Map<string, StationInfo>([\n [\"EDDB\", STATIONS[0]!],\n [\"EDDF\", STATIONS[1]!],\n [\"EDDM\", STATIONS[2]!],\n [\"EFHK\", STATIONS[3]!],\n [\"EGKK\", STATIONS[4]!],\n [\"EGLL\", STATIONS[5]!],\n [\"EHAM\", STATIONS[6]!],\n [\"EKCH\", STATIONS[7]!],\n [\"EPWA\", STATIONS[8]!],\n [\"ESSA\", STATIONS[9]!],\n [\"KATL\", STATIONS[10]!],\n [\"KAUS\", STATIONS[11]!],\n [\"KBOS\", STATIONS[12]!],\n [\"KDCA\", STATIONS[13]!],\n [\"KDEN\", STATIONS[14]!],\n [\"KDFW\", STATIONS[15]!],\n [\"KHOU\", STATIONS[16]!],\n [\"KLAS\", STATIONS[17]!],\n [\"KLAX\", STATIONS[18]!],\n [\"KMDW\", STATIONS[19]!],\n [\"KMIA\", STATIONS[20]!],\n [\"KMSP\", STATIONS[21]!],\n [\"KMSY\", STATIONS[22]!],\n [\"KNYC\", STATIONS[23]!],\n [\"KOKC\", STATIONS[24]!],\n [\"KPHL\", STATIONS[25]!],\n [\"KPHX\", STATIONS[26]!],\n [\"KSAT\", STATIONS[27]!],\n [\"KSEA\", STATIONS[28]!],\n [\"KSFO\", STATIONS[29]!],\n [\"LEBL\", STATIONS[30]!],\n [\"LEMD\", STATIONS[31]!],\n [\"LFPB\", STATIONS[32]!],\n [\"LFPG\", STATIONS[33]!],\n [\"LFPO\", STATIONS[34]!],\n [\"LIMC\", STATIONS[35]!],\n [\"LIRF\", STATIONS[36]!],\n [\"LOWW\", STATIONS[37]!],\n [\"LSZH\", STATIONS[38]!],\n [\"NZAA\", STATIONS[39]!],\n [\"NZWN\", STATIONS[40]!],\n [\"OERK\", STATIONS[41]!],\n [\"OMDB\", STATIONS[42]!],\n [\"OTHH\", STATIONS[43]!],\n [\"RCTP\", STATIONS[44]!],\n [\"RJAA\", STATIONS[45]!],\n [\"RJTT\", STATIONS[46]!],\n [\"RKSI\", STATIONS[47]!],\n [\"SAEZ\", STATIONS[48]!],\n [\"SBGR\", STATIONS[49]!],\n [\"UUEE\", STATIONS[50]!],\n [\"VABB\", STATIONS[51]!],\n [\"VHHH\", STATIONS[52]!],\n [\"VIDP\", STATIONS[53]!],\n [\"VTBS\", STATIONS[54]!],\n [\"WSSS\", STATIONS[55]!],\n [\"YBBN\", STATIONS[56]!],\n [\"YMML\", STATIONS[57]!],\n [\"YSSY\", STATIONS[58]!],\n [\"ZBAA\", STATIONS[59]!],\n [\"ZSPD\", STATIONS[60]!],\n]);\n","// Snapshot math — settlement-window and market-close arithmetic.\n//\n// Ported from `packages/core/src/mostlyright/snapshot.py` and\n// `packages/core/src/mostlyright/_internal/_pairs.py:market_close_utc`.\n//\n// Key concepts:\n// - LOCAL STANDARD TIME (LST): station's standard UTC offset, DST ignored.\n// Kalshi NHIGH/NLOW contracts define the settlement window in LST.\n// - Settlement window: midnight-midnight LST for a given date.\n// During US daylight saving the clock window is 1:00 AM–1:00 AM next day\n// (EDT), but the UTC bounds are the same year-round.\n// - CLI publication delay: NWS issues the overnight final CLI ~04:00–10:00\n// UTC the day after observation. Default: 10 h after midnight LST.\n\n// ---------------------------------------------------------------------------\n// Station → IANA timezone database\n// ---------------------------------------------------------------------------\n//\n// Used to extract the LOCAL STANDARD TIME UTC offset via a January reference\n// moment. Ported from `mostlyright.snapshot._STATION_TZ`.\n\nexport const _STATION_TZ: Readonly<Record<string, string>> = Object.freeze({\n // Eastern (UTC-5 standard / UTC-4 DST)\n NYC: \"America/New_York\",\n JFK: \"America/New_York\",\n LGA: \"America/New_York\",\n EWR: \"America/New_York\",\n ATL: \"America/New_York\",\n BOS: \"America/New_York\",\n PHL: \"America/New_York\",\n DCA: \"America/New_York\",\n IAD: \"America/New_York\",\n BWI: \"America/New_York\",\n MIA: \"America/New_York\",\n MCO: \"America/New_York\",\n TPA: \"America/New_York\",\n CLT: \"America/New_York\",\n RDU: \"America/New_York\",\n CLE: \"America/New_York\",\n PIT: \"America/New_York\",\n BUF: \"America/New_York\",\n DTW: \"America/Detroit\",\n IND: \"America/Indiana/Indianapolis\",\n CVG: \"America/New_York\",\n CMH: \"America/New_York\",\n SYR: \"America/New_York\",\n ALB: \"America/New_York\",\n BTV: \"America/New_York\",\n ORF: \"America/New_York\",\n RIC: \"America/New_York\",\n GSO: \"America/New_York\",\n CHS: \"America/New_York\",\n SAV: \"America/New_York\",\n JAX: \"America/New_York\",\n RSW: \"America/New_York\",\n PBI: \"America/New_York\",\n FLL: \"America/New_York\",\n // Central (UTC-6 standard / UTC-5 DST)\n ORD: \"America/Chicago\",\n MDW: \"America/Chicago\",\n DFW: \"America/Chicago\",\n DAL: \"America/Chicago\",\n IAH: \"America/Chicago\",\n HOU: \"America/Chicago\",\n MSP: \"America/Chicago\",\n STL: \"America/Chicago\",\n MCI: \"America/Chicago\",\n OMA: \"America/Chicago\",\n MKE: \"America/Chicago\",\n MSY: \"America/Chicago\",\n MEM: \"America/Chicago\",\n BNA: \"America/Chicago\",\n OKC: \"America/Chicago\",\n SAT: \"America/Chicago\",\n AUS: \"America/Chicago\",\n DSM: \"America/Chicago\",\n TUL: \"America/Chicago\",\n LIT: \"America/Chicago\",\n BIR: \"America/Chicago\",\n SDF: \"America/Chicago\",\n HSV: \"America/Chicago\",\n BHM: \"America/Chicago\",\n MOB: \"America/Chicago\",\n BTR: \"America/Chicago\",\n SHV: \"America/Chicago\",\n // Mountain (UTC-7 standard / UTC-6 DST)\n DEN: \"America/Denver\",\n SLC: \"America/Denver\",\n ABQ: \"America/Denver\",\n BOI: \"America/Boise\",\n BZN: \"America/Denver\",\n GJT: \"America/Denver\",\n // Arizona: no DST (UTC-7 always)\n PHX: \"America/Phoenix\",\n TUS: \"America/Phoenix\",\n // Pacific (UTC-8 standard / UTC-7 DST)\n LAX: \"America/Los_Angeles\",\n SFO: \"America/Los_Angeles\",\n SEA: \"America/Los_Angeles\",\n PDX: \"America/Los_Angeles\",\n LAS: \"America/Los_Angeles\",\n SAN: \"America/Los_Angeles\",\n OAK: \"America/Los_Angeles\",\n SJC: \"America/Los_Angeles\",\n SMF: \"America/Los_Angeles\",\n RNO: \"America/Los_Angeles\",\n FAT: \"America/Los_Angeles\",\n SNA: \"America/Los_Angeles\",\n ONT: \"America/Los_Angeles\",\n BUR: \"America/Los_Angeles\",\n // Alaska (UTC-9 standard / UTC-8 DST)\n ANC: \"America/Anchorage\",\n FAI: \"America/Anchorage\",\n JNU: \"America/Juneau\",\n // Hawaii (UTC-10, no DST)\n HNL: \"Pacific/Honolulu\",\n OGG: \"Pacific/Honolulu\",\n KOA: \"Pacific/Honolulu\",\n // International (iter-6 H12): minimal set required to un-skip the\n // case-5 RJTT year-wrap cache behavior test. Python's\n // `mostlyright.snapshot._resolve_tz` falls back to the broader STATIONS\n // registry for intl ICAOs; the TS port hasn't ported that fallback\n // yet (tracked as TS-W6 — exhaustive intl-station tz coverage). This\n // entry closes H12 cleanly without pulling the whole STATIONS map in.\n // ICAO key (RJTT) — international stations have no 3-letter NWS code.\n // Tokyo Haneda — UTC+9 LST, no DST.\n RJTT: \"Asia/Tokyo\",\n});\n\n/** Reference UTC moment in January (no DST in Northern Hemisphere US). */\nexport const _JAN_REF = new Date(Date.UTC(2024, 0, 15, 12, 0, 0));\n\n/** NWS CLI typical publication delay: 10 h after midnight LST. */\nexport const _CLI_PUBLICATION_DELAY_HOURS = 10.0;\n\n/** Kalshi market typical close time (LST). */\nexport const _MARKET_CLOSE_HOUR_LST = 16;\nexport const _MARKET_CLOSE_MINUTE_LST = 30;\n\n// ---------------------------------------------------------------------------\n// LST offset extraction\n// ---------------------------------------------------------------------------\n\nconst _OFFSET_CACHE = new Map<string, number>();\n\n/**\n * Return the LOCAL STANDARD TIME UTC offset (in hours) for an IANA tz,\n * sampled from January 15 2024 12:00 UTC so the result is never affected\n * by DST in the Northern Hemisphere.\n *\n * Implementation: format `_JAN_REF` in the target tz via Intl.DateTimeFormat\n * and diff against the UTC formatted view to recover the offset.\n */\nexport function _lstOffsetHours(stationTz: string): number {\n const cached = _OFFSET_CACHE.get(stationTz);\n if (cached !== undefined) return cached;\n\n // We compute: localComponents(stationTz, _JAN_REF) − utcComponents(_JAN_REF).\n // The difference gives the tz offset in (hours). Negative for west of UTC.\n const fmt = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: stationTz,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n });\n const parts = fmt.formatToParts(_JAN_REF);\n const get = (type: string): number => {\n const part = parts.find((p) => p.type === type);\n if (!part) {\n throw new Error(`Intl.DateTimeFormat missing ${type} for tz=${stationTz}`);\n }\n return Number(part.value);\n };\n\n const year = get(\"year\");\n const month = get(\"month\");\n const day = get(\"day\");\n let hour = get(\"hour\");\n const minute = get(\"minute\");\n const second = get(\"second\");\n // Some locales return hour \"24\" instead of \"00\" for midnight; normalize.\n if (hour === 24) hour = 0;\n\n // Compute the timezone's wall-clock for _JAN_REF treated as UTC.\n const localAsUtc = Date.UTC(year, month - 1, day, hour, minute, second);\n const offsetMs = localAsUtc - _JAN_REF.getTime();\n const offsetHours = offsetMs / 3_600_000;\n _OFFSET_CACHE.set(stationTz, offsetHours);\n return offsetHours;\n}\n\n// ---------------------------------------------------------------------------\n// Station code normalization + tz lookup\n// ---------------------------------------------------------------------------\n\nfunction _stationCodeNormalized(station: string): string {\n const s = station.trim().toUpperCase();\n if (s.length === 4 && s.startsWith(\"K\")) {\n return s.substring(1);\n }\n return s;\n}\n\n/**\n * Resolve a station code (NWS 3-letter, ICAO 4-letter) to an IANA tz string.\n * Honors `tzOverride` first, then the built-in `_STATION_TZ` map.\n * Throws if no tz can be resolved.\n */\nexport function _resolveStationTz(station: string, tzOverride?: string): string {\n if (tzOverride) return tzOverride;\n const code = _stationCodeNormalized(station);\n const tz = _STATION_TZ[code];\n if (tz) return tz;\n throw new Error(\n `Unknown station timezone: ${JSON.stringify(code)}. Add it to _STATION_TZ or pass tzOverride=\"America/...\".`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// as_of parsing\n// ---------------------------------------------------------------------------\n\nfunction _parseAsOf(asOf: Date | string): Date {\n if (asOf instanceof Date) {\n if (Number.isNaN(asOf.getTime())) {\n throw new Error(\"Invalid Date passed as asOf\");\n }\n return asOf;\n }\n let s = asOf.trim();\n // Python: bare ISO without tz → assume UTC.\n if (s.endsWith(\"Z\")) {\n // Date.parse handles \"Z\" natively.\n } else if (!/[+-]\\d{2}:?\\d{2}$/.test(s)) {\n // No timezone suffix — treat as UTC.\n s = `${s}Z`;\n }\n const ms = Date.parse(s);\n if (!Number.isFinite(ms)) {\n throw new Error(`Invalid as_of string: ${JSON.stringify(asOf)}`);\n }\n return new Date(ms);\n}\n\n// ---------------------------------------------------------------------------\n// Public surface\n// ---------------------------------------------------------------------------\n\nfunction _pad2(n: number): string {\n return n < 10 ? `0${n}` : `${n}`;\n}\n\nfunction _isoDate(year: number, month: number, day: number): string {\n return `${year}-${_pad2(month)}-${_pad2(day)}`;\n}\n\n/**\n * Return the Kalshi settlement date (YYYY-MM-DD LST) for a UTC moment.\n *\n * Kalshi NHIGH/NLOW contracts cover midnight–midnight LOCAL STANDARD TIME.\n * DST is ignored: the window is always fixed to the standard UTC offset.\n */\nexport function settlementDateFor(\n asOf: Date | string,\n station: string,\n tzOverride?: string,\n): string {\n const utcDt = _parseAsOf(asOf);\n const tz = _resolveStationTz(station, tzOverride);\n const offsetHours = _lstOffsetHours(tz);\n // offsetHours is negative for US stations → lstMs < utcMs.\n const lstMs = utcDt.getTime() + offsetHours * 3_600_000;\n const lst = new Date(lstMs);\n // Use getUTC* because we already shifted the epoch by the LST offset.\n return _isoDate(lst.getUTCFullYear(), lst.getUTCMonth() + 1, lst.getUTCDate());\n}\n\n/**\n * Return UTC start/end of the Kalshi settlement window for a date.\n * The window is midnight-midnight LST, expressed in UTC.\n */\nexport function settlementWindowUtc(\n dateStr: string,\n station: string,\n tzOverride?: string,\n): [Date, Date] {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(dateStr);\n if (!match) {\n throw new Error(`Invalid ISO date for settlement window: ${JSON.stringify(dateStr)}`);\n }\n const [, yStr, mStr, dStr] = match;\n const year = Number(yStr);\n const month = Number(mStr);\n const day = Number(dStr);\n const tz = _resolveStationTz(station, tzOverride);\n const offsetHours = _lstOffsetHours(tz);\n\n // midnight LST = 00:00 LST = (00:00 UTC) − offset (offset is negative)\n // Example: UTC-5 → midnight LST = 05:00 UTC.\n const midnightLstAsUtcMs = Date.UTC(year, month - 1, day, 0, 0, 0);\n const startMs = midnightLstAsUtcMs - offsetHours * 3_600_000;\n const start = new Date(startMs);\n const end = new Date(startMs + 24 * 3_600_000);\n return [start, end];\n}\n\n/**\n * Return the UTC time at which the NWS CLI for a date is expected to be\n * available. Default delay is 10 h after midnight LST on the next day.\n */\nexport function cliAvailableAt(\n dateStr: string,\n station: string,\n delayHours: number = _CLI_PUBLICATION_DELAY_HOURS,\n tzOverride?: string,\n): Date {\n const [, windowEnd] = settlementWindowUtc(dateStr, station, tzOverride);\n return new Date(windowEnd.getTime() + delayHours * 3_600_000);\n}\n\n/**\n * Return the UTC time of the Kalshi market close for a settlement date.\n * Kalshi NHIGH/NLOW markets close at 4:30 PM LST on the day of settlement.\n */\nexport function marketCloseUtc(dateStr: string, station: string, tzOverride?: string): Date {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(dateStr);\n if (!match) {\n throw new Error(`Invalid ISO date for market close: ${JSON.stringify(dateStr)}`);\n }\n const [, yStr, mStr, dStr] = match;\n const year = Number(yStr);\n const month = Number(mStr);\n const day = Number(dStr);\n const tz = _resolveStationTz(station, tzOverride);\n const offsetHours = _lstOffsetHours(tz);\n\n const marketCloseAsUtcMs = Date.UTC(\n year,\n month - 1,\n day,\n _MARKET_CLOSE_HOUR_LST,\n _MARKET_CLOSE_MINUTE_LST,\n 0,\n );\n return new Date(marketCloseAsUtcMs - offsetHours * 3_600_000);\n}\n","// Cache-skip rule predicates — pure functions over inputs.\n//\n// Mirrors `packages/weather/src/mostlyright/weather/cache.py`:\n// - `_is_current_lst_month` / `_is_current_lst_year`\n// - `_is_live_source`\n//\n// Plus one TS-NEW addition required by TS-CACHE-02:\n// - `isWithinVolatileWindow` (30-day volatile-window check for archive\n// endpoints). Python's `cache.py` predates this rule; back-porting to\n// Python is tracked as a CROSS-SDK-SYNC parity ticket.\n//\n// All functions accept an optional `now: Date` test seam — production\n// callers pass `new Date()` once at the call site (plan 06).\n\nimport { STATION_BY_CODE, STATION_BY_ICAO } from \"../../data/generated/stations.js\";\nimport { _lstOffsetHours } from \"../../snapshot.js\";\n\n/** Resolve a station identifier (3-letter code OR 4-letter ICAO) to LST offset hours. */\nfunction _lstOffsetHoursFor(station: string): number {\n const upper = station.trim().toUpperCase();\n const byCode = STATION_BY_CODE.get(upper);\n if (byCode !== undefined) return _lstOffsetHours(byCode.tz);\n const byIcao = STATION_BY_ICAO.get(upper);\n if (byIcao !== undefined) return _lstOffsetHours(byIcao.tz);\n if (upper.length === 4 && upper.startsWith(\"K\")) {\n const stripped = upper.slice(1);\n const retry = STATION_BY_CODE.get(stripped);\n if (retry !== undefined) return _lstOffsetHours(retry.tz);\n }\n throw new RangeError(`unknown station: ${JSON.stringify(station)}`);\n}\n\n/**\n * Compute the station's current LST wall-clock as a UTC Date offset by the\n * LST hour shift. Use `getUTC*` to read fields (we already shifted the epoch).\n */\nfunction _nowLst(station: string, now: Date = new Date()): Date {\n const offsetHours = _lstOffsetHoursFor(station);\n return new Date(now.getTime() + offsetHours * 3_600_000);\n}\n\n/**\n * True iff `(year, month)` is the current LST month for `station`.\n *\n * Mirrors Python `_is_current_lst_month`. The current month is mutable\n * (observations still arriving) — caching it would serve stale data.\n */\nexport function shouldSkipCacheForCurrentLstMonth(\n station: string,\n year: number,\n month: number,\n now?: Date,\n): boolean {\n const lst = _nowLst(station, now);\n return lst.getUTCFullYear() === year && lst.getUTCMonth() + 1 === month;\n}\n\n/**\n * True iff `year` is the current LST year for `station`. Annual analog of\n * the monthly variant — gates the climate cache.\n */\nexport function shouldSkipCacheForCurrentLstYear(\n station: string,\n year: number,\n now?: Date,\n): boolean {\n const lst = _nowLst(station, now);\n return lst.getUTCFullYear() === year;\n}\n\n/**\n * True iff `(year, month)` is a **strictly past** UTC month relative to\n * `now` — i.e. cacheable on the strictest possible temporal axis.\n *\n * iter-12 C14: `shouldSkipCacheForCurrentLstMonth` and `isMonthVolatile`\n * (lives in `meta/src/research.ts`) only catch the *current* LST month\n * and the immediate post-month volatile tail. Both predicates return\n * false for months that lie in the FUTURE relative to `now`, or for the\n * current UTC month when the station's LST is still in the prior UTC\n * month (negative tz offsets near UTC midnight). An empty / partial\n * fetch for such a month would be persisted and later served as\n * \"complete.\" `isWritableMonth` is a stricter additional gate: it\n * requires the (year, month) to be lexicographically less than the\n * UTC current month, so neither future months nor the partial current\n * UTC month are ever cacheable — regardless of any station's LST.\n *\n * Mirrors Python `cache.py:_is_current_lst_month`'s implicit invariant\n * (Python paths use parquet-on-disk which can't be written for future\n * dates because the cache root never spawns those years). TS callers\n * MUST gate cache reads AND writes on this predicate before applying\n * the LST / volatile-window gates.\n */\nexport function isWritableMonth(year: number, month: number, now: Date): boolean {\n const nowYear = now.getUTCFullYear();\n const nowMonth = now.getUTCMonth() + 1; // 1-12\n if (year < nowYear) return true;\n if (year > nowYear) return false;\n return month < nowMonth;\n}\n\n/**\n * True iff `year` is a **strictly past** UTC year relative to `now` —\n * the annual analog of `isWritableMonth`.\n *\n * iter-12 C15: `shouldSkipCacheForCurrentLstYear` only catches the\n * current LST year. It misses (a) future years, which would silently\n * cache empty/incomplete data, and (b) the UTC Jan-1 boundary window\n * where the station's LST is still in the prior calendar year (negative\n * tz offsets) but the UTC year has already rolled over — without this\n * gate the new UTC year, which is mutable, could be written. Stricter\n * additional gate: require `year < now.getUTCFullYear()`. TS callers\n * MUST gate cache reads AND writes on this predicate before applying\n * the LST / volatile-window gates.\n */\nexport function isWritableYear(year: number, now: Date): boolean {\n return year < now.getUTCFullYear();\n}\n\n/**\n * True iff `source` ends with `.live`.\n *\n * Mirrors Python `_is_live_source` byte-equivalently — accepts null /\n * undefined / empty (returns false in all three cases).\n */\nexport function isLiveSource(source: string | null | undefined): boolean {\n return typeof source === \"string\" && source.length > 0 && source.endsWith(\".live\");\n}\n\n/**\n * **TS-NEW** addition per TS-CACHE-02: archive endpoints within `days` days\n * of `archiveAsOf` are treated as volatile (some sources amend their\n * published data for ~30 days post-event). NOT a Python port today — file\n * a CROSS-SDK-SYNC parity ticket if Python adopts it.\n *\n * Returns true iff `eventDate` falls within `[archiveAsOf - days, archiveAsOf]`\n * (inclusive at both endpoints — an event exactly `days` days before\n * `archiveAsOf` is still volatile and MUST be re-fetched).\n *\n * Events AFTER `archiveAsOf` are never volatile by this rule (deltaDays < 0).\n */\nexport function isWithinVolatileWindow(eventDate: string, archiveAsOf: string, days = 30): boolean {\n const e = Date.parse(`${eventDate}T00:00:00Z`);\n const a = Date.parse(`${archiveAsOf}T00:00:00Z`);\n if (!Number.isFinite(e) || !Number.isFinite(a)) {\n throw new RangeError(\n `invalid YYYY-MM-DD: eventDate=${JSON.stringify(eventDate)} archiveAsOf=${JSON.stringify(archiveAsOf)}`,\n );\n }\n const deltaDays = (a - e) / 86_400_000;\n return deltaDays >= 0 && deltaDays <= days;\n}\n","// Cache-key generators — pure functions producing the canonical key strings\n// `cacheKeyForObservations(station, year, month)` and\n// `cacheKeyForClimate(station, year)`. Matches the Python file-path zero-\n// padded month/year scheme (Python: `01.parquet`, TS: `:01`).\n//\n// Station is upper-cased but NOT validated here (validation is the\n// orchestrator's job; this module stays pure).\n//\n// iter-7 H13 / H14: an optional `source` segment was added to\n// `cacheKeyForObservations` so the multi-source observations cache\n// (IEM ASOS + GHCNh) does not collide on the same `(station, year, month)`\n// triplet. Python writes one parquet per month containing the merged\n// observations from all sources; the TS orchestrator caches per-source\n// chunks pre-merge (because the fetchers are independent paths) and\n// disambiguates with the source segment. Omitting `source` preserves the\n// legacy 3-arg key shape — useful for tests that don't care about source\n// (sentinel preloads, fixture replays) and matches the canonical\n// Python-parity contract for callers that have already pre-merged sources.\n\nconst MIN_YEAR = 1900;\nconst MAX_YEAR = 2100;\nconst SOURCE_RE = /^[a-z0-9_-]+$/;\n\n/**\n * Build the canonical observations cache key.\n *\n * Examples:\n * `cacheKeyForObservations(\"KNYC\", 2025, 1)` →\n * `\"mostlyright:v1:observations:KNYC:2025:01\"`.\n * `cacheKeyForObservations(\"KNYC\", 2025, 1, \"iem\")` →\n * `\"mostlyright:v1:observations:KNYC:2025:01:iem\"`.\n *\n * The `source` segment (optional, lowercase alphanumeric / hyphen /\n * underscore) namespaces per-source pre-merge chunks so IEM ASOS and\n * GHCNh writes for the same `(station, year, month)` do not collide.\n * Omit for back-compat (sentinel preloads, fixture replays).\n */\nexport function cacheKeyForObservations(\n station: string,\n year: number,\n month: number,\n source?: string,\n): string {\n if (!Number.isInteger(year) || year < MIN_YEAR || year > MAX_YEAR) {\n throw new RangeError(`year out of range: ${year}`);\n }\n if (!Number.isInteger(month) || month < 1 || month > 12) {\n throw new RangeError(`month out of range: ${month}`);\n }\n const yyyy = String(year).padStart(4, \"0\");\n const mm = String(month).padStart(2, \"0\");\n const base = `mostlyright:v1:observations:${station.toUpperCase()}:${yyyy}:${mm}`;\n if (source === undefined) return base;\n if (typeof source !== \"string\" || !SOURCE_RE.test(source)) {\n throw new RangeError(\n `source must match ${SOURCE_RE.source} (lowercase alnum / hyphen / underscore); got ${JSON.stringify(source)}`,\n );\n }\n return `${base}:${source}`;\n}\n\n/**\n * Build the canonical climate cache key (annual).\n *\n * Example: `cacheKeyForClimate(\"KNYC\", 2025)` →\n * `\"mostlyright:v1:climate:KNYC:2025\"`.\n */\nexport function cacheKeyForClimate(station: string, year: number): string {\n if (!Number.isInteger(year) || year < MIN_YEAR || year > MAX_YEAR) {\n throw new RangeError(`year out of range: ${year}`);\n }\n const yyyy = String(year).padStart(4, \"0\");\n return `mostlyright:v1:climate:${station.toUpperCase()}:${yyyy}`;\n}\n"],"mappings":"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AAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,OAAO,SAAS,EAAE,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AACxB,CAAC;AAEM,IAAM,kBAAoD,oBAAI,IAAyB;AAAA,EAC5F,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,CAAC,CAAE;AAAA,EACrB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EAAE,CAAE;AAAA,EACtB,CAAC,QAAQ,SAAS,EA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","names":[]}