hron-ts 0.5.0 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/ast.ts","../src/error.ts","../src/cron.ts","../src/display.ts","../src/eval.ts","../src/lexer.ts","../src/parser.ts"],"sourcesContent":["// hron-js — Public API\n\nimport type { Temporal } from \"@js-temporal/polyfill\";\nimport type { ScheduleData, ScheduleExpr } from \"./ast.js\";\nimport { fromCron, toCron } from \"./cron.js\";\nimport { display } from \"./display.js\";\nimport { matches, nextFrom, nextNFrom } from \"./eval.js\";\nimport { parse } from \"./parser.js\";\n\nexport class Schedule {\n private data: ScheduleData;\n\n private constructor(data: ScheduleData) {\n this.data = data;\n }\n\n /** Parse an hron expression string. */\n static parse(input: string): Schedule {\n return new Schedule(parse(input));\n }\n\n /** Convert a 5-field cron expression to a Schedule. */\n static fromCron(cronExpr: string): Schedule {\n return new Schedule(fromCron(cronExpr));\n }\n\n /** Check if an input string is a valid hron expression. */\n static validate(input: string): boolean {\n try {\n parse(input);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Compute the next occurrence after `now`. */\n nextFrom(now: Temporal.ZonedDateTime): Temporal.ZonedDateTime | null {\n return nextFrom(this.data, now);\n }\n\n /** Compute the next `n` occurrences after `now`. */\n nextNFrom(now: Temporal.ZonedDateTime, n: number): Temporal.ZonedDateTime[] {\n return nextNFrom(this.data, now, n);\n }\n\n /** Check if a datetime matches this schedule. */\n matches(datetime: Temporal.ZonedDateTime): boolean {\n return matches(this.data, datetime);\n }\n\n /** Convert this schedule to a 5-field cron expression. */\n toCron(): string {\n return toCron(this.data);\n }\n\n /** Render as canonical string (roundtrip-safe). */\n toString(): string {\n return display(this.data);\n }\n\n /** Get the timezone, if specified. */\n get timezone(): string | null {\n return this.data.timezone;\n }\n\n /** Get the underlying schedule expression. */\n get expression(): ScheduleExpr {\n return this.data.expr;\n }\n}\n\nexport { Temporal } from \"@js-temporal/polyfill\";\nexport type {\n DateSpec,\n DayFilter,\n DayOfMonthSpec,\n Exception,\n IntervalUnit,\n MonthName,\n MonthTarget,\n OrdinalPosition,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n UntilSpec,\n Weekday,\n YearTarget,\n} from \"./ast.js\";\nexport type { HronErrorKind, Span } from \"./error.js\";\n// Re-exports\nexport { HronError } from \"./error.js\";\n","// AST types for hron — TypeScript discriminated unions mirroring Rust enums.\n\nexport type Weekday =\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\"\n | \"sunday\";\n\nexport type MonthName =\n | \"jan\"\n | \"feb\"\n | \"mar\"\n | \"apr\"\n | \"may\"\n | \"jun\"\n | \"jul\"\n | \"aug\"\n | \"sep\"\n | \"oct\"\n | \"nov\"\n | \"dec\";\n\nexport type IntervalUnit = \"min\" | \"hours\";\n\nexport type OrdinalPosition =\n | \"first\"\n | \"second\"\n | \"third\"\n | \"fourth\"\n | \"fifth\"\n | \"last\";\n\nexport interface TimeOfDay {\n hour: number;\n minute: number;\n}\n\n// --- Day filter ---\n\nexport type DayFilter =\n | { type: \"every\" }\n | { type: \"weekday\" }\n | { type: \"weekend\" }\n | { type: \"days\"; days: Weekday[] };\n\n// --- Day of month spec ---\n\nexport type DayOfMonthSpec =\n | { type: \"single\"; day: number }\n | { type: \"range\"; start: number; end: number };\n\n// --- Month target ---\n\nexport type MonthTarget =\n | { type: \"days\"; specs: DayOfMonthSpec[] }\n | { type: \"lastDay\" }\n | { type: \"lastWeekday\" };\n\n// --- Year target ---\n\nexport type YearTarget =\n | { type: \"date\"; month: MonthName; day: number }\n | {\n type: \"ordinalWeekday\";\n ordinal: OrdinalPosition;\n weekday: Weekday;\n month: MonthName;\n }\n | { type: \"dayOfMonth\"; day: number; month: MonthName }\n | { type: \"lastWeekday\"; month: MonthName };\n\n// --- Date spec ---\n\nexport type DateSpec =\n | { type: \"named\"; month: MonthName; day: number }\n | { type: \"iso\"; date: string };\n\n// --- Exception ---\n\nexport type Exception =\n | { type: \"named\"; month: MonthName; day: number }\n | { type: \"iso\"; date: string };\n\n// --- Until spec ---\n\nexport type UntilSpec =\n | { type: \"iso\"; date: string }\n | { type: \"named\"; month: MonthName; day: number };\n\n// --- Schedule expression ---\n\nexport type ScheduleExpr =\n | {\n type: \"intervalRepeat\";\n interval: number;\n unit: IntervalUnit;\n from: TimeOfDay;\n to: TimeOfDay;\n dayFilter: DayFilter | null;\n }\n | { type: \"dayRepeat\"; interval: number; days: DayFilter; times: TimeOfDay[] }\n | {\n type: \"weekRepeat\";\n interval: number;\n days: Weekday[];\n times: TimeOfDay[];\n }\n | {\n type: \"monthRepeat\";\n interval: number;\n target: MonthTarget;\n times: TimeOfDay[];\n }\n | {\n type: \"ordinalRepeat\";\n interval: number;\n ordinal: OrdinalPosition;\n day: Weekday;\n times: TimeOfDay[];\n }\n | { type: \"singleDate\"; date: DateSpec; times: TimeOfDay[] }\n | {\n type: \"yearRepeat\";\n interval: number;\n target: YearTarget;\n times: TimeOfDay[];\n };\n\n// --- Schedule (top-level) ---\n\nexport interface ScheduleData {\n expr: ScheduleExpr;\n timezone: string | null;\n except: Exception[];\n until: UntilSpec | null;\n anchor: string | null; // ISO date string (YYYY-MM-DD)\n during: MonthName[];\n}\n\n// --- Helper functions ---\n\n/** ISO 8601 day number: Monday=1, Sunday=7. */\nexport function weekdayNumber(day: Weekday): number {\n const map: Record<Weekday, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n };\n return map[day];\n}\n\n/** Cron DOW number: Sunday=0, Monday=1, ..., Saturday=6. */\nexport function cronDowNumber(day: Weekday): number {\n const map: Record<Weekday, number> = {\n sunday: 0,\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n };\n return map[day];\n}\n\nexport function weekdayFromNumber(n: number): Weekday | null {\n const map: Record<number, Weekday> = {\n 1: \"monday\",\n 2: \"tuesday\",\n 3: \"wednesday\",\n 4: \"thursday\",\n 5: \"friday\",\n 6: \"saturday\",\n 7: \"sunday\",\n };\n return map[n] ?? null;\n}\n\nexport function monthNumber(month: MonthName): number {\n const map: Record<MonthName, number> = {\n jan: 1,\n feb: 2,\n mar: 3,\n apr: 4,\n may: 5,\n jun: 6,\n jul: 7,\n aug: 8,\n sep: 9,\n oct: 10,\n nov: 11,\n dec: 12,\n };\n return map[month];\n}\n\nexport function parseWeekday(s: string): Weekday | null {\n const map: Record<string, Weekday> = {\n monday: \"monday\",\n mon: \"monday\",\n tuesday: \"tuesday\",\n tue: \"tuesday\",\n wednesday: \"wednesday\",\n wed: \"wednesday\",\n thursday: \"thursday\",\n thu: \"thursday\",\n friday: \"friday\",\n fri: \"friday\",\n saturday: \"saturday\",\n sat: \"saturday\",\n sunday: \"sunday\",\n sun: \"sunday\",\n };\n return map[s.toLowerCase()] ?? null;\n}\n\nexport function parseMonthName(s: string): MonthName | null {\n const map: Record<string, MonthName> = {\n january: \"jan\",\n jan: \"jan\",\n february: \"feb\",\n feb: \"feb\",\n march: \"mar\",\n mar: \"mar\",\n april: \"apr\",\n apr: \"apr\",\n may: \"may\",\n june: \"jun\",\n jun: \"jun\",\n july: \"jul\",\n jul: \"jul\",\n august: \"aug\",\n aug: \"aug\",\n september: \"sep\",\n sep: \"sep\",\n october: \"oct\",\n oct: \"oct\",\n november: \"nov\",\n nov: \"nov\",\n december: \"dec\",\n dec: \"dec\",\n };\n return map[s.toLowerCase()] ?? null;\n}\n\nexport function expandDaySpec(spec: DayOfMonthSpec): number[] {\n if (spec.type === \"single\") {\n return [spec.day];\n }\n const result: number[] = [];\n for (let d = spec.start; d <= spec.end; d++) {\n result.push(d);\n }\n return result;\n}\n\nexport function expandMonthTarget(target: MonthTarget): number[] {\n if (target.type === \"days\") {\n return target.specs.flatMap(expandDaySpec);\n }\n return [];\n}\n\nexport function ordinalToN(ord: OrdinalPosition): number {\n const map: Record<string, number> = {\n first: 1,\n second: 2,\n third: 3,\n fourth: 4,\n fifth: 5,\n };\n return map[ord];\n}\n\nexport const ALL_WEEKDAYS: Weekday[] = [\n \"monday\",\n \"tuesday\",\n \"wednesday\",\n \"thursday\",\n \"friday\",\n];\n\nexport const ALL_WEEKEND: Weekday[] = [\"saturday\", \"sunday\"];\n\nexport function newScheduleData(expr: ScheduleExpr): ScheduleData {\n return {\n expr,\n timezone: null,\n except: [],\n until: null,\n anchor: null,\n during: [],\n };\n}\n","/** Byte range within the input string. */\nexport interface Span {\n start: number;\n end: number;\n}\n\nexport type HronErrorKind = \"lex\" | \"parse\" | \"eval\" | \"cron\";\n\n/** All errors produced by hron. */\nexport class HronError extends Error {\n readonly kind: HronErrorKind;\n readonly span?: Span;\n readonly input?: string;\n readonly suggestion?: string;\n\n constructor(\n kind: HronErrorKind,\n message: string,\n span?: Span,\n input?: string,\n suggestion?: string,\n ) {\n super(message);\n this.name = \"HronError\";\n this.kind = kind;\n this.span = span;\n this.input = input;\n this.suggestion = suggestion;\n }\n\n static lex(message: string, span: Span, input: string): HronError {\n return new HronError(\"lex\", message, span, input);\n }\n\n static parse(\n message: string,\n span: Span,\n input: string,\n suggestion?: string,\n ): HronError {\n return new HronError(\"parse\", message, span, input, suggestion);\n }\n\n static eval(message: string): HronError {\n return new HronError(\"eval\", message);\n }\n\n static cron(message: string): HronError {\n return new HronError(\"cron\", message);\n }\n\n displayRich(): string {\n if (\n (this.kind === \"lex\" || this.kind === \"parse\") &&\n this.span &&\n this.input\n ) {\n let out = `error: ${this.message}\\n`;\n out += ` ${this.input}\\n`;\n const padding = \" \".repeat(this.span.start + 2);\n const underline = \"^\".repeat(\n Math.max(this.span.end - this.span.start, 1),\n );\n out += padding + underline;\n if (this.suggestion) {\n out += ` try: \"${this.suggestion}\"`;\n }\n return out;\n }\n return `error: ${this.message}`;\n }\n}\n","// Cron conversion — to_cron / from_cron for hron schedules.\n\nimport type {\n DayFilter,\n DayOfMonthSpec,\n ScheduleData,\n ScheduleExpr,\n Weekday,\n} from \"./ast.js\";\nimport { cronDowNumber, newScheduleData } from \"./ast.js\";\nimport { HronError } from \"./error.js\";\n\n/** Convert a Schedule to a 5-field cron expression. */\nexport function toCron(schedule: ScheduleData): string {\n if (schedule.except.length > 0) {\n throw HronError.cron(\n \"not expressible as cron (except clauses not supported)\",\n );\n }\n if (schedule.until) {\n throw HronError.cron(\n \"not expressible as cron (until clauses not supported)\",\n );\n }\n if (schedule.during.length > 0) {\n throw HronError.cron(\n \"not expressible as cron (during clauses not supported)\",\n );\n }\n\n const expr = schedule.expr;\n\n switch (expr.type) {\n case \"dayRepeat\": {\n if (expr.interval > 1) {\n throw HronError.cron(\n \"not expressible as cron (multi-day intervals not supported)\",\n );\n }\n if (expr.times.length !== 1) {\n throw HronError.cron(\n \"not expressible as cron (multiple times not supported)\",\n );\n }\n const time = expr.times[0];\n const dow = dayFilterToCronDow(expr.days);\n return `${time.minute} ${time.hour} * * ${dow}`;\n }\n\n case \"intervalRepeat\": {\n const fullDay =\n expr.from.hour === 0 &&\n expr.from.minute === 0 &&\n expr.to.hour === 23 &&\n expr.to.minute === 59;\n if (!fullDay) {\n throw HronError.cron(\n \"not expressible as cron (partial-day interval windows not supported)\",\n );\n }\n if (expr.dayFilter) {\n throw HronError.cron(\n \"not expressible as cron (interval with day filter not supported)\",\n );\n }\n\n if (expr.unit === \"min\") {\n if (60 % expr.interval !== 0) {\n throw HronError.cron(\n `not expressible as cron (*/${expr.interval} breaks at hour boundaries)`,\n );\n }\n return `*/${expr.interval} * * * *`;\n }\n // hours\n return `0 */${expr.interval} * * *`;\n }\n\n case \"weekRepeat\":\n throw HronError.cron(\n \"not expressible as cron (multi-week intervals not supported)\",\n );\n\n case \"monthRepeat\": {\n if (expr.interval > 1) {\n throw HronError.cron(\n \"not expressible as cron (multi-month intervals not supported)\",\n );\n }\n if (expr.times.length !== 1) {\n throw HronError.cron(\n \"not expressible as cron (multiple times not supported)\",\n );\n }\n const time = expr.times[0];\n const { target } = expr;\n if (target.type === \"days\") {\n const expanded = target.specs.flatMap((s) => {\n if (s.type === \"single\") return [s.day];\n const r: number[] = [];\n for (let d = s.start; d <= s.end; d++) r.push(d);\n return r;\n });\n const dom = expanded.join(\",\");\n return `${time.minute} ${time.hour} ${dom} * *`;\n }\n if (target.type === \"lastDay\") {\n throw HronError.cron(\n \"not expressible as cron (last day of month not supported)\",\n );\n }\n throw HronError.cron(\n \"not expressible as cron (last weekday of month not supported)\",\n );\n }\n\n case \"ordinalRepeat\":\n throw HronError.cron(\n \"not expressible as cron (ordinal weekday of month not supported)\",\n );\n\n case \"singleDate\":\n throw HronError.cron(\n \"not expressible as cron (single dates are not repeating)\",\n );\n\n case \"yearRepeat\":\n throw HronError.cron(\n \"not expressible as cron (yearly schedules not supported in 5-field cron)\",\n );\n }\n}\n\nfunction dayFilterToCronDow(filter: DayFilter): string {\n switch (filter.type) {\n case \"every\":\n return \"*\";\n case \"weekday\":\n return \"1-5\";\n case \"weekend\":\n return \"0,6\";\n case \"days\": {\n const nums = filter.days.map((d) => cronDowNumber(d));\n nums.sort((a, b) => a - b);\n return nums.join(\",\");\n }\n }\n}\n\n/** Parse a 5-field cron expression into a ScheduleData. */\nexport function fromCron(cron: string): ScheduleData {\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== 5) {\n throw HronError.cron(`expected 5 cron fields, got ${fields.length}`);\n }\n\n const [minuteField, hourField, domField, _monthField, dowField] = fields;\n\n // Minute interval: */N\n if (minuteField.startsWith(\"*/\")) {\n const interval = parseInt(minuteField.slice(2), 10);\n if (Number.isNaN(interval)) throw HronError.cron(\"invalid minute interval\");\n\n let fromHour = 0;\n let toHour = 23;\n\n if (hourField === \"*\") {\n // full day\n } else if (hourField.includes(\"-\")) {\n const [start, end] = hourField.split(\"-\");\n fromHour = parseInt(start, 10);\n toHour = parseInt(end, 10);\n if (Number.isNaN(fromHour) || Number.isNaN(toHour))\n throw HronError.cron(\"invalid hour range\");\n } else {\n const h = parseInt(hourField, 10);\n if (Number.isNaN(h)) throw HronError.cron(\"invalid hour\");\n fromHour = h;\n toHour = h;\n }\n\n const dayFilter = dowField === \"*\" ? null : parseCronDow(dowField);\n\n if (domField === \"*\") {\n const expr: ScheduleExpr = {\n type: \"intervalRepeat\",\n interval,\n unit: \"min\",\n from: { hour: fromHour, minute: 0 },\n to: { hour: toHour, minute: toHour === 23 ? 59 : 0 },\n dayFilter,\n };\n return newScheduleData(expr);\n }\n }\n\n // Hour interval: 0 */N\n if (hourField.startsWith(\"*/\") && minuteField === \"0\") {\n const interval = parseInt(hourField.slice(2), 10);\n if (Number.isNaN(interval)) throw HronError.cron(\"invalid hour interval\");\n if (domField === \"*\" && dowField === \"*\") {\n const expr: ScheduleExpr = {\n type: \"intervalRepeat\",\n interval,\n unit: \"hours\",\n from: { hour: 0, minute: 0 },\n to: { hour: 23, minute: 59 },\n dayFilter: null,\n };\n return newScheduleData(expr);\n }\n }\n\n // Standard time-based cron\n const minute = parseInt(minuteField, 10);\n if (Number.isNaN(minute))\n throw HronError.cron(`invalid minute field: ${minuteField}`);\n const hour = parseInt(hourField, 10);\n if (Number.isNaN(hour))\n throw HronError.cron(`invalid hour field: ${hourField}`);\n const time = { hour, minute };\n\n // DOM-based (monthly)\n if (domField !== \"*\" && dowField === \"*\") {\n if (domField.includes(\"-\")) {\n throw HronError.cron(`DOM ranges not supported: ${domField}`);\n }\n const dayNums = domField.split(\",\").map((s) => {\n const n = parseInt(s, 10);\n if (Number.isNaN(n))\n throw HronError.cron(`invalid DOM field: ${domField}`);\n return n;\n });\n const specs: DayOfMonthSpec[] = dayNums.map((d) => ({\n type: \"single\" as const,\n day: d,\n }));\n const expr: ScheduleExpr = {\n type: \"monthRepeat\",\n interval: 1,\n target: { type: \"days\", specs },\n times: [time],\n };\n return newScheduleData(expr);\n }\n\n // DOW-based (day repeat)\n const days = parseCronDow(dowField);\n const expr: ScheduleExpr = {\n type: \"dayRepeat\",\n interval: 1,\n days,\n times: [time],\n };\n return newScheduleData(expr);\n}\n\nfunction parseCronDow(field: string): DayFilter {\n if (field === \"*\") return { type: \"every\" };\n if (field === \"1-5\") return { type: \"weekday\" };\n if (field === \"0,6\" || field === \"6,0\") return { type: \"weekend\" };\n\n if (field.includes(\"-\")) {\n throw HronError.cron(`DOW ranges not supported: ${field}`);\n }\n\n const nums = field.split(\",\").map((s) => {\n const n = parseInt(s, 10);\n if (Number.isNaN(n)) throw HronError.cron(`invalid DOW field: ${field}`);\n return n;\n });\n\n const days: Weekday[] = nums.map((n) => cronDowToWeekday(n));\n return { type: \"days\", days };\n}\n\nfunction cronDowToWeekday(n: number): Weekday {\n const map: Record<number, Weekday> = {\n 0: \"sunday\",\n 1: \"monday\",\n 2: \"tuesday\",\n 3: \"wednesday\",\n 4: \"thursday\",\n 5: \"friday\",\n 6: \"saturday\",\n 7: \"sunday\",\n };\n const result = map[n];\n if (!result) throw HronError.cron(`invalid DOW number: ${n}`);\n return result;\n}\n","// Display (toString) for hron schedules — produces canonical form for roundtrip.\n\nimport type {\n DayFilter,\n DayOfMonthSpec,\n IntervalUnit,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n Weekday,\n} from \"./ast.js\";\n\n/** Render a schedule as its canonical string form. */\nexport function display(schedule: ScheduleData): string {\n let out = displayExpr(schedule.expr);\n\n // Trailing clauses in order: except, until, starting, during, timezone\n if (schedule.except.length > 0) {\n out += \" except \";\n out += schedule.except\n .map((exc) => {\n if (exc.type === \"named\") return `${exc.month} ${exc.day}`;\n return exc.date;\n })\n .join(\", \");\n }\n\n if (schedule.until) {\n if (schedule.until.type === \"iso\") {\n out += ` until ${schedule.until.date}`;\n } else {\n out += ` until ${schedule.until.month} ${schedule.until.day}`;\n }\n }\n\n if (schedule.anchor) {\n out += ` starting ${schedule.anchor}`;\n }\n\n if (schedule.during.length > 0) {\n out += ` during ${schedule.during.join(\", \")}`;\n }\n\n if (schedule.timezone) {\n out += ` in ${schedule.timezone}`;\n }\n\n return out;\n}\n\nfunction displayExpr(expr: ScheduleExpr): string {\n switch (expr.type) {\n case \"intervalRepeat\": {\n let out = `every ${expr.interval} ${unitDisplay(expr.interval, expr.unit)}`;\n out += ` from ${formatTime(expr.from)} to ${formatTime(expr.to)}`;\n if (expr.dayFilter) {\n out += ` on ${displayDayFilter(expr.dayFilter)}`;\n }\n return out;\n }\n case \"dayRepeat\":\n if (expr.interval > 1) {\n return `every ${expr.interval} days at ${formatTimeList(expr.times)}`;\n }\n return `every ${displayDayFilter(expr.days)} at ${formatTimeList(expr.times)}`;\n case \"weekRepeat\":\n return `every ${expr.interval} weeks on ${formatDayList(expr.days)} at ${formatTimeList(expr.times)}`;\n case \"monthRepeat\": {\n let targetStr: string;\n if (expr.target.type === \"days\") {\n targetStr = formatOrdinalDaySpecs(expr.target.specs);\n } else if (expr.target.type === \"lastDay\") {\n targetStr = \"last day\";\n } else {\n targetStr = \"last weekday\";\n }\n if (expr.interval > 1) {\n return `every ${expr.interval} months on the ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n return `every month on the ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n case \"ordinalRepeat\":\n if (expr.interval > 1) {\n return `${expr.ordinal} ${expr.day} of every ${expr.interval} months at ${formatTimeList(expr.times)}`;\n }\n return `${expr.ordinal} ${expr.day} of every month at ${formatTimeList(expr.times)}`;\n case \"singleDate\": {\n let dateStr: string;\n if (expr.date.type === \"named\") {\n dateStr = `${expr.date.month} ${expr.date.day}`;\n } else {\n dateStr = expr.date.date;\n }\n return `on ${dateStr} at ${formatTimeList(expr.times)}`;\n }\n case \"yearRepeat\": {\n let targetStr: string;\n if (expr.target.type === \"date\") {\n targetStr = `${expr.target.month} ${expr.target.day}`;\n } else if (expr.target.type === \"ordinalWeekday\") {\n targetStr = `the ${expr.target.ordinal} ${expr.target.weekday} of ${expr.target.month}`;\n } else if (expr.target.type === \"dayOfMonth\") {\n targetStr = `the ${expr.target.day}${ordinalSuffix(expr.target.day)} of ${expr.target.month}`;\n } else {\n targetStr = `the last weekday of ${expr.target.month}`;\n }\n if (expr.interval > 1) {\n return `every ${expr.interval} years on ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n return `every year on ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n }\n}\n\nfunction displayDayFilter(filter: DayFilter): string {\n switch (filter.type) {\n case \"every\":\n return \"day\";\n case \"weekday\":\n return \"weekday\";\n case \"weekend\":\n return \"weekend\";\n case \"days\":\n return formatDayList(filter.days);\n }\n}\n\nfunction formatTime(t: TimeOfDay): string {\n return `${String(t.hour).padStart(2, \"0\")}:${String(t.minute).padStart(2, \"0\")}`;\n}\n\nfunction formatTimeList(times: TimeOfDay[]): string {\n return times.map(formatTime).join(\", \");\n}\n\nfunction formatDayList(days: Weekday[]): string {\n return days.join(\", \");\n}\n\nfunction formatOrdinalDaySpecs(specs: DayOfMonthSpec[]): string {\n return specs\n .map((spec) => {\n if (spec.type === \"single\") {\n return `${spec.day}${ordinalSuffix(spec.day)}`;\n }\n return `${spec.start}${ordinalSuffix(spec.start)} to ${spec.end}${ordinalSuffix(spec.end)}`;\n })\n .join(\", \");\n}\n\nexport function ordinalSuffix(n: number): string {\n const mod100 = n % 100;\n if (mod100 >= 11 && mod100 <= 13) return \"th\";\n switch (n % 10) {\n case 1:\n return \"st\";\n case 2:\n return \"nd\";\n case 3:\n return \"rd\";\n default:\n return \"th\";\n }\n}\n\nfunction unitDisplay(interval: number, unit: IntervalUnit): string {\n if (unit === \"min\") {\n return interval === 1 ? \"minute\" : \"min\";\n }\n return interval === 1 ? \"hour\" : \"hours\";\n}\n","// Evaluator — computes next occurrences and matches for hron schedules.\n\nimport { Temporal } from \"@js-temporal/polyfill\";\nimport type {\n DateSpec,\n DayFilter,\n Exception,\n MonthName,\n MonthTarget,\n OrdinalPosition,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n UntilSpec,\n Weekday,\n YearTarget,\n} from \"./ast.js\";\nimport {\n expandMonthTarget,\n monthNumber,\n ordinalToN,\n weekdayNumber,\n} from \"./ast.js\";\n\ntype ZDT = Temporal.ZonedDateTime;\ntype PD = Temporal.PlainDate;\n\n// --- Timezone resolution ---\n\n/** Resolve timezone, defaulting to UTC for deterministic behavior. */\nfunction resolveTz(tz: string | null): string {\n return tz ?? \"UTC\";\n}\n\n// --- Helpers ---\n\nfunction toPlainTime(tod: TimeOfDay): Temporal.PlainTime {\n return Temporal.PlainTime.from({ hour: tod.hour, minute: tod.minute });\n}\n\nfunction atTimeOnDate(date: PD, time: Temporal.PlainTime, tz: string): ZDT {\n return date.toPlainDateTime(time).toZonedDateTime(tz, {\n disambiguation: \"compatible\",\n });\n}\n\nfunction weekdayNameToNumber(day: Weekday): number {\n return weekdayNumber(day);\n}\n\nfunction matchesDayFilter(date: PD, filter: DayFilter): boolean {\n const dow = date.dayOfWeek; // 1=Monday ... 7=Sunday\n switch (filter.type) {\n case \"every\":\n return true;\n case \"weekday\":\n return dow >= 1 && dow <= 5;\n case \"weekend\":\n return dow === 6 || dow === 7;\n case \"days\":\n return filter.days.some((d) => weekdayNameToNumber(d) === dow);\n }\n}\n\nfunction lastDayOfMonth(year: number, month: number): PD {\n return Temporal.PlainDate.from({ year, month, day: 1 })\n .add({ months: 1 })\n .subtract({ days: 1 });\n}\n\nfunction lastWeekdayOfMonth(year: number, month: number): PD {\n let d = lastDayOfMonth(year, month);\n while (d.dayOfWeek === 6 || d.dayOfWeek === 7) {\n d = d.subtract({ days: 1 });\n }\n return d;\n}\n\nfunction nthWeekdayOfMonth(\n year: number,\n month: number,\n weekday: Weekday,\n n: number,\n): PD | null {\n const targetDow = weekdayNameToNumber(weekday);\n let d = Temporal.PlainDate.from({ year, month, day: 1 });\n while (d.dayOfWeek !== targetDow) {\n d = d.add({ days: 1 });\n }\n for (let i = 1; i < n; i++) {\n d = d.add({ days: 7 });\n }\n if (d.month !== month) return null;\n return d;\n}\n\nfunction lastWeekdayInMonth(year: number, month: number, weekday: Weekday): PD {\n const targetDow = weekdayNameToNumber(weekday);\n let d = lastDayOfMonth(year, month);\n while (d.dayOfWeek !== targetDow) {\n d = d.subtract({ days: 1 });\n }\n return d;\n}\n\nconst EPOCH_MONDAY: PD = Temporal.PlainDate.from(\"1970-01-05\");\nconst EPOCH_DATE: PD = Temporal.PlainDate.from(\"1970-01-01\");\nconst MIDNIGHT: Temporal.PlainTime = Temporal.PlainTime.from({\n hour: 0,\n minute: 0,\n});\n\nfunction weeksBetween(a: PD, b: PD): number {\n const days = a.until(b, { largestUnit: \"days\" }).days;\n return Math.floor(days / 7);\n}\n\nfunction daysBetween(a: PD, b: PD): number {\n return a.until(b, { largestUnit: \"days\" }).days;\n}\n\nfunction monthsBetweenYM(a: PD, b: PD): number {\n return b.year * 12 + b.month - (a.year * 12 + a.month);\n}\n\n/** Euclidean modulo (always non-negative). */\nfunction euclideanMod(a: number, b: number): number {\n return ((a % b) + b) % b;\n}\n\nfunction isExcepted(date: PD, exceptions: Exception[]): boolean {\n for (const exc of exceptions) {\n if (exc.type === \"named\") {\n if (date.month === monthNumber(exc.month) && date.day === exc.day) {\n return true;\n }\n } else {\n const excDate = Temporal.PlainDate.from(exc.date);\n if (Temporal.PlainDate.compare(date, excDate) === 0) {\n return true;\n }\n }\n }\n return false;\n}\n\ninterface ParsedExceptions {\n named: Array<{ month: number; day: number }>;\n isoDates: PD[];\n}\n\nfunction parseExceptions(exceptions: Exception[]): ParsedExceptions {\n const named: Array<{ month: number; day: number }> = [];\n const isoDates: PD[] = [];\n for (const exc of exceptions) {\n if (exc.type === \"named\") {\n named.push({ month: monthNumber(exc.month), day: exc.day });\n } else {\n isoDates.push(Temporal.PlainDate.from(exc.date));\n }\n }\n return { named, isoDates };\n}\n\nfunction isExceptedParsed(date: PD, parsed: ParsedExceptions): boolean {\n for (const n of parsed.named) {\n if (date.month === n.month && date.day === n.day) return true;\n }\n for (const d of parsed.isoDates) {\n if (Temporal.PlainDate.compare(date, d) === 0) return true;\n }\n return false;\n}\n\nfunction matchesDuring(date: PD, during: MonthName[]): boolean {\n if (during.length === 0) return true;\n return during.some((mn) => monthNumber(mn) === date.month);\n}\n\n/** Find the 1st of the next valid `during` month after `date`. */\nfunction nextDuringMonth(date: PD, during: MonthName[]): PD {\n const currentMonth = date.month;\n const months = during.map((mn) => monthNumber(mn)).sort((a, b) => a - b);\n\n for (const m of months) {\n if (m > currentMonth) {\n return Temporal.PlainDate.from({ year: date.year, month: m, day: 1 });\n }\n }\n // Wrap to first month of next year\n return Temporal.PlainDate.from({\n year: date.year + 1,\n month: months[0],\n day: 1,\n });\n}\n\nfunction resolveUntil(until: UntilSpec, now: ZDT): PD {\n if (until.type === \"iso\") {\n return Temporal.PlainDate.from(until.date);\n }\n const year = now.toPlainDate().year;\n for (const y of [year, year + 1]) {\n try {\n const d = Temporal.PlainDate.from(\n {\n year: y,\n month: monthNumber(until.month),\n day: until.day,\n },\n { overflow: \"reject\" },\n );\n if (Temporal.PlainDate.compare(d, now.toPlainDate()) >= 0) {\n return d;\n }\n } catch {\n // Invalid date, try next year\n }\n }\n return Temporal.PlainDate.from(\n {\n year: year + 1,\n month: monthNumber(until.month),\n day: until.day,\n },\n { overflow: \"reject\" },\n );\n}\n\nfunction earliestFutureAtTimes(\n date: PD,\n times: TimeOfDay[],\n tz: string,\n now: ZDT,\n): ZDT | null {\n let best: ZDT | null = null;\n for (const tod of times) {\n const t = toPlainTime(tod);\n const candidate = atTimeOnDate(date, t, tz);\n if (Temporal.ZonedDateTime.compare(candidate, now) > 0) {\n if (\n best === null ||\n Temporal.ZonedDateTime.compare(candidate, best) < 0\n ) {\n best = candidate;\n }\n }\n }\n return best;\n}\n\n// --- Public API ---\n\nexport function nextFrom(schedule: ScheduleData, now: ZDT): ZDT | null {\n const tz = resolveTz(schedule.timezone);\n\n const untilDate = schedule.until ? resolveUntil(schedule.until, now) : null;\n\n const parsedExceptions = parseExceptions(schedule.except);\n const hasExceptions = schedule.except.length > 0;\n const hasDuring = schedule.during.length > 0;\n const needsTzConversion = untilDate !== null || hasDuring || hasExceptions;\n\n let current = now;\n for (let i = 0; i < 1000; i++) {\n const candidate = nextExpr(schedule.expr, tz, schedule.anchor, current);\n\n if (candidate === null) return null;\n\n // Convert to target tz once for all filter checks\n const cDate = needsTzConversion\n ? candidate.withTimeZone(tz).toPlainDate()\n : null;\n\n // Apply until filter\n if (untilDate) {\n if (Temporal.PlainDate.compare(cDate!, untilDate) > 0) {\n return null;\n }\n }\n\n // Apply during filter\n if (hasDuring && !matchesDuring(cDate!, schedule.during)) {\n // Skip ahead to 1st of next valid during month\n const skipTo = nextDuringMonth(cDate!, schedule.during);\n current = atTimeOnDate(skipTo, MIDNIGHT, tz).subtract({ seconds: 1 });\n continue;\n }\n\n // Apply except filter\n if (hasExceptions && isExceptedParsed(cDate!, parsedExceptions)) {\n const nextDay = cDate!.add({ days: 1 });\n current = atTimeOnDate(nextDay, MIDNIGHT, tz).subtract({ seconds: 1 });\n continue;\n }\n\n return candidate;\n }\n\n return null;\n}\n\nfunction nextExpr(\n expr: ScheduleExpr,\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n switch (expr.type) {\n case \"dayRepeat\":\n return nextDayRepeat(\n expr.interval,\n expr.days,\n expr.times,\n tz,\n anchor,\n now,\n );\n case \"intervalRepeat\":\n return nextIntervalRepeat(\n expr.interval,\n expr.unit,\n expr.from,\n expr.to,\n expr.dayFilter,\n tz,\n now,\n );\n case \"weekRepeat\":\n return nextWeekRepeat(\n expr.interval,\n expr.days,\n expr.times,\n tz,\n anchor,\n now,\n );\n case \"monthRepeat\":\n return nextMonthRepeat(\n expr.interval,\n expr.target,\n expr.times,\n tz,\n anchor,\n now,\n );\n case \"ordinalRepeat\":\n return nextOrdinalRepeat(\n expr.interval,\n expr.ordinal,\n expr.day,\n expr.times,\n tz,\n anchor,\n now,\n );\n case \"singleDate\":\n return nextSingleDate(expr.date, expr.times, tz, now);\n case \"yearRepeat\":\n return nextYearRepeat(\n expr.interval,\n expr.target,\n expr.times,\n tz,\n anchor,\n now,\n );\n }\n}\n\nexport function nextNFrom(schedule: ScheduleData, now: ZDT, n: number): ZDT[] {\n const results: ZDT[] = [];\n let current = now;\n for (let i = 0; i < n; i++) {\n const next = nextFrom(schedule, current);\n if (next === null) break;\n current = next.add({ minutes: 1 });\n results.push(next);\n }\n return results;\n}\n\nexport function matches(schedule: ScheduleData, datetime: ZDT): boolean {\n const tz = resolveTz(schedule.timezone);\n const zdt = datetime.withTimeZone(tz);\n const date = zdt.toPlainDate();\n\n if (!matchesDuring(date, schedule.during)) return false;\n if (isExcepted(date, schedule.except)) return false;\n\n if (schedule.until) {\n const untilDate = resolveUntil(schedule.until, datetime);\n if (Temporal.PlainDate.compare(date, untilDate) > 0) return false;\n }\n\n // DST-aware time matching: a time matches if either the wall-clock matches\n // directly, or the scheduled time falls in a DST gap and resolves to the\n // candidate's instant (e.g., scheduled 2:00 AM during spring-forward → 3:00 AM).\n const timeMatchesWithDst = (times: TimeOfDay[]) =>\n times.some((tod) => {\n if (zdt.hour === tod.hour && zdt.minute === tod.minute) return true;\n const t = toPlainTime(tod);\n const resolved = atTimeOnDate(date, t, tz);\n return resolved.epochNanoseconds === datetime.epochNanoseconds;\n });\n\n switch (schedule.expr.type) {\n case \"dayRepeat\": {\n if (!matchesDayFilter(date, schedule.expr.days)) return false;\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_DATE;\n const dayOffset = daysBetween(anchorDate, date);\n return dayOffset >= 0 && dayOffset % schedule.expr.interval === 0;\n }\n return true;\n }\n case \"intervalRepeat\": {\n const { interval, unit, from, to, dayFilter } = schedule.expr;\n if (dayFilter && !matchesDayFilter(date, dayFilter)) return false;\n const fromMinutes = from.hour * 60 + from.minute;\n const toMinutes = to.hour * 60 + to.minute;\n const currentMinutes = zdt.hour * 60 + zdt.minute;\n if (currentMinutes < fromMinutes || currentMinutes > toMinutes)\n return false;\n const diff = currentMinutes - fromMinutes;\n const step = unit === \"min\" ? interval : interval * 60;\n return diff >= 0 && diff % step === 0;\n }\n case \"weekRepeat\": {\n const { interval, days, times } = schedule.expr;\n const dow = date.dayOfWeek;\n if (!days.some((d) => weekdayNameToNumber(d) === dow)) return false;\n if (!timeMatchesWithDst(times)) return false;\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_MONDAY;\n const weeks = weeksBetween(anchorDate, date);\n return weeks >= 0 && weeks % interval === 0;\n }\n case \"monthRepeat\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_DATE;\n const monthOffset = monthsBetweenYM(anchorDate, date);\n if (monthOffset < 0 || monthOffset % schedule.expr.interval !== 0) {\n return false;\n }\n }\n const { target } = schedule.expr;\n if (target.type === \"days\") {\n const expanded = expandMonthTarget(target);\n return expanded.includes(date.day);\n }\n if (target.type === \"lastDay\") {\n const last = lastDayOfMonth(date.year, date.month);\n return Temporal.PlainDate.compare(date, last) === 0;\n }\n const lastWd = lastWeekdayOfMonth(date.year, date.month);\n return Temporal.PlainDate.compare(date, lastWd) === 0;\n }\n case \"ordinalRepeat\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_DATE;\n const monthOffset = monthsBetweenYM(anchorDate, date);\n if (monthOffset < 0 || monthOffset % schedule.expr.interval !== 0) {\n return false;\n }\n }\n const { ordinal, day } = schedule.expr;\n let targetDate: PD | null;\n if (ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(date.year, date.month, day);\n } else {\n targetDate = nthWeekdayOfMonth(\n date.year,\n date.month,\n day,\n ordinalToN(ordinal),\n );\n }\n if (!targetDate) return false;\n return Temporal.PlainDate.compare(date, targetDate) === 0;\n }\n case \"singleDate\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n const { date: dateSpec } = schedule.expr;\n if (dateSpec.type === \"iso\") {\n const target = Temporal.PlainDate.from(dateSpec.date);\n return Temporal.PlainDate.compare(date, target) === 0;\n }\n if (dateSpec.type === \"named\") {\n return (\n date.month === monthNumber(dateSpec.month) &&\n date.day === dateSpec.day\n );\n }\n return false;\n }\n case \"yearRepeat\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorYear = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor).year\n : EPOCH_DATE.year;\n const yearOffset = date.year - anchorYear;\n if (yearOffset < 0 || yearOffset % schedule.expr.interval !== 0) {\n return false;\n }\n }\n return matchesYearTarget(schedule.expr.target, date);\n }\n }\n}\n\nfunction matchesYearTarget(target: YearTarget, date: PD): boolean {\n switch (target.type) {\n case \"date\":\n return (\n date.month === monthNumber(target.month) && date.day === target.day\n );\n case \"ordinalWeekday\": {\n if (date.month !== monthNumber(target.month)) return false;\n let targetDate: PD | null;\n if (target.ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(date.year, date.month, target.weekday);\n } else {\n targetDate = nthWeekdayOfMonth(\n date.year,\n date.month,\n target.weekday,\n ordinalToN(target.ordinal),\n );\n }\n if (!targetDate) return false;\n return Temporal.PlainDate.compare(date, targetDate) === 0;\n }\n case \"dayOfMonth\":\n return (\n date.month === monthNumber(target.month) && date.day === target.day\n );\n case \"lastWeekday\": {\n if (date.month !== monthNumber(target.month)) return false;\n const lwd = lastWeekdayOfMonth(date.year, date.month);\n return Temporal.PlainDate.compare(date, lwd) === 0;\n }\n }\n}\n\n// --- Per-variant next functions ---\n\nfunction nextDayRepeat(\n interval: number,\n days: DayFilter,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let date = nowInTz.toPlainDate();\n\n if (interval <= 1) {\n // Original behavior for interval=1\n if (matchesDayFilter(date, days)) {\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) return candidate;\n }\n\n for (let i = 0; i < 8; i++) {\n date = date.add({ days: 1 });\n if (matchesDayFilter(date, days)) {\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) return candidate;\n }\n }\n\n return null;\n }\n\n // Interval > 1: day intervals only apply to DayFilter::Every\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n\n // Find the next aligned day >= today\n const offset = daysBetween(anchorDate, date);\n const remainder = euclideanMod(offset, interval);\n let alignedDate =\n remainder === 0 ? date : date.add({ days: interval - remainder });\n\n for (let i = 0; i < 400; i++) {\n const candidate = earliestFutureAtTimes(alignedDate, times, tz, now);\n if (candidate) return candidate;\n alignedDate = alignedDate.add({ days: interval });\n }\n\n return null;\n}\n\nfunction nextIntervalRepeat(\n interval: number,\n unit: string,\n from: TimeOfDay,\n to: TimeOfDay,\n dayFilter: DayFilter | null,\n tz: string,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const stepMinutes = unit === \"min\" ? interval : interval * 60;\n const fromMinutes = from.hour * 60 + from.minute;\n const toMinutes = to.hour * 60 + to.minute;\n\n let date = nowInTz.toPlainDate();\n\n for (let d = 0; d < 400; d++) {\n if (dayFilter && !matchesDayFilter(date, dayFilter)) {\n date = date.add({ days: 1 });\n continue;\n }\n\n const sameDay =\n Temporal.PlainDate.compare(date, nowInTz.toPlainDate()) === 0;\n const nowMinutes = sameDay ? nowInTz.hour * 60 + nowInTz.minute : -1;\n\n let nextSlot: number;\n if (nowMinutes < fromMinutes) {\n nextSlot = fromMinutes;\n } else {\n const elapsed = nowMinutes - fromMinutes;\n nextSlot =\n fromMinutes + (Math.floor(elapsed / stepMinutes) + 1) * stepMinutes;\n }\n\n if (nextSlot <= toMinutes) {\n const h = Math.floor(nextSlot / 60);\n const m = nextSlot % 60;\n const t = Temporal.PlainTime.from({ hour: h, minute: m });\n const candidate = atTimeOnDate(date, t, tz);\n if (Temporal.ZonedDateTime.compare(candidate, now) > 0) {\n return candidate;\n }\n }\n\n date = date.add({ days: 1 });\n }\n\n return null;\n}\n\nfunction nextWeekRepeat(\n interval: number,\n days: Weekday[],\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_MONDAY;\n\n const date = nowInTz.toPlainDate();\n\n // Sort target DOWs by number for earliest-first matching\n const sortedDays = [...days].sort(\n (a, b) => weekdayNameToNumber(a) - weekdayNameToNumber(b),\n );\n\n // Find Monday of current week and Monday of anchor week\n const dowOffset = date.dayOfWeek - 1;\n let currentMonday = date.subtract({ days: dowOffset });\n\n const anchorDowOffset = anchorDate.dayOfWeek - 1;\n const anchorMonday = anchorDate.subtract({ days: anchorDowOffset });\n\n // Loop up to 54 iterations (covers >1 year for any interval)\n for (let i = 0; i < 54; i++) {\n const weeks = weeksBetween(anchorMonday, currentMonday);\n\n // Skip weeks before anchor\n if (weeks < 0) {\n const skip = Math.ceil(-weeks / interval);\n currentMonday = currentMonday.add({ days: skip * interval * 7 });\n continue;\n }\n\n if (weeks % interval === 0) {\n // Aligned week — try each target DOW\n for (const wd of sortedDays) {\n const dayOffset = weekdayNameToNumber(wd) - 1;\n const targetDate = currentMonday.add({ days: dayOffset });\n const candidate = earliestFutureAtTimes(targetDate, times, tz, now);\n if (candidate) return candidate;\n }\n }\n\n // Skip to next aligned week\n const remainder = weeks % interval;\n const skipWeeks = remainder === 0 ? interval : interval - remainder;\n currentMonday = currentMonday.add({ days: skipWeeks * 7 });\n }\n\n return null;\n}\n\nfunction nextMonthRepeat(\n interval: number,\n target: MonthTarget,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let year = nowInTz.year;\n let month = nowInTz.month;\n\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n const maxIter = interval > 1 ? 24 * interval : 24;\n\n for (let i = 0; i < maxIter; i++) {\n // Check interval alignment\n if (interval > 1) {\n const cur = Temporal.PlainDate.from({ year, month, day: 1 });\n const monthOffset = monthsBetweenYM(anchorDate, cur);\n if (monthOffset < 0 || euclideanMod(monthOffset, interval) !== 0) {\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n continue;\n }\n }\n\n const dateCandidates: PD[] = [];\n\n if (target.type === \"days\") {\n const expanded = expandMonthTarget(target);\n for (const dayNum of expanded) {\n const last = lastDayOfMonth(year, month);\n if (dayNum <= last.day) {\n try {\n dateCandidates.push(\n Temporal.PlainDate.from({ year, month, day: dayNum }),\n );\n } catch {\n // skip invalid\n }\n }\n }\n } else if (target.type === \"lastDay\") {\n dateCandidates.push(lastDayOfMonth(year, month));\n } else {\n dateCandidates.push(lastWeekdayOfMonth(year, month));\n }\n\n let best: ZDT | null = null;\n for (const date of dateCandidates) {\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) {\n if (\n best === null ||\n Temporal.ZonedDateTime.compare(candidate, best) < 0\n ) {\n best = candidate;\n }\n }\n }\n if (best) return best;\n\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n }\n\n return null;\n}\n\nfunction nextOrdinalRepeat(\n interval: number,\n ordinal: OrdinalPosition,\n day: Weekday,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let year = nowInTz.year;\n let month = nowInTz.month;\n\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n const maxIter = interval > 1 ? 24 * interval : 24;\n\n for (let i = 0; i < maxIter; i++) {\n // Check interval alignment\n if (interval > 1) {\n const cur = Temporal.PlainDate.from({ year, month, day: 1 });\n const monthOffset = monthsBetweenYM(anchorDate, cur);\n if (monthOffset < 0 || euclideanMod(monthOffset, interval) !== 0) {\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n continue;\n }\n }\n\n let targetDate: PD | null;\n if (ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(year, month, day);\n } else {\n targetDate = nthWeekdayOfMonth(year, month, day, ordinalToN(ordinal));\n }\n\n if (targetDate) {\n const candidate = earliestFutureAtTimes(targetDate, times, tz, now);\n if (candidate) return candidate;\n }\n\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n }\n\n return null;\n}\n\nfunction nextSingleDate(\n dateSpec: DateSpec,\n times: TimeOfDay[],\n tz: string,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n\n if (dateSpec.type === \"iso\") {\n const date = Temporal.PlainDate.from(dateSpec.date);\n return earliestFutureAtTimes(date, times, tz, now);\n }\n\n if (dateSpec.type === \"named\") {\n const startYear = nowInTz.year;\n for (let y = 0; y < 8; y++) {\n const year = startYear + y;\n try {\n const date = Temporal.PlainDate.from(\n {\n year,\n month: monthNumber(dateSpec.month),\n day: dateSpec.day,\n },\n { overflow: \"reject\" },\n );\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) return candidate;\n } catch {\n // invalid date\n }\n }\n return null;\n }\n\n return null;\n}\n\nfunction nextYearRepeat(\n interval: number,\n target: YearTarget,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const startYear = nowInTz.year;\n const anchorYear = anchor\n ? Temporal.PlainDate.from(anchor).year\n : EPOCH_DATE.year;\n\n const maxIter = interval > 1 ? 8 * interval : 8;\n\n for (let y = 0; y < maxIter; y++) {\n const year = startYear + y;\n\n // Check interval alignment\n if (interval > 1) {\n const yearOffset = year - anchorYear;\n if (yearOffset < 0 || euclideanMod(yearOffset, interval) !== 0) {\n continue;\n }\n }\n\n let targetDate: PD | null = null;\n\n switch (target.type) {\n case \"date\":\n try {\n targetDate = Temporal.PlainDate.from(\n {\n year,\n month: monthNumber(target.month),\n day: target.day,\n },\n { overflow: \"reject\" },\n );\n } catch {\n continue;\n }\n break;\n case \"ordinalWeekday\":\n if (target.ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(\n year,\n monthNumber(target.month),\n target.weekday,\n );\n } else {\n targetDate = nthWeekdayOfMonth(\n year,\n monthNumber(target.month),\n target.weekday,\n ordinalToN(target.ordinal),\n );\n }\n break;\n case \"dayOfMonth\":\n try {\n targetDate = Temporal.PlainDate.from(\n {\n year,\n month: monthNumber(target.month),\n day: target.day,\n },\n { overflow: \"reject\" },\n );\n } catch {\n continue;\n }\n break;\n case \"lastWeekday\":\n targetDate = lastWeekdayOfMonth(year, monthNumber(target.month));\n break;\n }\n\n if (targetDate) {\n const candidate = earliestFutureAtTimes(targetDate, times, tz, now);\n if (candidate) return candidate;\n }\n }\n\n return null;\n}\n","import { HronError, type Span } from \"./error.js\";\n\nexport interface Token {\n kind: TokenKind;\n span: Span;\n}\n\nexport type TokenKind =\n | { type: \"every\" }\n | { type: \"on\" }\n | { type: \"at\" }\n | { type: \"from\" }\n | { type: \"to\" }\n | { type: \"in\" }\n | { type: \"of\" }\n | { type: \"the\" }\n | { type: \"last\" }\n | { type: \"except\" }\n | { type: \"until\" }\n | { type: \"starting\" }\n | { type: \"during\" }\n | { type: \"year\" }\n | { type: \"day\" }\n | { type: \"weekday\" }\n | { type: \"weekend\" }\n | { type: \"weeks\" }\n | { type: \"month\" }\n | { type: \"dayName\"; name: string }\n | { type: \"monthName\"; name: string }\n | { type: \"ordinal\"; name: string }\n | { type: \"intervalUnit\"; unit: string }\n | { type: \"number\"; value: number }\n | { type: \"ordinalNumber\"; value: number }\n | { type: \"time\"; hour: number; minute: number }\n | { type: \"isoDate\"; date: string }\n | { type: \"comma\" }\n | { type: \"timezone\"; tz: string };\n\nexport function tokenize(input: string): Token[] {\n const lexer = new Lexer(input);\n return lexer.tokenize();\n}\n\nclass Lexer {\n private input: string;\n private pos: number;\n private afterIn: boolean;\n\n constructor(input: string) {\n this.input = input;\n this.pos = 0;\n this.afterIn = false;\n }\n\n tokenize(): Token[] {\n const tokens: Token[] = [];\n while (true) {\n this.skipWhitespace();\n if (this.pos >= this.input.length) break;\n\n if (this.afterIn) {\n this.afterIn = false;\n tokens.push(this.lexTimezone());\n continue;\n }\n\n const start = this.pos;\n const ch = this.input[this.pos];\n\n if (ch === \",\") {\n this.pos++;\n tokens.push({\n kind: { type: \"comma\" },\n span: { start, end: this.pos },\n });\n continue;\n }\n\n if (isDigit(ch)) {\n tokens.push(this.lexNumberOrTimeOrDate());\n continue;\n }\n\n if (isAlpha(ch)) {\n tokens.push(this.lexWord());\n continue;\n }\n\n throw HronError.lex(\n `unexpected character '${ch}'`,\n { start, end: start + 1 },\n this.input,\n );\n }\n return tokens;\n }\n\n private skipWhitespace(): void {\n while (this.pos < this.input.length && isWhitespace(this.input[this.pos])) {\n this.pos++;\n }\n }\n\n private lexTimezone(): Token {\n this.skipWhitespace();\n const start = this.pos;\n while (\n this.pos < this.input.length &&\n !isWhitespace(this.input[this.pos])\n ) {\n this.pos++;\n }\n const tz = this.input.slice(start, this.pos);\n if (tz.length === 0) {\n throw HronError.lex(\n \"expected timezone after 'in'\",\n { start, end: start + 1 },\n this.input,\n );\n }\n return { kind: { type: \"timezone\", tz }, span: { start, end: this.pos } };\n }\n\n private lexNumberOrTimeOrDate(): Token {\n const start = this.pos;\n const numStart = this.pos;\n while (this.pos < this.input.length && isDigit(this.input[this.pos])) {\n this.pos++;\n }\n const digits = this.input.slice(numStart, this.pos);\n\n // Check for ISO date: YYYY-MM-DD\n if (\n digits.length === 4 &&\n this.pos < this.input.length &&\n this.input[this.pos] === \"-\"\n ) {\n const remaining = this.input.slice(start);\n if (\n remaining.length >= 10 &&\n remaining[4] === \"-\" &&\n isDigit(remaining[5]) &&\n isDigit(remaining[6]) &&\n remaining[7] === \"-\" &&\n isDigit(remaining[8]) &&\n isDigit(remaining[9])\n ) {\n this.pos = start + 10;\n return {\n kind: { type: \"isoDate\", date: this.input.slice(start, this.pos) },\n span: { start, end: this.pos },\n };\n }\n }\n\n // Check for time: HH:MM\n if (\n (digits.length === 1 || digits.length === 2) &&\n this.pos < this.input.length &&\n this.input[this.pos] === \":\"\n ) {\n this.pos++; // skip ':'\n const minStart = this.pos;\n while (this.pos < this.input.length && isDigit(this.input[this.pos])) {\n this.pos++;\n }\n const minDigits = this.input.slice(minStart, this.pos);\n if (minDigits.length === 2) {\n const hour = parseInt(digits, 10);\n const minute = parseInt(minDigits, 10);\n if (hour > 23 || minute > 59) {\n throw HronError.lex(\n \"invalid time\",\n { start, end: this.pos },\n this.input,\n );\n }\n return {\n kind: { type: \"time\", hour, minute },\n span: { start, end: this.pos },\n };\n }\n }\n\n const num = parseInt(digits, 10);\n if (Number.isNaN(num)) {\n throw HronError.lex(\n \"invalid number\",\n { start, end: this.pos },\n this.input,\n );\n }\n\n // Check for ordinal suffix: st, nd, rd, th\n if (this.pos + 1 < this.input.length) {\n const suffix = this.input.slice(this.pos, this.pos + 2).toLowerCase();\n if (\n suffix === \"st\" ||\n suffix === \"nd\" ||\n suffix === \"rd\" ||\n suffix === \"th\"\n ) {\n this.pos += 2;\n return {\n kind: { type: \"ordinalNumber\", value: num },\n span: { start, end: this.pos },\n };\n }\n }\n\n return {\n kind: { type: \"number\", value: num },\n span: { start, end: this.pos },\n };\n }\n\n private lexWord(): Token {\n const start = this.pos;\n while (\n this.pos < this.input.length &&\n (isAlphanumeric(this.input[this.pos]) || this.input[this.pos] === \"_\")\n ) {\n this.pos++;\n }\n const word = this.input.slice(start, this.pos).toLowerCase();\n const span = { start, end: this.pos };\n\n const kind = KEYWORD_MAP[word];\n if (kind === undefined) {\n throw HronError.lex(`unknown keyword '${word}'`, span, this.input);\n }\n\n if (kind.type === \"in\") {\n this.afterIn = true;\n }\n\n return { kind, span };\n }\n}\n\nconst KEYWORD_MAP: Record<string, TokenKind> = {\n every: { type: \"every\" },\n on: { type: \"on\" },\n at: { type: \"at\" },\n from: { type: \"from\" },\n to: { type: \"to\" },\n in: { type: \"in\" },\n of: { type: \"of\" },\n the: { type: \"the\" },\n last: { type: \"last\" },\n except: { type: \"except\" },\n until: { type: \"until\" },\n starting: { type: \"starting\" },\n during: { type: \"during\" },\n year: { type: \"year\" },\n years: { type: \"year\" },\n\n day: { type: \"day\" },\n days: { type: \"day\" },\n weekday: { type: \"weekday\" },\n weekdays: { type: \"weekday\" },\n weekend: { type: \"weekend\" },\n weekends: { type: \"weekend\" },\n weeks: { type: \"weeks\" },\n week: { type: \"weeks\" },\n month: { type: \"month\" },\n months: { type: \"month\" },\n\n monday: { type: \"dayName\", name: \"monday\" },\n mon: { type: \"dayName\", name: \"monday\" },\n tuesday: { type: \"dayName\", name: \"tuesday\" },\n tue: { type: \"dayName\", name: \"tuesday\" },\n wednesday: { type: \"dayName\", name: \"wednesday\" },\n wed: { type: \"dayName\", name: \"wednesday\" },\n thursday: { type: \"dayName\", name: \"thursday\" },\n thu: { type: \"dayName\", name: \"thursday\" },\n friday: { type: \"dayName\", name: \"friday\" },\n fri: { type: \"dayName\", name: \"friday\" },\n saturday: { type: \"dayName\", name: \"saturday\" },\n sat: { type: \"dayName\", name: \"saturday\" },\n sunday: { type: \"dayName\", name: \"sunday\" },\n sun: { type: \"dayName\", name: \"sunday\" },\n\n january: { type: \"monthName\", name: \"jan\" },\n jan: { type: \"monthName\", name: \"jan\" },\n february: { type: \"monthName\", name: \"feb\" },\n feb: { type: \"monthName\", name: \"feb\" },\n march: { type: \"monthName\", name: \"mar\" },\n mar: { type: \"monthName\", name: \"mar\" },\n april: { type: \"monthName\", name: \"apr\" },\n apr: { type: \"monthName\", name: \"apr\" },\n may: { type: \"monthName\", name: \"may\" },\n june: { type: \"monthName\", name: \"jun\" },\n jun: { type: \"monthName\", name: \"jun\" },\n july: { type: \"monthName\", name: \"jul\" },\n jul: { type: \"monthName\", name: \"jul\" },\n august: { type: \"monthName\", name: \"aug\" },\n aug: { type: \"monthName\", name: \"aug\" },\n september: { type: \"monthName\", name: \"sep\" },\n sep: { type: \"monthName\", name: \"sep\" },\n october: { type: \"monthName\", name: \"oct\" },\n oct: { type: \"monthName\", name: \"oct\" },\n november: { type: \"monthName\", name: \"nov\" },\n nov: { type: \"monthName\", name: \"nov\" },\n december: { type: \"monthName\", name: \"dec\" },\n dec: { type: \"monthName\", name: \"dec\" },\n\n first: { type: \"ordinal\", name: \"first\" },\n second: { type: \"ordinal\", name: \"second\" },\n third: { type: \"ordinal\", name: \"third\" },\n fourth: { type: \"ordinal\", name: \"fourth\" },\n fifth: { type: \"ordinal\", name: \"fifth\" },\n\n min: { type: \"intervalUnit\", unit: \"min\" },\n mins: { type: \"intervalUnit\", unit: \"min\" },\n minute: { type: \"intervalUnit\", unit: \"min\" },\n minutes: { type: \"intervalUnit\", unit: \"min\" },\n hour: { type: \"intervalUnit\", unit: \"hours\" },\n hours: { type: \"intervalUnit\", unit: \"hours\" },\n hr: { type: \"intervalUnit\", unit: \"hours\" },\n hrs: { type: \"intervalUnit\", unit: \"hours\" },\n};\n\nfunction isDigit(ch: string): boolean {\n return ch >= \"0\" && ch <= \"9\";\n}\n\nfunction isAlpha(ch: string): boolean {\n return (ch >= \"a\" && ch <= \"z\") || (ch >= \"A\" && ch <= \"Z\");\n}\n\nfunction isAlphanumeric(ch: string): boolean {\n return isDigit(ch) || isAlpha(ch);\n}\n\nfunction isWhitespace(ch: string): boolean {\n return ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\";\n}\n","// Hand-rolled recursive descent parser for hron expressions.\n\nimport type {\n DateSpec,\n DayFilter,\n DayOfMonthSpec,\n Exception,\n IntervalUnit,\n MonthName,\n MonthTarget,\n OrdinalPosition,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n UntilSpec,\n Weekday,\n YearTarget,\n} from \"./ast.js\";\nimport { newScheduleData, parseMonthName, parseWeekday } from \"./ast.js\";\nimport { HronError, type Span } from \"./error.js\";\nimport { type Token, type TokenKind, tokenize } from \"./lexer.js\";\n\nclass Parser {\n private tokens: Token[];\n private pos: number;\n private input: string;\n\n constructor(tokens: Token[], input: string) {\n this.tokens = tokens;\n this.pos = 0;\n this.input = input;\n }\n\n peek(): Token | undefined {\n return this.tokens[this.pos];\n }\n\n peekKind(): TokenKind | undefined {\n return this.tokens[this.pos]?.kind;\n }\n\n advance(): Token | undefined {\n const tok = this.tokens[this.pos];\n if (tok) this.pos++;\n return tok;\n }\n\n currentSpan(): Span {\n const tok = this.peek();\n if (tok) return tok.span;\n const last = this.tokens[this.tokens.length - 1];\n if (last) return { start: last.span.end, end: last.span.end };\n return { start: 0, end: 0 };\n }\n\n error(message: string, span: Span): HronError {\n return HronError.parse(message, span, this.input);\n }\n\n errorAtEnd(message: string): HronError {\n const span =\n this.tokens.length > 0\n ? {\n start: this.tokens[this.tokens.length - 1].span.end,\n end: this.tokens[this.tokens.length - 1].span.end,\n }\n : { start: 0, end: 0 };\n return HronError.parse(message, span, this.input);\n }\n\n consumeKind(expected: string, check: (k: TokenKind) => boolean): Token {\n const span = this.currentSpan();\n const tok = this.peek();\n if (tok && check(tok.kind)) {\n this.pos++;\n return tok;\n }\n if (tok) {\n throw this.error(`expected ${expected}, got ${tok.kind.type}`, span);\n }\n throw this.errorAtEnd(`expected ${expected}`);\n }\n\n // --- Grammar productions ---\n\n parseExpression(): ScheduleData {\n const span = this.currentSpan();\n const kind = this.peekKind();\n\n let expr: ScheduleExpr;\n if (kind?.type === \"every\") {\n this.advance();\n expr = this.parseEvery();\n } else if (kind?.type === \"on\") {\n this.advance();\n expr = this.parseOn();\n } else if (kind?.type === \"ordinal\" || kind?.type === \"last\") {\n expr = this.parseOrdinalRepeat();\n } else {\n throw this.error(\n \"expected 'every', 'on', or an ordinal (first, second, ...)\",\n span,\n );\n }\n\n return this.parseTrailingClauses(expr);\n }\n\n private parseTrailingClauses(expr: ScheduleExpr): ScheduleData {\n const schedule = newScheduleData(expr);\n\n // except\n if (this.peekKind()?.type === \"except\") {\n this.advance();\n schedule.except = this.parseExceptionList();\n }\n\n // until\n if (this.peekKind()?.type === \"until\") {\n this.advance();\n schedule.until = this.parseUntilSpec();\n }\n\n // starting\n if (this.peekKind()?.type === \"starting\") {\n this.advance();\n const k = this.peekKind();\n if (k?.type === \"isoDate\") {\n schedule.anchor = (k as { type: \"isoDate\"; date: string }).date;\n this.advance();\n } else {\n throw this.error(\n \"expected ISO date (YYYY-MM-DD) after 'starting'\",\n this.currentSpan(),\n );\n }\n }\n\n // during\n if (this.peekKind()?.type === \"during\") {\n this.advance();\n schedule.during = this.parseMonthList();\n }\n\n // in <timezone>\n if (this.peekKind()?.type === \"in\") {\n this.advance();\n const k = this.peekKind();\n if (k?.type === \"timezone\") {\n schedule.timezone = (k as { type: \"timezone\"; tz: string }).tz;\n this.advance();\n } else {\n throw this.error(\"expected timezone after 'in'\", this.currentSpan());\n }\n }\n\n return schedule;\n }\n\n private parseExceptionList(): Exception[] {\n const exceptions: Exception[] = [this.parseException()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n exceptions.push(this.parseException());\n }\n return exceptions;\n }\n\n private parseException(): Exception {\n const k = this.peekKind();\n if (k?.type === \"isoDate\") {\n const date = (k as { type: \"isoDate\"; date: string }).date;\n this.advance();\n return { type: \"iso\", date };\n }\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n )!;\n this.advance();\n const day = this.parseDayNumber(\n \"expected day number after month name in exception\",\n );\n return { type: \"named\", month, day };\n }\n throw this.error(\n \"expected ISO date or month-day in exception\",\n this.currentSpan(),\n );\n }\n\n private parseUntilSpec(): UntilSpec {\n const k = this.peekKind();\n if (k?.type === \"isoDate\") {\n const date = (k as { type: \"isoDate\"; date: string }).date;\n this.advance();\n return { type: \"iso\", date };\n }\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n )!;\n this.advance();\n const day = this.parseDayNumber(\n \"expected day number after month name in until\",\n );\n return { type: \"named\", month, day };\n }\n throw this.error(\n \"expected ISO date or month-day after 'until'\",\n this.currentSpan(),\n );\n }\n\n private parseDayNumber(errorMsg: string): number {\n const k = this.peekKind();\n if (k?.type === \"number\") {\n const n = (k as { type: \"number\"; value: number }).value;\n this.advance();\n return n;\n }\n if (k?.type === \"ordinalNumber\") {\n const n = (k as { type: \"ordinalNumber\"; value: number }).value;\n this.advance();\n return n;\n }\n throw this.error(errorMsg, this.currentSpan());\n }\n\n // After \"every\": dispatch\n private parseEvery(): ScheduleExpr {\n if (!this.peek()) throw this.errorAtEnd(\"expected repeater\");\n\n const k = this.peekKind()!;\n\n if (k.type === \"year\") {\n this.advance();\n return this.parseYearRepeat(1);\n }\n if (k.type === \"day\") {\n return this.parseDayRepeat(1, { type: \"every\" });\n }\n if (k.type === \"weekday\") {\n this.advance();\n return this.parseDayRepeat(1, { type: \"weekday\" });\n }\n if (k.type === \"weekend\") {\n this.advance();\n return this.parseDayRepeat(1, { type: \"weekend\" });\n }\n if (k.type === \"dayName\") {\n const days = this.parseDayList();\n return this.parseDayRepeat(1, { type: \"days\", days });\n }\n if (k.type === \"month\") {\n this.advance();\n return this.parseMonthRepeat(1);\n }\n if (k.type === \"number\") {\n return this.parseNumberRepeat();\n }\n\n throw this.error(\n \"expected day, weekday, weekend, year, day name, month, or number after 'every'\",\n this.currentSpan(),\n );\n }\n\n private parseDayRepeat(interval: number, days: DayFilter): ScheduleExpr {\n if (days.type === \"every\") {\n this.consumeKind(\"'day'\", (k) => k.type === \"day\");\n }\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"dayRepeat\", interval, days, times };\n }\n\n private parseNumberRepeat(): ScheduleExpr {\n const span = this.currentSpan();\n const k = this.peekKind()!;\n const num = (k as { type: \"number\"; value: number }).value;\n if (num === 0) {\n throw this.error(\"interval must be at least 1\", span);\n }\n this.advance();\n\n const next = this.peekKind();\n if (next?.type === \"weeks\") {\n this.advance();\n return this.parseWeekRepeat(num);\n }\n if (next?.type === \"intervalUnit\") {\n return this.parseIntervalRepeat(num);\n }\n if (next?.type === \"day\") {\n return this.parseDayRepeat(num, { type: \"every\" });\n }\n if (next?.type === \"month\") {\n this.advance();\n return this.parseMonthRepeat(num);\n }\n if (next?.type === \"year\") {\n this.advance();\n return this.parseYearRepeat(num);\n }\n\n throw this.error(\n \"expected 'weeks', 'min', 'minutes', 'hour', 'hours', 'day(s)', 'month(s)', or 'year(s)' after number\",\n this.currentSpan(),\n );\n }\n\n private parseIntervalRepeat(interval: number): ScheduleExpr {\n const k = this.peekKind()!;\n const unitStr = (k as { type: \"intervalUnit\"; unit: string }).unit;\n this.advance();\n\n const unit: IntervalUnit = unitStr === \"min\" ? \"min\" : \"hours\";\n\n this.consumeKind(\"'from'\", (k) => k.type === \"from\");\n const from = this.parseTime();\n this.consumeKind(\"'to'\", (k) => k.type === \"to\");\n const to = this.parseTime();\n\n let dayFilter: DayFilter | null = null;\n if (this.peekKind()?.type === \"on\") {\n this.advance();\n dayFilter = this.parseDayTarget();\n }\n\n return { type: \"intervalRepeat\", interval, unit, from, to, dayFilter };\n }\n\n private parseWeekRepeat(interval: number): ScheduleExpr {\n this.consumeKind(\"'on'\", (k) => k.type === \"on\");\n const days = this.parseDayList();\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"weekRepeat\", interval, days, times };\n }\n\n private parseMonthRepeat(interval: number): ScheduleExpr {\n this.consumeKind(\"'on'\", (k) => k.type === \"on\");\n this.consumeKind(\"'the'\", (k) => k.type === \"the\");\n\n let target: MonthTarget;\n const k = this.peekKind();\n\n if (k?.type === \"last\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type === \"day\") {\n this.advance();\n target = { type: \"lastDay\" };\n } else if (next?.type === \"weekday\") {\n this.advance();\n target = { type: \"lastWeekday\" };\n } else {\n throw this.error(\n \"expected 'day' or 'weekday' after 'last'\",\n this.currentSpan(),\n );\n }\n } else if (k?.type === \"ordinalNumber\") {\n const specs = this.parseOrdinalDayList();\n target = { type: \"days\", specs };\n } else {\n throw this.error(\n \"expected ordinal day (1st, 15th) or 'last' after 'the'\",\n this.currentSpan(),\n );\n }\n\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"monthRepeat\", interval, target, times };\n }\n\n private parseOrdinalRepeat(): ScheduleExpr {\n const ordinal = this.parseOrdinalPosition();\n\n const k = this.peekKind();\n if (k?.type !== \"dayName\") {\n throw this.error(\"expected day name after ordinal\", this.currentSpan());\n }\n const day = parseWeekday(\n (k as { type: \"dayName\"; name: string }).name,\n )! as Weekday;\n this.advance();\n\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n this.consumeKind(\"'every'\", (k) => k.type === \"every\");\n\n // \"of every [N] month(s) at ...\"\n let interval = 1;\n const next = this.peekKind();\n if (next?.type === \"number\") {\n interval = (next as { type: \"number\"; value: number }).value;\n if (interval === 0) {\n throw this.error(\"interval must be at least 1\", this.currentSpan());\n }\n this.advance();\n }\n\n this.consumeKind(\"'month'\", (k) => k.type === \"month\");\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n\n return { type: \"ordinalRepeat\", interval, ordinal, day, times };\n }\n\n private parseYearRepeat(interval: number): ScheduleExpr {\n this.consumeKind(\"'on'\", (k) => k.type === \"on\");\n\n let target: YearTarget;\n const k = this.peekKind();\n\n if (k?.type === \"the\") {\n this.advance();\n target = this.parseYearTargetAfterThe();\n } else if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n )!;\n this.advance();\n const day = this.parseDayNumber(\"expected day number after month name\");\n target = { type: \"date\", month, day };\n } else {\n throw this.error(\n \"expected month name or 'the' after 'every year on'\",\n this.currentSpan(),\n );\n }\n\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"yearRepeat\", interval, target, times };\n }\n\n private parseYearTargetAfterThe(): YearTarget {\n const k = this.peekKind();\n\n if (k?.type === \"last\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type === \"weekday\") {\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"lastWeekday\", month };\n }\n if (next?.type === \"dayName\") {\n const weekday = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n )! as Weekday;\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"ordinalWeekday\", ordinal: \"last\", weekday, month };\n }\n throw this.error(\n \"expected 'weekday' or day name after 'last' in yearly expression\",\n this.currentSpan(),\n );\n }\n\n if (k?.type === \"ordinal\") {\n const ordinal = this.parseOrdinalPosition();\n const next = this.peekKind();\n if (next?.type === \"dayName\") {\n const weekday = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n )! as Weekday;\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"ordinalWeekday\", ordinal, weekday, month };\n }\n throw this.error(\n \"expected day name after ordinal in yearly expression\",\n this.currentSpan(),\n );\n }\n\n if (k?.type === \"ordinalNumber\") {\n const day = (k as { type: \"ordinalNumber\"; value: number }).value;\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"dayOfMonth\", day, month };\n }\n\n throw this.error(\n \"expected ordinal, day number, or 'last' after 'the' in yearly expression\",\n this.currentSpan(),\n );\n }\n\n private parseMonthNameToken(): MonthName {\n const k = this.peekKind();\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n )!;\n this.advance();\n return month;\n }\n throw this.error(\"expected month name\", this.currentSpan());\n }\n\n private parseOrdinalPosition(): OrdinalPosition {\n const span = this.currentSpan();\n const k = this.peekKind();\n\n if (k?.type === \"ordinal\") {\n const name = (k as { type: \"ordinal\"; name: string }).name;\n this.advance();\n return name as OrdinalPosition;\n }\n if (k?.type === \"last\") {\n this.advance();\n return \"last\";\n }\n throw this.error(\n \"expected ordinal (first, second, third, fourth, fifth, last)\",\n span,\n );\n }\n\n private parseOn(): ScheduleExpr {\n const date = this.parseDateTarget();\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"singleDate\", date, times };\n }\n\n private parseDateTarget(): DateSpec {\n const k = this.peekKind();\n\n if (k?.type === \"isoDate\") {\n const date = (k as { type: \"isoDate\"; date: string }).date;\n this.advance();\n return { type: \"iso\", date };\n }\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n )!;\n this.advance();\n const day = this.parseDayNumber(\"expected day number after month name\");\n return { type: \"named\", month, day };\n }\n throw this.error(\n \"expected date (ISO date or month name)\",\n this.currentSpan(),\n );\n }\n\n private parseDayTarget(): DayFilter {\n const k = this.peekKind();\n if (k?.type === \"day\") {\n this.advance();\n return { type: \"every\" };\n }\n if (k?.type === \"weekday\") {\n this.advance();\n return { type: \"weekday\" };\n }\n if (k?.type === \"weekend\") {\n this.advance();\n return { type: \"weekend\" };\n }\n if (k?.type === \"dayName\") {\n const days = this.parseDayList();\n return { type: \"days\", days };\n }\n throw this.error(\n \"expected 'day', 'weekday', 'weekend', or day name\",\n this.currentSpan(),\n );\n }\n\n private parseDayList(): Weekday[] {\n const k = this.peekKind();\n if (k?.type !== \"dayName\") {\n throw this.error(\"expected day name\", this.currentSpan());\n }\n const days: Weekday[] = [\n parseWeekday((k as { type: \"dayName\"; name: string }).name)! as Weekday,\n ];\n this.advance();\n\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type !== \"dayName\") {\n throw this.error(\"expected day name after ','\", this.currentSpan());\n }\n days.push(\n parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n )! as Weekday,\n );\n this.advance();\n }\n return days;\n }\n\n private parseOrdinalDayList(): DayOfMonthSpec[] {\n const specs: DayOfMonthSpec[] = [this.parseOrdinalDaySpec()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n specs.push(this.parseOrdinalDaySpec());\n }\n return specs;\n }\n\n private parseOrdinalDaySpec(): DayOfMonthSpec {\n const k = this.peekKind();\n if (k?.type !== \"ordinalNumber\") {\n throw this.error(\"expected ordinal day number\", this.currentSpan());\n }\n const start = (k as { type: \"ordinalNumber\"; value: number }).value;\n this.advance();\n\n if (this.peekKind()?.type === \"to\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type !== \"ordinalNumber\") {\n throw this.error(\n \"expected ordinal day number after 'to'\",\n this.currentSpan(),\n );\n }\n const end = (next as { type: \"ordinalNumber\"; value: number }).value;\n this.advance();\n return { type: \"range\", start, end };\n }\n\n return { type: \"single\", day: start };\n }\n\n private parseMonthList(): MonthName[] {\n const months: MonthName[] = [this.parseMonthNameToken()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n months.push(this.parseMonthNameToken());\n }\n return months;\n }\n\n private parseTimeList(): TimeOfDay[] {\n const times: TimeOfDay[] = [this.parseTime()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n times.push(this.parseTime());\n }\n return times;\n }\n\n private parseTime(): TimeOfDay {\n const span = this.currentSpan();\n const k = this.peekKind();\n if (k?.type === \"time\") {\n const { hour, minute } = k as {\n type: \"time\";\n hour: number;\n minute: number;\n };\n this.advance();\n return { hour, minute };\n }\n throw this.error(\"expected time (HH:MM)\", span);\n }\n}\n\n/** Parse an hron expression string into a ScheduleData AST. */\nexport function parse(input: string): ScheduleData {\n const tokens = tokenize(input);\n\n if (tokens.length === 0) {\n throw HronError.parse(\"empty expression\", { start: 0, end: 0 }, input);\n }\n\n const parser = new Parser(tokens, input);\n const schedule = parser.parseExpression();\n\n if (parser.peek()) {\n throw HronError.parse(\n \"unexpected tokens after expression\",\n parser.currentSpan(),\n input,\n );\n }\n\n return schedule;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACiJO,SAAS,cAAc,KAAsB;AAClD,QAAM,MAA+B;AAAA,IACnC,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AACA,SAAO,IAAI,GAAG;AAChB;AAGO,SAAS,cAAc,KAAsB;AAClD,QAAM,MAA+B;AAAA,IACnC,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACA,SAAO,IAAI,GAAG;AAChB;AAeO,SAAS,YAAY,OAA0B;AACpD,QAAM,MAAiC;AAAA,IACrC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,SAAO,IAAI,KAAK;AAClB;AAEO,SAAS,aAAa,GAA2B;AACtD,QAAM,MAA+B;AAAA,IACnC,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS;AAAA,IACT,KAAK;AAAA,IACL,WAAW;AAAA,IACX,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AACA,SAAO,IAAI,EAAE,YAAY,CAAC,KAAK;AACjC;AAEO,SAAS,eAAe,GAA6B;AAC1D,QAAM,MAAiC;AAAA,IACrC,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,WAAW;AAAA,IACX,KAAK;AAAA,IACL,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,IACL,UAAU;AAAA,IACV,KAAK;AAAA,EACP;AACA,SAAO,IAAI,EAAE,YAAY,CAAC,KAAK;AACjC;AAEO,SAAS,cAAc,MAAgC;AAC5D,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO,CAAC,KAAK,GAAG;AAAA,EAClB;AACA,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK;AAC3C,WAAO,KAAK,CAAC;AAAA,EACf;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAA+B;AAC/D,MAAI,OAAO,SAAS,QAAQ;AAC1B,WAAO,OAAO,MAAM,QAAQ,aAAa;AAAA,EAC3C;AACA,SAAO,CAAC;AACV;AAEO,SAAS,WAAW,KAA8B;AACvD,QAAM,MAA8B;AAAA,IAClC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACA,SAAO,IAAI,GAAG;AAChB;AAYO,SAAS,gBAAgB,MAAkC;AAChE,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AAAA,IACV,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ,CAAC;AAAA,EACX;AACF;;;ACnSO,IAAM,YAAN,MAAM,mBAAkB,MAAM;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,MACA,SACA,MACA,OACA,YACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,OAAO,IAAI,SAAiB,MAAY,OAA0B;AAChE,WAAO,IAAI,WAAU,OAAO,SAAS,MAAM,KAAK;AAAA,EAClD;AAAA,EAEA,OAAO,MACL,SACA,MACA,OACA,YACW;AACX,WAAO,IAAI,WAAU,SAAS,SAAS,MAAM,OAAO,UAAU;AAAA,EAChE;AAAA,EAEA,OAAO,KAAK,SAA4B;AACtC,WAAO,IAAI,WAAU,QAAQ,OAAO;AAAA,EACtC;AAAA,EAEA,OAAO,KAAK,SAA4B;AACtC,WAAO,IAAI,WAAU,QAAQ,OAAO;AAAA,EACtC;AAAA,EAEA,cAAsB;AACpB,SACG,KAAK,SAAS,SAAS,KAAK,SAAS,YACtC,KAAK,QACL,KAAK,OACL;AACA,UAAI,MAAM,UAAU,KAAK,OAAO;AAAA;AAChC,aAAO,KAAK,KAAK,KAAK;AAAA;AACtB,YAAM,UAAU,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;AAC9C,YAAM,YAAY,IAAI;AAAA,QACpB,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,MAC7C;AACA,aAAO,UAAU;AACjB,UAAI,KAAK,YAAY;AACnB,eAAO,UAAU,KAAK,UAAU;AAAA,MAClC;AACA,aAAO;AAAA,IACT;AACA,WAAO,UAAU,KAAK,OAAO;AAAA,EAC/B;AACF;;;AC1DO,SAAS,OAAO,UAAgC;AACrD,MAAI,SAAS,OAAO,SAAS,GAAG;AAC9B,UAAM,UAAU;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,OAAO;AAClB,UAAM,UAAU;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,OAAO,SAAS,GAAG;AAC9B,UAAM,UAAU;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,SAAS;AAEtB,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,aAAa;AAChB,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,KAAK,MAAM,CAAC;AACzB,YAAM,MAAM,mBAAmB,KAAK,IAAI;AACxC,aAAO,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,QAAQ,GAAG;AAAA,IAC/C;AAAA,IAEA,KAAK,kBAAkB;AACrB,YAAM,UACJ,KAAK,KAAK,SAAS,KACnB,KAAK,KAAK,WAAW,KACrB,KAAK,GAAG,SAAS,MACjB,KAAK,GAAG,WAAW;AACrB,UAAI,CAAC,SAAS;AACZ,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,WAAW;AAClB,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,UAAI,KAAK,SAAS,OAAO;AACvB,YAAI,KAAK,KAAK,aAAa,GAAG;AAC5B,gBAAM,UAAU;AAAA,YACd,8BAA8B,KAAK,QAAQ;AAAA,UAC7C;AAAA,QACF;AACA,eAAO,KAAK,KAAK,QAAQ;AAAA,MAC3B;AAEA,aAAO,OAAO,KAAK,QAAQ;AAAA,IAC7B;AAAA,IAEA,KAAK;AACH,YAAM,UAAU;AAAA,QACd;AAAA,MACF;AAAA,IAEF,KAAK,eAAe;AAClB,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,KAAK,MAAM,CAAC;AACzB,YAAM,EAAE,OAAO,IAAI;AACnB,UAAI,OAAO,SAAS,QAAQ;AAC1B,cAAM,WAAW,OAAO,MAAM,QAAQ,CAAC,MAAM;AAC3C,cAAI,EAAE,SAAS,SAAU,QAAO,CAAC,EAAE,GAAG;AACtC,gBAAM,IAAc,CAAC;AACrB,mBAAS,IAAI,EAAE,OAAO,KAAK,EAAE,KAAK,IAAK,GAAE,KAAK,CAAC;AAC/C,iBAAO;AAAA,QACT,CAAC;AACD,cAAM,MAAM,SAAS,KAAK,GAAG;AAC7B,eAAO,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI,GAAG;AAAA,MAC3C;AACA,UAAI,OAAO,SAAS,WAAW;AAC7B,cAAM,UAAU;AAAA,UACd;AAAA,QACF;AAAA,MACF;AACA,YAAM,UAAU;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,IAEA,KAAK;AACH,YAAM,UAAU;AAAA,QACd;AAAA,MACF;AAAA,IAEF,KAAK;AACH,YAAM,UAAU;AAAA,QACd;AAAA,MACF;AAAA,IAEF,KAAK;AACH,YAAM,UAAU;AAAA,QACd;AAAA,MACF;AAAA,EACJ;AACF;AAEA,SAAS,mBAAmB,QAA2B;AACrD,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK,QAAQ;AACX,YAAM,OAAO,OAAO,KAAK,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC;AACpD,WAAK,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACzB,aAAO,KAAK,KAAK,GAAG;AAAA,IACtB;AAAA,EACF;AACF;AAGO,SAAS,SAAS,MAA4B;AACnD,QAAM,SAAS,KAAK,KAAK,EAAE,MAAM,KAAK;AACtC,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,UAAU,KAAK,+BAA+B,OAAO,MAAM,EAAE;AAAA,EACrE;AAEA,QAAM,CAAC,aAAa,WAAW,UAAU,aAAa,QAAQ,IAAI;AAGlE,MAAI,YAAY,WAAW,IAAI,GAAG;AAChC,UAAM,WAAW,SAAS,YAAY,MAAM,CAAC,GAAG,EAAE;AAClD,QAAI,OAAO,MAAM,QAAQ,EAAG,OAAM,UAAU,KAAK,yBAAyB;AAE1E,QAAI,WAAW;AACf,QAAI,SAAS;AAEb,QAAI,cAAc,KAAK;AAAA,IAEvB,WAAW,UAAU,SAAS,GAAG,GAAG;AAClC,YAAM,CAAC,OAAO,GAAG,IAAI,UAAU,MAAM,GAAG;AACxC,iBAAW,SAAS,OAAO,EAAE;AAC7B,eAAS,SAAS,KAAK,EAAE;AACzB,UAAI,OAAO,MAAM,QAAQ,KAAK,OAAO,MAAM,MAAM;AAC/C,cAAM,UAAU,KAAK,oBAAoB;AAAA,IAC7C,OAAO;AACL,YAAM,IAAI,SAAS,WAAW,EAAE;AAChC,UAAI,OAAO,MAAM,CAAC,EAAG,OAAM,UAAU,KAAK,cAAc;AACxD,iBAAW;AACX,eAAS;AAAA,IACX;AAEA,UAAM,YAAY,aAAa,MAAM,OAAO,aAAa,QAAQ;AAEjE,QAAI,aAAa,KAAK;AACpB,YAAMA,QAAqB;AAAA,QACzB,MAAM;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,MAAM,EAAE,MAAM,UAAU,QAAQ,EAAE;AAAA,QAClC,IAAI,EAAE,MAAM,QAAQ,QAAQ,WAAW,KAAK,KAAK,EAAE;AAAA,QACnD;AAAA,MACF;AACA,aAAO,gBAAgBA,KAAI;AAAA,IAC7B;AAAA,EACF;AAGA,MAAI,UAAU,WAAW,IAAI,KAAK,gBAAgB,KAAK;AACrD,UAAM,WAAW,SAAS,UAAU,MAAM,CAAC,GAAG,EAAE;AAChD,QAAI,OAAO,MAAM,QAAQ,EAAG,OAAM,UAAU,KAAK,uBAAuB;AACxE,QAAI,aAAa,OAAO,aAAa,KAAK;AACxC,YAAMA,QAAqB;AAAA,QACzB,MAAM;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE;AAAA,QAC3B,IAAI,EAAE,MAAM,IAAI,QAAQ,GAAG;AAAA,QAC3B,WAAW;AAAA,MACb;AACA,aAAO,gBAAgBA,KAAI;AAAA,IAC7B;AAAA,EACF;AAGA,QAAM,SAAS,SAAS,aAAa,EAAE;AACvC,MAAI,OAAO,MAAM,MAAM;AACrB,UAAM,UAAU,KAAK,yBAAyB,WAAW,EAAE;AAC7D,QAAM,OAAO,SAAS,WAAW,EAAE;AACnC,MAAI,OAAO,MAAM,IAAI;AACnB,UAAM,UAAU,KAAK,uBAAuB,SAAS,EAAE;AACzD,QAAM,OAAO,EAAE,MAAM,OAAO;AAG5B,MAAI,aAAa,OAAO,aAAa,KAAK;AACxC,QAAI,SAAS,SAAS,GAAG,GAAG;AAC1B,YAAM,UAAU,KAAK,6BAA6B,QAAQ,EAAE;AAAA,IAC9D;AACA,UAAM,UAAU,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM;AAC7C,YAAM,IAAI,SAAS,GAAG,EAAE;AACxB,UAAI,OAAO,MAAM,CAAC;AAChB,cAAM,UAAU,KAAK,sBAAsB,QAAQ,EAAE;AACvD,aAAO;AAAA,IACT,CAAC;AACD,UAAM,QAA0B,QAAQ,IAAI,CAAC,OAAO;AAAA,MAClD,MAAM;AAAA,MACN,KAAK;AAAA,IACP,EAAE;AACF,UAAMA,QAAqB;AAAA,MACzB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ,EAAE,MAAM,QAAQ,MAAM;AAAA,MAC9B,OAAO,CAAC,IAAI;AAAA,IACd;AACA,WAAO,gBAAgBA,KAAI;AAAA,EAC7B;AAGA,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,OAAqB;AAAA,IACzB,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,IACA,OAAO,CAAC,IAAI;AAAA,EACd;AACA,SAAO,gBAAgB,IAAI;AAC7B;AAEA,SAAS,aAAa,OAA0B;AAC9C,MAAI,UAAU,IAAK,QAAO,EAAE,MAAM,QAAQ;AAC1C,MAAI,UAAU,MAAO,QAAO,EAAE,MAAM,UAAU;AAC9C,MAAI,UAAU,SAAS,UAAU,MAAO,QAAO,EAAE,MAAM,UAAU;AAEjE,MAAI,MAAM,SAAS,GAAG,GAAG;AACvB,UAAM,UAAU,KAAK,6BAA6B,KAAK,EAAE;AAAA,EAC3D;AAEA,QAAM,OAAO,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM;AACvC,UAAM,IAAI,SAAS,GAAG,EAAE;AACxB,QAAI,OAAO,MAAM,CAAC,EAAG,OAAM,UAAU,KAAK,sBAAsB,KAAK,EAAE;AACvE,WAAO;AAAA,EACT,CAAC;AAED,QAAM,OAAkB,KAAK,IAAI,CAAC,MAAM,iBAAiB,CAAC,CAAC;AAC3D,SAAO,EAAE,MAAM,QAAQ,KAAK;AAC9B;AAEA,SAAS,iBAAiB,GAAoB;AAC5C,QAAM,MAA+B;AAAA,IACnC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACA,QAAM,SAAS,IAAI,CAAC;AACpB,MAAI,CAAC,OAAQ,OAAM,UAAU,KAAK,uBAAuB,CAAC,EAAE;AAC5D,SAAO;AACT;;;ACrRO,SAAS,QAAQ,UAAgC;AACtD,MAAI,MAAM,YAAY,SAAS,IAAI;AAGnC,MAAI,SAAS,OAAO,SAAS,GAAG;AAC9B,WAAO;AACP,WAAO,SAAS,OACb,IAAI,CAAC,QAAQ;AACZ,UAAI,IAAI,SAAS,QAAS,QAAO,GAAG,IAAI,KAAK,IAAI,IAAI,GAAG;AACxD,aAAO,IAAI;AAAA,IACb,CAAC,EACA,KAAK,IAAI;AAAA,EACd;AAEA,MAAI,SAAS,OAAO;AAClB,QAAI,SAAS,MAAM,SAAS,OAAO;AACjC,aAAO,UAAU,SAAS,MAAM,IAAI;AAAA,IACtC,OAAO;AACL,aAAO,UAAU,SAAS,MAAM,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,IAC7D;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,aAAa,SAAS,MAAM;AAAA,EACrC;AAEA,MAAI,SAAS,OAAO,SAAS,GAAG;AAC9B,WAAO,WAAW,SAAS,OAAO,KAAK,IAAI,CAAC;AAAA,EAC9C;AAEA,MAAI,SAAS,UAAU;AACrB,WAAO,OAAO,SAAS,QAAQ;AAAA,EACjC;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,MAA4B;AAC/C,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,kBAAkB;AACrB,UAAI,MAAM,SAAS,KAAK,QAAQ,IAAI,YAAY,KAAK,UAAU,KAAK,IAAI,CAAC;AACzE,aAAO,SAAS,WAAW,KAAK,IAAI,CAAC,OAAO,WAAW,KAAK,EAAE,CAAC;AAC/D,UAAI,KAAK,WAAW;AAClB,eAAO,OAAO,iBAAiB,KAAK,SAAS,CAAC;AAAA,MAChD;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK;AACH,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,SAAS,KAAK,QAAQ,YAAY,eAAe,KAAK,KAAK,CAAC;AAAA,MACrE;AACA,aAAO,SAAS,iBAAiB,KAAK,IAAI,CAAC,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,IAC9E,KAAK;AACH,aAAO,SAAS,KAAK,QAAQ,aAAa,cAAc,KAAK,IAAI,CAAC,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,IACrG,KAAK,eAAe;AAClB,UAAI;AACJ,UAAI,KAAK,OAAO,SAAS,QAAQ;AAC/B,oBAAY,sBAAsB,KAAK,OAAO,KAAK;AAAA,MACrD,WAAW,KAAK,OAAO,SAAS,WAAW;AACzC,oBAAY;AAAA,MACd,OAAO;AACL,oBAAY;AAAA,MACd;AACA,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,SAAS,KAAK,QAAQ,kBAAkB,SAAS,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,MAC3F;AACA,aAAO,sBAAsB,SAAS,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,IACzE;AAAA,IACA,KAAK;AACH,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,GAAG,KAAK,OAAO,IAAI,KAAK,GAAG,aAAa,KAAK,QAAQ,cAAc,eAAe,KAAK,KAAK,CAAC;AAAA,MACtG;AACA,aAAO,GAAG,KAAK,OAAO,IAAI,KAAK,GAAG,sBAAsB,eAAe,KAAK,KAAK,CAAC;AAAA,IACpF,KAAK,cAAc;AACjB,UAAI;AACJ,UAAI,KAAK,KAAK,SAAS,SAAS;AAC9B,kBAAU,GAAG,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,GAAG;AAAA,MAC/C,OAAO;AACL,kBAAU,KAAK,KAAK;AAAA,MACtB;AACA,aAAO,MAAM,OAAO,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,IACvD;AAAA,IACA,KAAK,cAAc;AACjB,UAAI;AACJ,UAAI,KAAK,OAAO,SAAS,QAAQ;AAC/B,oBAAY,GAAG,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,GAAG;AAAA,MACrD,WAAW,KAAK,OAAO,SAAS,kBAAkB;AAChD,oBAAY,OAAO,KAAK,OAAO,OAAO,IAAI,KAAK,OAAO,OAAO,OAAO,KAAK,OAAO,KAAK;AAAA,MACvF,WAAW,KAAK,OAAO,SAAS,cAAc;AAC5C,oBAAY,OAAO,KAAK,OAAO,GAAG,GAAG,cAAc,KAAK,OAAO,GAAG,CAAC,OAAO,KAAK,OAAO,KAAK;AAAA,MAC7F,OAAO;AACL,oBAAY,uBAAuB,KAAK,OAAO,KAAK;AAAA,MACtD;AACA,UAAI,KAAK,WAAW,GAAG;AACrB,eAAO,SAAS,KAAK,QAAQ,aAAa,SAAS,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,MACtF;AACA,aAAO,iBAAiB,SAAS,OAAO,eAAe,KAAK,KAAK,CAAC;AAAA,IACpE;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAA2B;AACnD,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,cAAc,OAAO,IAAI;AAAA,EACpC;AACF;AAEA,SAAS,WAAW,GAAsB;AACxC,SAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,EAAE,MAAM,EAAE,SAAS,GAAG,GAAG,CAAC;AAChF;AAEA,SAAS,eAAe,OAA4B;AAClD,SAAO,MAAM,IAAI,UAAU,EAAE,KAAK,IAAI;AACxC;AAEA,SAAS,cAAc,MAAyB;AAC9C,SAAO,KAAK,KAAK,IAAI;AACvB;AAEA,SAAS,sBAAsB,OAAiC;AAC9D,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,QAAI,KAAK,SAAS,UAAU;AAC1B,aAAO,GAAG,KAAK,GAAG,GAAG,cAAc,KAAK,GAAG,CAAC;AAAA,IAC9C;AACA,WAAO,GAAG,KAAK,KAAK,GAAG,cAAc,KAAK,KAAK,CAAC,OAAO,KAAK,GAAG,GAAG,cAAc,KAAK,GAAG,CAAC;AAAA,EAC3F,CAAC,EACA,KAAK,IAAI;AACd;AAEO,SAAS,cAAc,GAAmB;AAC/C,QAAM,SAAS,IAAI;AACnB,MAAI,UAAU,MAAM,UAAU,GAAI,QAAO;AACzC,UAAQ,IAAI,IAAI;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,YAAY,UAAkB,MAA4B;AACjE,MAAI,SAAS,OAAO;AAClB,WAAO,aAAa,IAAI,WAAW;AAAA,EACrC;AACA,SAAO,aAAa,IAAI,SAAS;AACnC;;;ACxKA,sBAAyB;AA4BzB,SAAS,UAAU,IAA2B;AAC5C,SAAO,MAAM;AACf;AAIA,SAAS,YAAY,KAAoC;AACvD,SAAO,yBAAS,UAAU,KAAK,EAAE,MAAM,IAAI,MAAM,QAAQ,IAAI,OAAO,CAAC;AACvE;AAEA,SAAS,aAAa,MAAU,MAA0B,IAAiB;AACzE,SAAO,KAAK,gBAAgB,IAAI,EAAE,gBAAgB,IAAI;AAAA,IACpD,gBAAgB;AAAA,EAClB,CAAC;AACH;AAEA,SAAS,oBAAoB,KAAsB;AACjD,SAAO,cAAc,GAAG;AAC1B;AAEA,SAAS,iBAAiB,MAAU,QAA4B;AAC9D,QAAM,MAAM,KAAK;AACjB,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,OAAO,KAAK,OAAO;AAAA,IAC5B,KAAK;AACH,aAAO,QAAQ,KAAK,QAAQ;AAAA,IAC9B,KAAK;AACH,aAAO,OAAO,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC,MAAM,GAAG;AAAA,EACjE;AACF;AAEA,SAAS,eAAe,MAAc,OAAmB;AACvD,SAAO,yBAAS,UAAU,KAAK,EAAE,MAAM,OAAO,KAAK,EAAE,CAAC,EACnD,IAAI,EAAE,QAAQ,EAAE,CAAC,EACjB,SAAS,EAAE,MAAM,EAAE,CAAC;AACzB;AAEA,SAAS,mBAAmB,MAAc,OAAmB;AAC3D,MAAI,IAAI,eAAe,MAAM,KAAK;AAClC,SAAO,EAAE,cAAc,KAAK,EAAE,cAAc,GAAG;AAC7C,QAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,SAAS,kBACP,MACA,OACA,SACA,GACW;AACX,QAAM,YAAY,oBAAoB,OAAO;AAC7C,MAAI,IAAI,yBAAS,UAAU,KAAK,EAAE,MAAM,OAAO,KAAK,EAAE,CAAC;AACvD,SAAO,EAAE,cAAc,WAAW;AAChC,QAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAAA,EACvB;AACA,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAAA,EACvB;AACA,MAAI,EAAE,UAAU,MAAO,QAAO;AAC9B,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAc,OAAe,SAAsB;AAC7E,QAAM,YAAY,oBAAoB,OAAO;AAC7C,MAAI,IAAI,eAAe,MAAM,KAAK;AAClC,SAAO,EAAE,cAAc,WAAW;AAChC,QAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,IAAM,eAAmB,yBAAS,UAAU,KAAK,YAAY;AAC7D,IAAM,aAAiB,yBAAS,UAAU,KAAK,YAAY;AAC3D,IAAM,WAA+B,yBAAS,UAAU,KAAK;AAAA,EAC3D,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;AAED,SAAS,aAAa,GAAO,GAAe;AAC1C,QAAM,OAAO,EAAE,MAAM,GAAG,EAAE,aAAa,OAAO,CAAC,EAAE;AACjD,SAAO,KAAK,MAAM,OAAO,CAAC;AAC5B;AAEA,SAAS,YAAY,GAAO,GAAe;AACzC,SAAO,EAAE,MAAM,GAAG,EAAE,aAAa,OAAO,CAAC,EAAE;AAC7C;AAEA,SAAS,gBAAgB,GAAO,GAAe;AAC7C,SAAO,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,KAAK,EAAE;AAClD;AAGA,SAAS,aAAa,GAAW,GAAmB;AAClD,UAAS,IAAI,IAAK,KAAK;AACzB;AAEA,SAAS,WAAW,MAAU,YAAkC;AAC9D,aAAW,OAAO,YAAY;AAC5B,QAAI,IAAI,SAAS,SAAS;AACxB,UAAI,KAAK,UAAU,YAAY,IAAI,KAAK,KAAK,KAAK,QAAQ,IAAI,KAAK;AACjE,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,YAAM,UAAU,yBAAS,UAAU,KAAK,IAAI,IAAI;AAChD,UAAI,yBAAS,UAAU,QAAQ,MAAM,OAAO,MAAM,GAAG;AACnD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAOA,SAAS,gBAAgB,YAA2C;AAClE,QAAM,QAA+C,CAAC;AACtD,QAAM,WAAiB,CAAC;AACxB,aAAW,OAAO,YAAY;AAC5B,QAAI,IAAI,SAAS,SAAS;AACxB,YAAM,KAAK,EAAE,OAAO,YAAY,IAAI,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC;AAAA,IAC5D,OAAO;AACL,eAAS,KAAK,yBAAS,UAAU,KAAK,IAAI,IAAI,CAAC;AAAA,IACjD;AAAA,EACF;AACA,SAAO,EAAE,OAAO,SAAS;AAC3B;AAEA,SAAS,iBAAiB,MAAU,QAAmC;AACrE,aAAW,KAAK,OAAO,OAAO;AAC5B,QAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,EAAE,IAAK,QAAO;AAAA,EAC3D;AACA,aAAW,KAAK,OAAO,UAAU;AAC/B,QAAI,yBAAS,UAAU,QAAQ,MAAM,CAAC,MAAM,EAAG,QAAO;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,cAAc,MAAU,QAA8B;AAC7D,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,KAAK,CAAC,OAAO,YAAY,EAAE,MAAM,KAAK,KAAK;AAC3D;AAGA,SAAS,gBAAgB,MAAU,QAAyB;AAC1D,QAAM,eAAe,KAAK;AAC1B,QAAM,SAAS,OAAO,IAAI,CAAC,OAAO,YAAY,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAEvE,aAAW,KAAK,QAAQ;AACtB,QAAI,IAAI,cAAc;AACpB,aAAO,yBAAS,UAAU,KAAK,EAAE,MAAM,KAAK,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;AAAA,IACtE;AAAA,EACF;AAEA,SAAO,yBAAS,UAAU,KAAK;AAAA,IAC7B,MAAM,KAAK,OAAO;AAAA,IAClB,OAAO,OAAO,CAAC;AAAA,IACf,KAAK;AAAA,EACP,CAAC;AACH;AAEA,SAAS,aAAa,OAAkB,KAAc;AACpD,MAAI,MAAM,SAAS,OAAO;AACxB,WAAO,yBAAS,UAAU,KAAK,MAAM,IAAI;AAAA,EAC3C;AACA,QAAM,OAAO,IAAI,YAAY,EAAE;AAC/B,aAAW,KAAK,CAAC,MAAM,OAAO,CAAC,GAAG;AAChC,QAAI;AACF,YAAM,IAAI,yBAAS,UAAU;AAAA,QAC3B;AAAA,UACE,MAAM;AAAA,UACN,OAAO,YAAY,MAAM,KAAK;AAAA,UAC9B,KAAK,MAAM;AAAA,QACb;AAAA,QACA,EAAE,UAAU,SAAS;AAAA,MACvB;AACA,UAAI,yBAAS,UAAU,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG;AACzD,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,yBAAS,UAAU;AAAA,IACxB;AAAA,MACE,MAAM,OAAO;AAAA,MACb,OAAO,YAAY,MAAM,KAAK;AAAA,MAC9B,KAAK,MAAM;AAAA,IACb;AAAA,IACA,EAAE,UAAU,SAAS;AAAA,EACvB;AACF;AAEA,SAAS,sBACP,MACA,OACA,IACA,KACY;AACZ,MAAI,OAAmB;AACvB,aAAW,OAAO,OAAO;AACvB,UAAM,IAAI,YAAY,GAAG;AACzB,UAAM,YAAY,aAAa,MAAM,GAAG,EAAE;AAC1C,QAAI,yBAAS,cAAc,QAAQ,WAAW,GAAG,IAAI,GAAG;AACtD,UACE,SAAS,QACT,yBAAS,cAAc,QAAQ,WAAW,IAAI,IAAI,GAClD;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAIO,SAAS,SAAS,UAAwB,KAAsB;AACrE,QAAM,KAAK,UAAU,SAAS,QAAQ;AAEtC,QAAM,YAAY,SAAS,QAAQ,aAAa,SAAS,OAAO,GAAG,IAAI;AAEvE,QAAM,mBAAmB,gBAAgB,SAAS,MAAM;AACxD,QAAM,gBAAgB,SAAS,OAAO,SAAS;AAC/C,QAAM,YAAY,SAAS,OAAO,SAAS;AAC3C,QAAM,oBAAoB,cAAc,QAAQ,aAAa;AAE7D,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,KAAM,KAAK;AAC7B,UAAM,YAAY,SAAS,SAAS,MAAM,IAAI,SAAS,QAAQ,OAAO;AAEtE,QAAI,cAAc,KAAM,QAAO;AAG/B,UAAM,QAAQ,oBACV,UAAU,aAAa,EAAE,EAAE,YAAY,IACvC;AAGJ,QAAI,WAAW;AACb,UAAI,yBAAS,UAAU,QAAQ,OAAQ,SAAS,IAAI,GAAG;AACrD,eAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,aAAa,CAAC,cAAc,OAAQ,SAAS,MAAM,GAAG;AAExD,YAAM,SAAS,gBAAgB,OAAQ,SAAS,MAAM;AACtD,gBAAU,aAAa,QAAQ,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACpE;AAAA,IACF;AAGA,QAAI,iBAAiB,iBAAiB,OAAQ,gBAAgB,GAAG;AAC/D,YAAM,UAAU,MAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACtC,gBAAU,aAAa,SAAS,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACrE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,SACP,MACA,IACA,QACA,KACY;AACZ,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO,eAAe,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG;AAAA,IACtD,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,EACJ;AACF;AAEO,SAAS,UAAU,UAAwB,KAAU,GAAkB;AAC5E,QAAM,UAAiB,CAAC;AACxB,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,OAAO,SAAS,UAAU,OAAO;AACvC,QAAI,SAAS,KAAM;AACnB,cAAU,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC;AACjC,YAAQ,KAAK,IAAI;AAAA,EACnB;AACA,SAAO;AACT;AAEO,SAAS,QAAQ,UAAwB,UAAwB;AACtE,QAAM,KAAK,UAAU,SAAS,QAAQ;AACtC,QAAM,MAAM,SAAS,aAAa,EAAE;AACpC,QAAM,OAAO,IAAI,YAAY;AAE7B,MAAI,CAAC,cAAc,MAAM,SAAS,MAAM,EAAG,QAAO;AAClD,MAAI,WAAW,MAAM,SAAS,MAAM,EAAG,QAAO;AAE9C,MAAI,SAAS,OAAO;AAClB,UAAM,YAAY,aAAa,SAAS,OAAO,QAAQ;AACvD,QAAI,yBAAS,UAAU,QAAQ,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,EAC9D;AAKA,QAAM,qBAAqB,CAAC,UAC1B,MAAM,KAAK,CAAC,QAAQ;AAClB,QAAI,IAAI,SAAS,IAAI,QAAQ,IAAI,WAAW,IAAI,OAAQ,QAAO;AAC/D,UAAM,IAAI,YAAY,GAAG;AACzB,UAAM,WAAW,aAAa,MAAM,GAAG,EAAE;AACzC,WAAO,SAAS,qBAAqB,SAAS;AAAA,EAChD,CAAC;AAEH,UAAQ,SAAS,KAAK,MAAM;AAAA,IAC1B,KAAK,aAAa;AAChB,UAAI,CAAC,iBAAiB,MAAM,SAAS,KAAK,IAAI,EAAG,QAAO;AACxD,UAAI,CAAC,mBAAmB,SAAS,KAAK,KAAK,EAAG,QAAO;AACrD,UAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,cAAM,aAAa,SAAS,SACxB,yBAAS,UAAU,KAAK,SAAS,MAAM,IACvC;AACJ,cAAM,YAAY,YAAY,YAAY,IAAI;AAC9C,eAAO,aAAa,KAAK,YAAY,SAAS,KAAK,aAAa;AAAA,MAClE;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,kBAAkB;AACrB,YAAM,EAAE,UAAU,MAAM,MAAM,IAAI,UAAU,IAAI,SAAS;AACzD,UAAI,aAAa,CAAC,iBAAiB,MAAM,SAAS,EAAG,QAAO;AAC5D,YAAM,cAAc,KAAK,OAAO,KAAK,KAAK;AAC1C,YAAM,YAAY,GAAG,OAAO,KAAK,GAAG;AACpC,YAAM,iBAAiB,IAAI,OAAO,KAAK,IAAI;AAC3C,UAAI,iBAAiB,eAAe,iBAAiB;AACnD,eAAO;AACT,YAAM,OAAO,iBAAiB;AAC9B,YAAM,OAAO,SAAS,QAAQ,WAAW,WAAW;AACpD,aAAO,QAAQ,KAAK,OAAO,SAAS;AAAA,IACtC;AAAA,IACA,KAAK,cAAc;AACjB,YAAM,EAAE,UAAU,MAAM,MAAM,IAAI,SAAS;AAC3C,YAAM,MAAM,KAAK;AACjB,UAAI,CAAC,KAAK,KAAK,CAAC,MAAM,oBAAoB,CAAC,MAAM,GAAG,EAAG,QAAO;AAC9D,UAAI,CAAC,mBAAmB,KAAK,EAAG,QAAO;AACvC,YAAM,aAAa,SAAS,SACxB,yBAAS,UAAU,KAAK,SAAS,MAAM,IACvC;AACJ,YAAM,QAAQ,aAAa,YAAY,IAAI;AAC3C,aAAO,SAAS,KAAK,QAAQ,aAAa;AAAA,IAC5C;AAAA,IACA,KAAK,eAAe;AAClB,UAAI,CAAC,mBAAmB,SAAS,KAAK,KAAK,EAAG,QAAO;AACrD,UAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,cAAM,aAAa,SAAS,SACxB,yBAAS,UAAU,KAAK,SAAS,MAAM,IACvC;AACJ,cAAM,cAAc,gBAAgB,YAAY,IAAI;AACpD,YAAI,cAAc,KAAK,cAAc,SAAS,KAAK,aAAa,GAAG;AACjE,iBAAO;AAAA,QACT;AAAA,MACF;AACA,YAAM,EAAE,OAAO,IAAI,SAAS;AAC5B,UAAI,OAAO,SAAS,QAAQ;AAC1B,cAAM,WAAW,kBAAkB,MAAM;AACzC,eAAO,SAAS,SAAS,KAAK,GAAG;AAAA,MACnC;AACA,UAAI,OAAO,SAAS,WAAW;AAC7B,cAAM,OAAO,eAAe,KAAK,MAAM,KAAK,KAAK;AACjD,eAAO,yBAAS,UAAU,QAAQ,MAAM,IAAI,MAAM;AAAA,MACpD;AACA,YAAM,SAAS,mBAAmB,KAAK,MAAM,KAAK,KAAK;AACvD,aAAO,yBAAS,UAAU,QAAQ,MAAM,MAAM,MAAM;AAAA,IACtD;AAAA,IACA,KAAK,iBAAiB;AACpB,UAAI,CAAC,mBAAmB,SAAS,KAAK,KAAK,EAAG,QAAO;AACrD,UAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,cAAM,aAAa,SAAS,SACxB,yBAAS,UAAU,KAAK,SAAS,MAAM,IACvC;AACJ,cAAM,cAAc,gBAAgB,YAAY,IAAI;AACpD,YAAI,cAAc,KAAK,cAAc,SAAS,KAAK,aAAa,GAAG;AACjE,iBAAO;AAAA,QACT;AAAA,MACF;AACA,YAAM,EAAE,SAAS,IAAI,IAAI,SAAS;AAClC,UAAI;AACJ,UAAI,YAAY,QAAQ;AACtB,qBAAa,mBAAmB,KAAK,MAAM,KAAK,OAAO,GAAG;AAAA,MAC5D,OAAO;AACL,qBAAa;AAAA,UACX,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA,WAAW,OAAO;AAAA,QACpB;AAAA,MACF;AACA,UAAI,CAAC,WAAY,QAAO;AACxB,aAAO,yBAAS,UAAU,QAAQ,MAAM,UAAU,MAAM;AAAA,IAC1D;AAAA,IACA,KAAK,cAAc;AACjB,UAAI,CAAC,mBAAmB,SAAS,KAAK,KAAK,EAAG,QAAO;AACrD,YAAM,EAAE,MAAM,SAAS,IAAI,SAAS;AACpC,UAAI,SAAS,SAAS,OAAO;AAC3B,cAAM,SAAS,yBAAS,UAAU,KAAK,SAAS,IAAI;AACpD,eAAO,yBAAS,UAAU,QAAQ,MAAM,MAAM,MAAM;AAAA,MACtD;AACA,UAAI,SAAS,SAAS,SAAS;AAC7B,eACE,KAAK,UAAU,YAAY,SAAS,KAAK,KACzC,KAAK,QAAQ,SAAS;AAAA,MAE1B;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,cAAc;AACjB,UAAI,CAAC,mBAAmB,SAAS,KAAK,KAAK,EAAG,QAAO;AACrD,UAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,cAAM,aAAa,SAAS,SACxB,yBAAS,UAAU,KAAK,SAAS,MAAM,EAAE,OACzC,WAAW;AACf,cAAM,aAAa,KAAK,OAAO;AAC/B,YAAI,aAAa,KAAK,aAAa,SAAS,KAAK,aAAa,GAAG;AAC/D,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO,kBAAkB,SAAS,KAAK,QAAQ,IAAI;AAAA,IACrD;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,QAAoB,MAAmB;AAChE,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aACE,KAAK,UAAU,YAAY,OAAO,KAAK,KAAK,KAAK,QAAQ,OAAO;AAAA,IAEpE,KAAK,kBAAkB;AACrB,UAAI,KAAK,UAAU,YAAY,OAAO,KAAK,EAAG,QAAO;AACrD,UAAI;AACJ,UAAI,OAAO,YAAY,QAAQ;AAC7B,qBAAa,mBAAmB,KAAK,MAAM,KAAK,OAAO,OAAO,OAAO;AAAA,MACvE,OAAO;AACL,qBAAa;AAAA,UACX,KAAK;AAAA,UACL,KAAK;AAAA,UACL,OAAO;AAAA,UACP,WAAW,OAAO,OAAO;AAAA,QAC3B;AAAA,MACF;AACA,UAAI,CAAC,WAAY,QAAO;AACxB,aAAO,yBAAS,UAAU,QAAQ,MAAM,UAAU,MAAM;AAAA,IAC1D;AAAA,IACA,KAAK;AACH,aACE,KAAK,UAAU,YAAY,OAAO,KAAK,KAAK,KAAK,QAAQ,OAAO;AAAA,IAEpE,KAAK,eAAe;AAClB,UAAI,KAAK,UAAU,YAAY,OAAO,KAAK,EAAG,QAAO;AACrD,YAAM,MAAM,mBAAmB,KAAK,MAAM,KAAK,KAAK;AACpD,aAAO,yBAAS,UAAU,QAAQ,MAAM,GAAG,MAAM;AAAA,IACnD;AAAA,EACF;AACF;AAIA,SAAS,cACP,UACA,MACA,OACA,IACA,QACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AACnC,MAAI,OAAO,QAAQ,YAAY;AAE/B,MAAI,YAAY,GAAG;AAEjB,QAAI,iBAAiB,MAAM,IAAI,GAAG;AAChC,YAAM,YAAY,sBAAsB,MAAM,OAAO,IAAI,GAAG;AAC5D,UAAI,UAAW,QAAO;AAAA,IACxB;AAEA,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAO,KAAK,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3B,UAAI,iBAAiB,MAAM,IAAI,GAAG;AAChC,cAAM,YAAY,sBAAsB,MAAM,OAAO,IAAI,GAAG;AAC5D,YAAI,UAAW,QAAO;AAAA,MACxB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,SAAS,yBAAS,UAAU,KAAK,MAAM,IAAI;AAG9D,QAAM,SAAS,YAAY,YAAY,IAAI;AAC3C,QAAM,YAAY,aAAa,QAAQ,QAAQ;AAC/C,MAAI,cACF,cAAc,IAAI,OAAO,KAAK,IAAI,EAAE,MAAM,WAAW,UAAU,CAAC;AAElE,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,UAAM,YAAY,sBAAsB,aAAa,OAAO,IAAI,GAAG;AACnE,QAAI,UAAW,QAAO;AACtB,kBAAc,YAAY,IAAI,EAAE,MAAM,SAAS,CAAC;AAAA,EAClD;AAEA,SAAO;AACT;AAEA,SAAS,mBACP,UACA,MACA,MACA,IACA,WACA,IACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AACnC,QAAM,cAAc,SAAS,QAAQ,WAAW,WAAW;AAC3D,QAAM,cAAc,KAAK,OAAO,KAAK,KAAK;AAC1C,QAAM,YAAY,GAAG,OAAO,KAAK,GAAG;AAEpC,MAAI,OAAO,QAAQ,YAAY;AAE/B,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,QAAI,aAAa,CAAC,iBAAiB,MAAM,SAAS,GAAG;AACnD,aAAO,KAAK,IAAI,EAAE,MAAM,EAAE,CAAC;AAC3B;AAAA,IACF;AAEA,UAAM,UACJ,yBAAS,UAAU,QAAQ,MAAM,QAAQ,YAAY,CAAC,MAAM;AAC9D,UAAM,aAAa,UAAU,QAAQ,OAAO,KAAK,QAAQ,SAAS;AAElE,QAAI;AACJ,QAAI,aAAa,aAAa;AAC5B,iBAAW;AAAA,IACb,OAAO;AACL,YAAM,UAAU,aAAa;AAC7B,iBACE,eAAe,KAAK,MAAM,UAAU,WAAW,IAAI,KAAK;AAAA,IAC5D;AAEA,QAAI,YAAY,WAAW;AACzB,YAAM,IAAI,KAAK,MAAM,WAAW,EAAE;AAClC,YAAM,IAAI,WAAW;AACrB,YAAM,IAAI,yBAAS,UAAU,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;AACxD,YAAM,YAAY,aAAa,MAAM,GAAG,EAAE;AAC1C,UAAI,yBAAS,cAAc,QAAQ,WAAW,GAAG,IAAI,GAAG;AACtD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO,KAAK,IAAI,EAAE,MAAM,EAAE,CAAC;AAAA,EAC7B;AAEA,SAAO;AACT;AAEA,SAAS,eACP,UACA,MACA,OACA,IACA,QACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AACnC,QAAM,aAAa,SAAS,yBAAS,UAAU,KAAK,MAAM,IAAI;AAE9D,QAAM,OAAO,QAAQ,YAAY;AAGjC,QAAM,aAAa,CAAC,GAAG,IAAI,EAAE;AAAA,IAC3B,CAAC,GAAG,MAAM,oBAAoB,CAAC,IAAI,oBAAoB,CAAC;AAAA,EAC1D;AAGA,QAAM,YAAY,KAAK,YAAY;AACnC,MAAI,gBAAgB,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAErD,QAAM,kBAAkB,WAAW,YAAY;AAC/C,QAAM,eAAe,WAAW,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGlE,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,QAAQ,aAAa,cAAc,aAAa;AAGtD,QAAI,QAAQ,GAAG;AACb,YAAM,OAAO,KAAK,KAAK,CAAC,QAAQ,QAAQ;AACxC,sBAAgB,cAAc,IAAI,EAAE,MAAM,OAAO,WAAW,EAAE,CAAC;AAC/D;AAAA,IACF;AAEA,QAAI,QAAQ,aAAa,GAAG;AAE1B,iBAAW,MAAM,YAAY;AAC3B,cAAM,YAAY,oBAAoB,EAAE,IAAI;AAC5C,cAAM,aAAa,cAAc,IAAI,EAAE,MAAM,UAAU,CAAC;AACxD,cAAM,YAAY,sBAAsB,YAAY,OAAO,IAAI,GAAG;AAClE,YAAI,UAAW,QAAO;AAAA,MACxB;AAAA,IACF;AAGA,UAAM,YAAY,QAAQ;AAC1B,UAAM,YAAY,cAAc,IAAI,WAAW,WAAW;AAC1D,oBAAgB,cAAc,IAAI,EAAE,MAAM,YAAY,EAAE,CAAC;AAAA,EAC3D;AAEA,SAAO;AACT;AAEA,SAAS,gBACP,UACA,QACA,OACA,IACA,QACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AACnC,MAAI,OAAO,QAAQ;AACnB,MAAI,QAAQ,QAAQ;AAEpB,QAAM,aAAa,SAAS,yBAAS,UAAU,KAAK,MAAM,IAAI;AAC9D,QAAM,UAAU,WAAW,IAAI,KAAK,WAAW;AAE/C,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAEhC,QAAI,WAAW,GAAG;AAChB,YAAM,MAAM,yBAAS,UAAU,KAAK,EAAE,MAAM,OAAO,KAAK,EAAE,CAAC;AAC3D,YAAM,cAAc,gBAAgB,YAAY,GAAG;AACnD,UAAI,cAAc,KAAK,aAAa,aAAa,QAAQ,MAAM,GAAG;AAChE;AACA,YAAI,QAAQ,IAAI;AACd,kBAAQ;AACR;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBAAuB,CAAC;AAE9B,QAAI,OAAO,SAAS,QAAQ;AAC1B,YAAM,WAAW,kBAAkB,MAAM;AACzC,iBAAW,UAAU,UAAU;AAC7B,cAAM,OAAO,eAAe,MAAM,KAAK;AACvC,YAAI,UAAU,KAAK,KAAK;AACtB,cAAI;AACF,2BAAe;AAAA,cACb,yBAAS,UAAU,KAAK,EAAE,MAAM,OAAO,KAAK,OAAO,CAAC;AAAA,YACtD;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,OAAO,SAAS,WAAW;AACpC,qBAAe,KAAK,eAAe,MAAM,KAAK,CAAC;AAAA,IACjD,OAAO;AACL,qBAAe,KAAK,mBAAmB,MAAM,KAAK,CAAC;AAAA,IACrD;AAEA,QAAI,OAAmB;AACvB,eAAW,QAAQ,gBAAgB;AACjC,YAAM,YAAY,sBAAsB,MAAM,OAAO,IAAI,GAAG;AAC5D,UAAI,WAAW;AACb,YACE,SAAS,QACT,yBAAS,cAAc,QAAQ,WAAW,IAAI,IAAI,GAClD;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAM,QAAO;AAEjB;AACA,QAAI,QAAQ,IAAI;AACd,cAAQ;AACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,UACA,SACA,KACA,OACA,IACA,QACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AACnC,MAAI,OAAO,QAAQ;AACnB,MAAI,QAAQ,QAAQ;AAEpB,QAAM,aAAa,SAAS,yBAAS,UAAU,KAAK,MAAM,IAAI;AAC9D,QAAM,UAAU,WAAW,IAAI,KAAK,WAAW;AAE/C,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAEhC,QAAI,WAAW,GAAG;AAChB,YAAM,MAAM,yBAAS,UAAU,KAAK,EAAE,MAAM,OAAO,KAAK,EAAE,CAAC;AAC3D,YAAM,cAAc,gBAAgB,YAAY,GAAG;AACnD,UAAI,cAAc,KAAK,aAAa,aAAa,QAAQ,MAAM,GAAG;AAChE;AACA,YAAI,QAAQ,IAAI;AACd,kBAAQ;AACR;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,YAAY,QAAQ;AACtB,mBAAa,mBAAmB,MAAM,OAAO,GAAG;AAAA,IAClD,OAAO;AACL,mBAAa,kBAAkB,MAAM,OAAO,KAAK,WAAW,OAAO,CAAC;AAAA,IACtE;AAEA,QAAI,YAAY;AACd,YAAM,YAAY,sBAAsB,YAAY,OAAO,IAAI,GAAG;AAClE,UAAI,UAAW,QAAO;AAAA,IACxB;AAEA;AACA,QAAI,QAAQ,IAAI;AACd,cAAQ;AACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,eACP,UACA,OACA,IACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AAEnC,MAAI,SAAS,SAAS,OAAO;AAC3B,UAAM,OAAO,yBAAS,UAAU,KAAK,SAAS,IAAI;AAClD,WAAO,sBAAsB,MAAM,OAAO,IAAI,GAAG;AAAA,EACnD;AAEA,MAAI,SAAS,SAAS,SAAS;AAC7B,UAAM,YAAY,QAAQ;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,OAAO,YAAY;AACzB,UAAI;AACF,cAAM,OAAO,yBAAS,UAAU;AAAA,UAC9B;AAAA,YACE;AAAA,YACA,OAAO,YAAY,SAAS,KAAK;AAAA,YACjC,KAAK,SAAS;AAAA,UAChB;AAAA,UACA,EAAE,UAAU,SAAS;AAAA,QACvB;AACA,cAAM,YAAY,sBAAsB,MAAM,OAAO,IAAI,GAAG;AAC5D,YAAI,UAAW,QAAO;AAAA,MACxB,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eACP,UACA,QACA,OACA,IACA,QACA,KACY;AACZ,QAAM,UAAU,IAAI,aAAa,EAAE;AACnC,QAAM,YAAY,QAAQ;AAC1B,QAAM,aAAa,SACf,yBAAS,UAAU,KAAK,MAAM,EAAE,OAChC,WAAW;AAEf,QAAM,UAAU,WAAW,IAAI,IAAI,WAAW;AAE9C,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,OAAO,YAAY;AAGzB,QAAI,WAAW,GAAG;AAChB,YAAM,aAAa,OAAO;AAC1B,UAAI,aAAa,KAAK,aAAa,YAAY,QAAQ,MAAM,GAAG;AAC9D;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAwB;AAE5B,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,YAAI;AACF,uBAAa,yBAAS,UAAU;AAAA,YAC9B;AAAA,cACE;AAAA,cACA,OAAO,YAAY,OAAO,KAAK;AAAA,cAC/B,KAAK,OAAO;AAAA,YACd;AAAA,YACA,EAAE,UAAU,SAAS;AAAA,UACvB;AAAA,QACF,QAAQ;AACN;AAAA,QACF;AACA;AAAA,MACF,KAAK;AACH,YAAI,OAAO,YAAY,QAAQ;AAC7B,uBAAa;AAAA,YACX;AAAA,YACA,YAAY,OAAO,KAAK;AAAA,YACxB,OAAO;AAAA,UACT;AAAA,QACF,OAAO;AACL,uBAAa;AAAA,YACX;AAAA,YACA,YAAY,OAAO,KAAK;AAAA,YACxB,OAAO;AAAA,YACP,WAAW,OAAO,OAAO;AAAA,UAC3B;AAAA,QACF;AACA;AAAA,MACF,KAAK;AACH,YAAI;AACF,uBAAa,yBAAS,UAAU;AAAA,YAC9B;AAAA,cACE;AAAA,cACA,OAAO,YAAY,OAAO,KAAK;AAAA,cAC/B,KAAK,OAAO;AAAA,YACd;AAAA,YACA,EAAE,UAAU,SAAS;AAAA,UACvB;AAAA,QACF,QAAQ;AACN;AAAA,QACF;AACA;AAAA,MACF,KAAK;AACH,qBAAa,mBAAmB,MAAM,YAAY,OAAO,KAAK,CAAC;AAC/D;AAAA,IACJ;AAEA,QAAI,YAAY;AACd,YAAM,YAAY,sBAAsB,YAAY,OAAO,IAAI,GAAG;AAClE,UAAI,UAAW,QAAO;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AACT;;;AC95BO,SAAS,SAAS,OAAwB;AAC/C,QAAM,QAAQ,IAAI,MAAM,KAAK;AAC7B,SAAO,MAAM,SAAS;AACxB;AAEA,IAAM,QAAN,MAAY;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,OAAe;AACzB,SAAK,QAAQ;AACb,SAAK,MAAM;AACX,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,WAAoB;AAClB,UAAM,SAAkB,CAAC;AACzB,WAAO,MAAM;AACX,WAAK,eAAe;AACpB,UAAI,KAAK,OAAO,KAAK,MAAM,OAAQ;AAEnC,UAAI,KAAK,SAAS;AAChB,aAAK,UAAU;AACf,eAAO,KAAK,KAAK,YAAY,CAAC;AAC9B;AAAA,MACF;AAEA,YAAM,QAAQ,KAAK;AACnB,YAAM,KAAK,KAAK,MAAM,KAAK,GAAG;AAE9B,UAAI,OAAO,KAAK;AACd,aAAK;AACL,eAAO,KAAK;AAAA,UACV,MAAM,EAAE,MAAM,QAAQ;AAAA,UACtB,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,QAC/B,CAAC;AACD;AAAA,MACF;AAEA,UAAI,QAAQ,EAAE,GAAG;AACf,eAAO,KAAK,KAAK,sBAAsB,CAAC;AACxC;AAAA,MACF;AAEA,UAAI,QAAQ,EAAE,GAAG;AACf,eAAO,KAAK,KAAK,QAAQ,CAAC;AAC1B;AAAA,MACF;AAEA,YAAM,UAAU;AAAA,QACd,yBAAyB,EAAE;AAAA,QAC3B,EAAE,OAAO,KAAK,QAAQ,EAAE;AAAA,QACxB,KAAK;AAAA,MACP;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAuB;AAC7B,WAAO,KAAK,MAAM,KAAK,MAAM,UAAU,aAAa,KAAK,MAAM,KAAK,GAAG,CAAC,GAAG;AACzE,WAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,cAAqB;AAC3B,SAAK,eAAe;AACpB,UAAM,QAAQ,KAAK;AACnB,WACE,KAAK,MAAM,KAAK,MAAM,UACtB,CAAC,aAAa,KAAK,MAAM,KAAK,GAAG,CAAC,GAClC;AACA,WAAK;AAAA,IACP;AACA,UAAM,KAAK,KAAK,MAAM,MAAM,OAAO,KAAK,GAAG;AAC3C,QAAI,GAAG,WAAW,GAAG;AACnB,YAAM,UAAU;AAAA,QACd;AAAA,QACA,EAAE,OAAO,KAAK,QAAQ,EAAE;AAAA,QACxB,KAAK;AAAA,MACP;AAAA,IACF;AACA,WAAO,EAAE,MAAM,EAAE,MAAM,YAAY,GAAG,GAAG,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EAC1E;AAAA,EAEQ,wBAA+B;AACrC,UAAM,QAAQ,KAAK;AACnB,UAAM,WAAW,KAAK;AACtB,WAAO,KAAK,MAAM,KAAK,MAAM,UAAU,QAAQ,KAAK,MAAM,KAAK,GAAG,CAAC,GAAG;AACpE,WAAK;AAAA,IACP;AACA,UAAM,SAAS,KAAK,MAAM,MAAM,UAAU,KAAK,GAAG;AAGlD,QACE,OAAO,WAAW,KAClB,KAAK,MAAM,KAAK,MAAM,UACtB,KAAK,MAAM,KAAK,GAAG,MAAM,KACzB;AACA,YAAM,YAAY,KAAK,MAAM,MAAM,KAAK;AACxC,UACE,UAAU,UAAU,MACpB,UAAU,CAAC,MAAM,OACjB,QAAQ,UAAU,CAAC,CAAC,KACpB,QAAQ,UAAU,CAAC,CAAC,KACpB,UAAU,CAAC,MAAM,OACjB,QAAQ,UAAU,CAAC,CAAC,KACpB,QAAQ,UAAU,CAAC,CAAC,GACpB;AACA,aAAK,MAAM,QAAQ;AACnB,eAAO;AAAA,UACL,MAAM,EAAE,MAAM,WAAW,MAAM,KAAK,MAAM,MAAM,OAAO,KAAK,GAAG,EAAE;AAAA,UACjE,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAGA,SACG,OAAO,WAAW,KAAK,OAAO,WAAW,MAC1C,KAAK,MAAM,KAAK,MAAM,UACtB,KAAK,MAAM,KAAK,GAAG,MAAM,KACzB;AACA,WAAK;AACL,YAAM,WAAW,KAAK;AACtB,aAAO,KAAK,MAAM,KAAK,MAAM,UAAU,QAAQ,KAAK,MAAM,KAAK,GAAG,CAAC,GAAG;AACpE,aAAK;AAAA,MACP;AACA,YAAM,YAAY,KAAK,MAAM,MAAM,UAAU,KAAK,GAAG;AACrD,UAAI,UAAU,WAAW,GAAG;AAC1B,cAAM,OAAO,SAAS,QAAQ,EAAE;AAChC,cAAM,SAAS,SAAS,WAAW,EAAE;AACrC,YAAI,OAAO,MAAM,SAAS,IAAI;AAC5B,gBAAM,UAAU;AAAA,YACd;AAAA,YACA,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,YACvB,KAAK;AAAA,UACP;AAAA,QACF;AACA,eAAO;AAAA,UACL,MAAM,EAAE,MAAM,QAAQ,MAAM,OAAO;AAAA,UACnC,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,SAAS,QAAQ,EAAE;AAC/B,QAAI,OAAO,MAAM,GAAG,GAAG;AACrB,YAAM,UAAU;AAAA,QACd;AAAA,QACA,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,QACvB,KAAK;AAAA,MACP;AAAA,IACF;AAGA,QAAI,KAAK,MAAM,IAAI,KAAK,MAAM,QAAQ;AACpC,YAAM,SAAS,KAAK,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,CAAC,EAAE,YAAY;AACpE,UACE,WAAW,QACX,WAAW,QACX,WAAW,QACX,WAAW,MACX;AACA,aAAK,OAAO;AACZ,eAAO;AAAA,UACL,MAAM,EAAE,MAAM,iBAAiB,OAAO,IAAI;AAAA,UAC1C,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM,EAAE,MAAM,UAAU,OAAO,IAAI;AAAA,MACnC,MAAM,EAAE,OAAO,KAAK,KAAK,IAAI;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,UAAiB;AACvB,UAAM,QAAQ,KAAK;AACnB,WACE,KAAK,MAAM,KAAK,MAAM,WACrB,eAAe,KAAK,MAAM,KAAK,GAAG,CAAC,KAAK,KAAK,MAAM,KAAK,GAAG,MAAM,MAClE;AACA,WAAK;AAAA,IACP;AACA,UAAM,OAAO,KAAK,MAAM,MAAM,OAAO,KAAK,GAAG,EAAE,YAAY;AAC3D,UAAM,OAAO,EAAE,OAAO,KAAK,KAAK,IAAI;AAEpC,UAAM,OAAO,YAAY,IAAI;AAC7B,QAAI,SAAS,QAAW;AACtB,YAAM,UAAU,IAAI,oBAAoB,IAAI,KAAK,MAAM,KAAK,KAAK;AAAA,IACnE;AAEA,QAAI,KAAK,SAAS,MAAM;AACtB,WAAK,UAAU;AAAA,IACjB;AAEA,WAAO,EAAE,MAAM,KAAK;AAAA,EACtB;AACF;AAEA,IAAM,cAAyC;AAAA,EAC7C,OAAO,EAAE,MAAM,QAAQ;AAAA,EACvB,IAAI,EAAE,MAAM,KAAK;AAAA,EACjB,IAAI,EAAE,MAAM,KAAK;AAAA,EACjB,MAAM,EAAE,MAAM,OAAO;AAAA,EACrB,IAAI,EAAE,MAAM,KAAK;AAAA,EACjB,IAAI,EAAE,MAAM,KAAK;AAAA,EACjB,IAAI,EAAE,MAAM,KAAK;AAAA,EACjB,KAAK,EAAE,MAAM,MAAM;AAAA,EACnB,MAAM,EAAE,MAAM,OAAO;AAAA,EACrB,QAAQ,EAAE,MAAM,SAAS;AAAA,EACzB,OAAO,EAAE,MAAM,QAAQ;AAAA,EACvB,UAAU,EAAE,MAAM,WAAW;AAAA,EAC7B,QAAQ,EAAE,MAAM,SAAS;AAAA,EACzB,MAAM,EAAE,MAAM,OAAO;AAAA,EACrB,OAAO,EAAE,MAAM,OAAO;AAAA,EAEtB,KAAK,EAAE,MAAM,MAAM;AAAA,EACnB,MAAM,EAAE,MAAM,MAAM;AAAA,EACpB,SAAS,EAAE,MAAM,UAAU;AAAA,EAC3B,UAAU,EAAE,MAAM,UAAU;AAAA,EAC5B,SAAS,EAAE,MAAM,UAAU;AAAA,EAC3B,UAAU,EAAE,MAAM,UAAU;AAAA,EAC5B,OAAO,EAAE,MAAM,QAAQ;AAAA,EACvB,MAAM,EAAE,MAAM,QAAQ;AAAA,EACtB,OAAO,EAAE,MAAM,QAAQ;AAAA,EACvB,QAAQ,EAAE,MAAM,QAAQ;AAAA,EAExB,QAAQ,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EAC1C,KAAK,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EACvC,SAAS,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,EAC5C,KAAK,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,EACxC,WAAW,EAAE,MAAM,WAAW,MAAM,YAAY;AAAA,EAChD,KAAK,EAAE,MAAM,WAAW,MAAM,YAAY;AAAA,EAC1C,UAAU,EAAE,MAAM,WAAW,MAAM,WAAW;AAAA,EAC9C,KAAK,EAAE,MAAM,WAAW,MAAM,WAAW;AAAA,EACzC,QAAQ,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EAC1C,KAAK,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EACvC,UAAU,EAAE,MAAM,WAAW,MAAM,WAAW;AAAA,EAC9C,KAAK,EAAE,MAAM,WAAW,MAAM,WAAW;AAAA,EACzC,QAAQ,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EAC1C,KAAK,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EAEvC,SAAS,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAC1C,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,UAAU,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAC3C,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,OAAO,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACxC,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,OAAO,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACxC,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,MAAM,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACvC,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,MAAM,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACvC,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,QAAQ,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACzC,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,WAAW,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAC5C,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,SAAS,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAC1C,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,UAAU,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAC3C,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EACtC,UAAU,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAC3C,KAAK,EAAE,MAAM,aAAa,MAAM,MAAM;AAAA,EAEtC,OAAO,EAAE,MAAM,WAAW,MAAM,QAAQ;AAAA,EACxC,QAAQ,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EAC1C,OAAO,EAAE,MAAM,WAAW,MAAM,QAAQ;AAAA,EACxC,QAAQ,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,EAC1C,OAAO,EAAE,MAAM,WAAW,MAAM,QAAQ;AAAA,EAExC,KAAK,EAAE,MAAM,gBAAgB,MAAM,MAAM;AAAA,EACzC,MAAM,EAAE,MAAM,gBAAgB,MAAM,MAAM;AAAA,EAC1C,QAAQ,EAAE,MAAM,gBAAgB,MAAM,MAAM;AAAA,EAC5C,SAAS,EAAE,MAAM,gBAAgB,MAAM,MAAM;AAAA,EAC7C,MAAM,EAAE,MAAM,gBAAgB,MAAM,QAAQ;AAAA,EAC5C,OAAO,EAAE,MAAM,gBAAgB,MAAM,QAAQ;AAAA,EAC7C,IAAI,EAAE,MAAM,gBAAgB,MAAM,QAAQ;AAAA,EAC1C,KAAK,EAAE,MAAM,gBAAgB,MAAM,QAAQ;AAC7C;AAEA,SAAS,QAAQ,IAAqB;AACpC,SAAO,MAAM,OAAO,MAAM;AAC5B;AAEA,SAAS,QAAQ,IAAqB;AACpC,SAAQ,MAAM,OAAO,MAAM,OAAS,MAAM,OAAO,MAAM;AACzD;AAEA,SAAS,eAAe,IAAqB;AAC3C,SAAO,QAAQ,EAAE,KAAK,QAAQ,EAAE;AAClC;AAEA,SAAS,aAAa,IAAqB;AACzC,SAAO,OAAO,OAAO,OAAO,OAAQ,OAAO,QAAQ,OAAO;AAC5D;;;AC3TA,IAAM,SAAN,MAAa;AAAA,EACH;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAAiB,OAAe;AAC1C,SAAK,SAAS;AACd,SAAK,MAAM;AACX,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,OAA0B;AACxB,WAAO,KAAK,OAAO,KAAK,GAAG;AAAA,EAC7B;AAAA,EAEA,WAAkC;AAChC,WAAO,KAAK,OAAO,KAAK,GAAG,GAAG;AAAA,EAChC;AAAA,EAEA,UAA6B;AAC3B,UAAM,MAAM,KAAK,OAAO,KAAK,GAAG;AAChC,QAAI,IAAK,MAAK;AACd,WAAO;AAAA,EACT;AAAA,EAEA,cAAoB;AAClB,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,IAAK,QAAO,IAAI;AACpB,UAAM,OAAO,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC;AAC/C,QAAI,KAAM,QAAO,EAAE,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;AAC5D,WAAO,EAAE,OAAO,GAAG,KAAK,EAAE;AAAA,EAC5B;AAAA,EAEA,MAAM,SAAiB,MAAuB;AAC5C,WAAO,UAAU,MAAM,SAAS,MAAM,KAAK,KAAK;AAAA,EAClD;AAAA,EAEA,WAAW,SAA4B;AACrC,UAAM,OACJ,KAAK,OAAO,SAAS,IACjB;AAAA,MACE,OAAO,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,EAAE,KAAK;AAAA,MAChD,KAAK,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,EAAE,KAAK;AAAA,IAChD,IACA,EAAE,OAAO,GAAG,KAAK,EAAE;AACzB,WAAO,UAAU,MAAM,SAAS,MAAM,KAAK,KAAK;AAAA,EAClD;AAAA,EAEA,YAAY,UAAkB,OAAyC;AACrE,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,OAAO,MAAM,IAAI,IAAI,GAAG;AAC1B,WAAK;AACL,aAAO;AAAA,IACT;AACA,QAAI,KAAK;AACP,YAAM,KAAK,MAAM,YAAY,QAAQ,SAAS,IAAI,KAAK,IAAI,IAAI,IAAI;AAAA,IACrE;AACA,UAAM,KAAK,WAAW,YAAY,QAAQ,EAAE;AAAA,EAC9C;AAAA;AAAA,EAIA,kBAAgC;AAC9B,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,OAAO,KAAK,SAAS;AAE3B,QAAI;AACJ,QAAI,MAAM,SAAS,SAAS;AAC1B,WAAK,QAAQ;AACb,aAAO,KAAK,WAAW;AAAA,IACzB,WAAW,MAAM,SAAS,MAAM;AAC9B,WAAK,QAAQ;AACb,aAAO,KAAK,QAAQ;AAAA,IACtB,WAAW,MAAM,SAAS,aAAa,MAAM,SAAS,QAAQ;AAC5D,aAAO,KAAK,mBAAmB;AAAA,IACjC,OAAO;AACL,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,qBAAqB,IAAI;AAAA,EACvC;AAAA,EAEQ,qBAAqB,MAAkC;AAC7D,UAAM,WAAW,gBAAgB,IAAI;AAGrC,QAAI,KAAK,SAAS,GAAG,SAAS,UAAU;AACtC,WAAK,QAAQ;AACb,eAAS,SAAS,KAAK,mBAAmB;AAAA,IAC5C;AAGA,QAAI,KAAK,SAAS,GAAG,SAAS,SAAS;AACrC,WAAK,QAAQ;AACb,eAAS,QAAQ,KAAK,eAAe;AAAA,IACvC;AAGA,QAAI,KAAK,SAAS,GAAG,SAAS,YAAY;AACxC,WAAK,QAAQ;AACb,YAAM,IAAI,KAAK,SAAS;AACxB,UAAI,GAAG,SAAS,WAAW;AACzB,iBAAS,SAAU,EAAwC;AAC3D,aAAK,QAAQ;AAAA,MACf,OAAO;AACL,cAAM,KAAK;AAAA,UACT;AAAA,UACA,KAAK,YAAY;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,SAAS,GAAG,SAAS,UAAU;AACtC,WAAK,QAAQ;AACb,eAAS,SAAS,KAAK,eAAe;AAAA,IACxC;AAGA,QAAI,KAAK,SAAS,GAAG,SAAS,MAAM;AAClC,WAAK,QAAQ;AACb,YAAM,IAAI,KAAK,SAAS;AACxB,UAAI,GAAG,SAAS,YAAY;AAC1B,iBAAS,WAAY,EAAuC;AAC5D,aAAK,QAAQ;AAAA,MACf,OAAO;AACL,cAAM,KAAK,MAAM,gCAAgC,KAAK,YAAY,CAAC;AAAA,MACrE;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,qBAAkC;AACxC,UAAM,aAA0B,CAAC,KAAK,eAAe,CAAC;AACtD,WAAO,KAAK,SAAS,GAAG,SAAS,SAAS;AACxC,WAAK,QAAQ;AACb,iBAAW,KAAK,KAAK,eAAe,CAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAA4B;AAClC,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,OAAQ,EAAwC;AACtD,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,OAAO,KAAK;AAAA,IAC7B;AACA,QAAI,GAAG,SAAS,aAAa;AAC3B,YAAM,QAAQ;AAAA,QACX,EAA0C;AAAA,MAC7C;AACA,WAAK,QAAQ;AACb,YAAM,MAAM,KAAK;AAAA,QACf;AAAA,MACF;AACA,aAAO,EAAE,MAAM,SAAS,OAAO,IAAI;AAAA,IACrC;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,iBAA4B;AAClC,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,OAAQ,EAAwC;AACtD,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,OAAO,KAAK;AAAA,IAC7B;AACA,QAAI,GAAG,SAAS,aAAa;AAC3B,YAAM,QAAQ;AAAA,QACX,EAA0C;AAAA,MAC7C;AACA,WAAK,QAAQ;AACb,YAAM,MAAM,KAAK;AAAA,QACf;AAAA,MACF;AACA,aAAO,EAAE,MAAM,SAAS,OAAO,IAAI;AAAA,IACrC;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,eAAe,UAA0B;AAC/C,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,UAAU;AACxB,YAAM,IAAK,EAAwC;AACnD,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AACA,QAAI,GAAG,SAAS,iBAAiB;AAC/B,YAAM,IAAK,EAA+C;AAC1D,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AACA,UAAM,KAAK,MAAM,UAAU,KAAK,YAAY,CAAC;AAAA,EAC/C;AAAA;AAAA,EAGQ,aAA2B;AACjC,QAAI,CAAC,KAAK,KAAK,EAAG,OAAM,KAAK,WAAW,mBAAmB;AAE3D,UAAM,IAAI,KAAK,SAAS;AAExB,QAAI,EAAE,SAAS,QAAQ;AACrB,WAAK,QAAQ;AACb,aAAO,KAAK,gBAAgB,CAAC;AAAA,IAC/B;AACA,QAAI,EAAE,SAAS,OAAO;AACpB,aAAO,KAAK,eAAe,GAAG,EAAE,MAAM,QAAQ,CAAC;AAAA,IACjD;AACA,QAAI,EAAE,SAAS,WAAW;AACxB,WAAK,QAAQ;AACb,aAAO,KAAK,eAAe,GAAG,EAAE,MAAM,UAAU,CAAC;AAAA,IACnD;AACA,QAAI,EAAE,SAAS,WAAW;AACxB,WAAK,QAAQ;AACb,aAAO,KAAK,eAAe,GAAG,EAAE,MAAM,UAAU,CAAC;AAAA,IACnD;AACA,QAAI,EAAE,SAAS,WAAW;AACxB,YAAM,OAAO,KAAK,aAAa;AAC/B,aAAO,KAAK,eAAe,GAAG,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,IACtD;AACA,QAAI,EAAE,SAAS,SAAS;AACtB,WAAK,QAAQ;AACb,aAAO,KAAK,iBAAiB,CAAC;AAAA,IAChC;AACA,QAAI,EAAE,SAAS,UAAU;AACvB,aAAO,KAAK,kBAAkB;AAAA,IAChC;AAEA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,eAAe,UAAkB,MAA+B;AACtE,QAAI,KAAK,SAAS,SAAS;AACzB,WAAK,YAAY,SAAS,CAAC,MAAM,EAAE,SAAS,KAAK;AAAA,IACnD;AACA,SAAK,YAAY,QAAQ,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,UAAM,QAAQ,KAAK,cAAc;AACjC,WAAO,EAAE,MAAM,aAAa,UAAU,MAAM,MAAM;AAAA,EACpD;AAAA,EAEQ,oBAAkC;AACxC,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,IAAI,KAAK,SAAS;AACxB,UAAM,MAAO,EAAwC;AACrD,QAAI,QAAQ,GAAG;AACb,YAAM,KAAK,MAAM,+BAA+B,IAAI;AAAA,IACtD;AACA,SAAK,QAAQ;AAEb,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,MAAM,SAAS,SAAS;AAC1B,WAAK,QAAQ;AACb,aAAO,KAAK,gBAAgB,GAAG;AAAA,IACjC;AACA,QAAI,MAAM,SAAS,gBAAgB;AACjC,aAAO,KAAK,oBAAoB,GAAG;AAAA,IACrC;AACA,QAAI,MAAM,SAAS,OAAO;AACxB,aAAO,KAAK,eAAe,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,IACnD;AACA,QAAI,MAAM,SAAS,SAAS;AAC1B,WAAK,QAAQ;AACb,aAAO,KAAK,iBAAiB,GAAG;AAAA,IAClC;AACA,QAAI,MAAM,SAAS,QAAQ;AACzB,WAAK,QAAQ;AACb,aAAO,KAAK,gBAAgB,GAAG;AAAA,IACjC;AAEA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,oBAAoB,UAAgC;AAC1D,UAAM,IAAI,KAAK,SAAS;AACxB,UAAM,UAAW,EAA6C;AAC9D,SAAK,QAAQ;AAEb,UAAM,OAAqB,YAAY,QAAQ,QAAQ;AAEvD,SAAK,YAAY,UAAU,CAACC,OAAMA,GAAE,SAAS,MAAM;AACnD,UAAM,OAAO,KAAK,UAAU;AAC5B,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,UAAM,KAAK,KAAK,UAAU;AAE1B,QAAI,YAA8B;AAClC,QAAI,KAAK,SAAS,GAAG,SAAS,MAAM;AAClC,WAAK,QAAQ;AACb,kBAAY,KAAK,eAAe;AAAA,IAClC;AAEA,WAAO,EAAE,MAAM,kBAAkB,UAAU,MAAM,MAAM,IAAI,UAAU;AAAA,EACvE;AAAA,EAEQ,gBAAgB,UAAgC;AACtD,SAAK,YAAY,QAAQ,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,UAAM,OAAO,KAAK,aAAa;AAC/B,SAAK,YAAY,QAAQ,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,UAAM,QAAQ,KAAK,cAAc;AACjC,WAAO,EAAE,MAAM,cAAc,UAAU,MAAM,MAAM;AAAA,EACrD;AAAA,EAEQ,iBAAiB,UAAgC;AACvD,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,SAAK,YAAY,SAAS,CAACA,OAAMA,GAAE,SAAS,KAAK;AAEjD,QAAI;AACJ,UAAM,IAAI,KAAK,SAAS;AAExB,QAAI,GAAG,SAAS,QAAQ;AACtB,WAAK,QAAQ;AACb,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,MAAM,SAAS,OAAO;AACxB,aAAK,QAAQ;AACb,iBAAS,EAAE,MAAM,UAAU;AAAA,MAC7B,WAAW,MAAM,SAAS,WAAW;AACnC,aAAK,QAAQ;AACb,iBAAS,EAAE,MAAM,cAAc;AAAA,MACjC,OAAO;AACL,cAAM,KAAK;AAAA,UACT;AAAA,UACA,KAAK,YAAY;AAAA,QACnB;AAAA,MACF;AAAA,IACF,WAAW,GAAG,SAAS,iBAAiB;AACtC,YAAM,QAAQ,KAAK,oBAAoB;AACvC,eAAS,EAAE,MAAM,QAAQ,MAAM;AAAA,IACjC,OAAO;AACL,YAAM,KAAK;AAAA,QACT;AAAA,QACA,KAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAEA,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,UAAM,QAAQ,KAAK,cAAc;AACjC,WAAO,EAAE,MAAM,eAAe,UAAU,QAAQ,MAAM;AAAA,EACxD;AAAA,EAEQ,qBAAmC;AACzC,UAAM,UAAU,KAAK,qBAAqB;AAE1C,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,KAAK,MAAM,mCAAmC,KAAK,YAAY,CAAC;AAAA,IACxE;AACA,UAAM,MAAM;AAAA,MACT,EAAwC;AAAA,IAC3C;AACA,SAAK,QAAQ;AAEb,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,SAAK,YAAY,WAAW,CAACA,OAAMA,GAAE,SAAS,OAAO;AAGrD,QAAI,WAAW;AACf,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,MAAM,SAAS,UAAU;AAC3B,iBAAY,KAA2C;AACvD,UAAI,aAAa,GAAG;AAClB,cAAM,KAAK,MAAM,+BAA+B,KAAK,YAAY,CAAC;AAAA,MACpE;AACA,WAAK,QAAQ;AAAA,IACf;AAEA,SAAK,YAAY,WAAW,CAACA,OAAMA,GAAE,SAAS,OAAO;AACrD,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,UAAM,QAAQ,KAAK,cAAc;AAEjC,WAAO,EAAE,MAAM,iBAAiB,UAAU,SAAS,KAAK,MAAM;AAAA,EAChE;AAAA,EAEQ,gBAAgB,UAAgC;AACtD,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAE/C,QAAI;AACJ,UAAM,IAAI,KAAK,SAAS;AAExB,QAAI,GAAG,SAAS,OAAO;AACrB,WAAK,QAAQ;AACb,eAAS,KAAK,wBAAwB;AAAA,IACxC,WAAW,GAAG,SAAS,aAAa;AAClC,YAAM,QAAQ;AAAA,QACX,EAA0C;AAAA,MAC7C;AACA,WAAK,QAAQ;AACb,YAAM,MAAM,KAAK,eAAe,sCAAsC;AACtE,eAAS,EAAE,MAAM,QAAQ,OAAO,IAAI;AAAA,IACtC,OAAO;AACL,YAAM,KAAK;AAAA,QACT;AAAA,QACA,KAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAEA,SAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,UAAM,QAAQ,KAAK,cAAc;AACjC,WAAO,EAAE,MAAM,cAAc,UAAU,QAAQ,MAAM;AAAA,EACvD;AAAA,EAEQ,0BAAsC;AAC5C,UAAM,IAAI,KAAK,SAAS;AAExB,QAAI,GAAG,SAAS,QAAQ;AACtB,WAAK,QAAQ;AACb,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,MAAM,SAAS,WAAW;AAC5B,aAAK,QAAQ;AACb,aAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,cAAM,QAAQ,KAAK,oBAAoB;AACvC,eAAO,EAAE,MAAM,eAAe,MAAM;AAAA,MACtC;AACA,UAAI,MAAM,SAAS,WAAW;AAC5B,cAAM,UAAU;AAAA,UACb,KAA2C;AAAA,QAC9C;AACA,aAAK,QAAQ;AACb,aAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,cAAM,QAAQ,KAAK,oBAAoB;AACvC,eAAO,EAAE,MAAM,kBAAkB,SAAS,QAAQ,SAAS,MAAM;AAAA,MACnE;AACA,YAAM,KAAK;AAAA,QACT;AAAA,QACA,KAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,UAAU,KAAK,qBAAqB;AAC1C,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,MAAM,SAAS,WAAW;AAC5B,cAAM,UAAU;AAAA,UACb,KAA2C;AAAA,QAC9C;AACA,aAAK,QAAQ;AACb,aAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,cAAM,QAAQ,KAAK,oBAAoB;AACvC,eAAO,EAAE,MAAM,kBAAkB,SAAS,SAAS,MAAM;AAAA,MAC3D;AACA,YAAM,KAAK;AAAA,QACT;AAAA,QACA,KAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,GAAG,SAAS,iBAAiB;AAC/B,YAAM,MAAO,EAA+C;AAC5D,WAAK,QAAQ;AACb,WAAK,YAAY,QAAQ,CAACA,OAAMA,GAAE,SAAS,IAAI;AAC/C,YAAM,QAAQ,KAAK,oBAAoB;AACvC,aAAO,EAAE,MAAM,cAAc,KAAK,MAAM;AAAA,IAC1C;AAEA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,sBAAiC;AACvC,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,aAAa;AAC3B,YAAM,QAAQ;AAAA,QACX,EAA0C;AAAA,MAC7C;AACA,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AACA,UAAM,KAAK,MAAM,uBAAuB,KAAK,YAAY,CAAC;AAAA,EAC5D;AAAA,EAEQ,uBAAwC;AAC9C,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,IAAI,KAAK,SAAS;AAExB,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,OAAQ,EAAwC;AACtD,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AACA,QAAI,GAAG,SAAS,QAAQ;AACtB,WAAK,QAAQ;AACb,aAAO;AAAA,IACT;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAwB;AAC9B,UAAM,OAAO,KAAK,gBAAgB;AAClC,SAAK,YAAY,QAAQ,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,UAAM,QAAQ,KAAK,cAAc;AACjC,WAAO,EAAE,MAAM,cAAc,MAAM,MAAM;AAAA,EAC3C;AAAA,EAEQ,kBAA4B;AAClC,UAAM,IAAI,KAAK,SAAS;AAExB,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,OAAQ,EAAwC;AACtD,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,OAAO,KAAK;AAAA,IAC7B;AACA,QAAI,GAAG,SAAS,aAAa;AAC3B,YAAM,QAAQ;AAAA,QACX,EAA0C;AAAA,MAC7C;AACA,WAAK,QAAQ;AACb,YAAM,MAAM,KAAK,eAAe,sCAAsC;AACtE,aAAO,EAAE,MAAM,SAAS,OAAO,IAAI;AAAA,IACrC;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,iBAA4B;AAClC,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,OAAO;AACrB,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,QAAQ;AAAA,IACzB;AACA,QAAI,GAAG,SAAS,WAAW;AACzB,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AACA,QAAI,GAAG,SAAS,WAAW;AACzB,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B;AACA,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,OAAO,KAAK,aAAa;AAC/B,aAAO,EAAE,MAAM,QAAQ,KAAK;AAAA,IAC9B;AACA,UAAM,KAAK;AAAA,MACT;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,eAA0B;AAChC,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,WAAW;AACzB,YAAM,KAAK,MAAM,qBAAqB,KAAK,YAAY,CAAC;AAAA,IAC1D;AACA,UAAM,OAAkB;AAAA,MACtB,aAAc,EAAwC,IAAI;AAAA,IAC5D;AACA,SAAK,QAAQ;AAEb,WAAO,KAAK,SAAS,GAAG,SAAS,SAAS;AACxC,WAAK,QAAQ;AACb,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,MAAM,SAAS,WAAW;AAC5B,cAAM,KAAK,MAAM,+BAA+B,KAAK,YAAY,CAAC;AAAA,MACpE;AACA,WAAK;AAAA,QACH;AAAA,UACG,KAA2C;AAAA,QAC9C;AAAA,MACF;AACA,WAAK,QAAQ;AAAA,IACf;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAwC;AAC9C,UAAM,QAA0B,CAAC,KAAK,oBAAoB,CAAC;AAC3D,WAAO,KAAK,SAAS,GAAG,SAAS,SAAS;AACxC,WAAK,QAAQ;AACb,YAAM,KAAK,KAAK,oBAAoB,CAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsC;AAC5C,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,iBAAiB;AAC/B,YAAM,KAAK,MAAM,+BAA+B,KAAK,YAAY,CAAC;AAAA,IACpE;AACA,UAAM,QAAS,EAA+C;AAC9D,SAAK,QAAQ;AAEb,QAAI,KAAK,SAAS,GAAG,SAAS,MAAM;AAClC,WAAK,QAAQ;AACb,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,MAAM,SAAS,iBAAiB;AAClC,cAAM,KAAK;AAAA,UACT;AAAA,UACA,KAAK,YAAY;AAAA,QACnB;AAAA,MACF;AACA,YAAM,MAAO,KAAkD;AAC/D,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,SAAS,OAAO,IAAI;AAAA,IACrC;AAEA,WAAO,EAAE,MAAM,UAAU,KAAK,MAAM;AAAA,EACtC;AAAA,EAEQ,iBAA8B;AACpC,UAAM,SAAsB,CAAC,KAAK,oBAAoB,CAAC;AACvD,WAAO,KAAK,SAAS,GAAG,SAAS,SAAS;AACxC,WAAK,QAAQ;AACb,aAAO,KAAK,KAAK,oBAAoB,CAAC;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,gBAA6B;AACnC,UAAM,QAAqB,CAAC,KAAK,UAAU,CAAC;AAC5C,WAAO,KAAK,SAAS,GAAG,SAAS,SAAS;AACxC,WAAK,QAAQ;AACb,YAAM,KAAK,KAAK,UAAU,CAAC;AAAA,IAC7B;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,YAAuB;AAC7B,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,IAAI,KAAK,SAAS;AACxB,QAAI,GAAG,SAAS,QAAQ;AACtB,YAAM,EAAE,MAAM,OAAO,IAAI;AAKzB,WAAK,QAAQ;AACb,aAAO,EAAE,MAAM,OAAO;AAAA,IACxB;AACA,UAAM,KAAK,MAAM,yBAAyB,IAAI;AAAA,EAChD;AACF;AAGO,SAAS,MAAM,OAA6B;AACjD,QAAM,SAAS,SAAS,KAAK;AAE7B,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,UAAU,MAAM,oBAAoB,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,KAAK;AAAA,EACvE;AAEA,QAAM,SAAS,IAAI,OAAO,QAAQ,KAAK;AACvC,QAAM,WAAW,OAAO,gBAAgB;AAExC,MAAI,OAAO,KAAK,GAAG;AACjB,UAAM,UAAU;AAAA,MACd;AAAA,MACA,OAAO,YAAY;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;APhnBA,IAAAC,mBAAyB;AA/DlB,IAAM,WAAN,MAAM,UAAS;AAAA,EACZ;AAAA,EAEA,YAAY,MAAoB;AACtC,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,OAAO,MAAM,OAAyB;AACpC,WAAO,IAAI,UAAS,MAAM,KAAK,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,OAAO,SAAS,UAA4B;AAC1C,WAAO,IAAI,UAAS,SAAS,QAAQ,CAAC;AAAA,EACxC;AAAA;AAAA,EAGA,OAAO,SAAS,OAAwB;AACtC,QAAI;AACF,YAAM,KAAK;AACX,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,SAAS,KAA4D;AACnE,WAAO,SAAS,KAAK,MAAM,GAAG;AAAA,EAChC;AAAA;AAAA,EAGA,UAAU,KAA6B,GAAqC;AAC1E,WAAO,UAAU,KAAK,MAAM,KAAK,CAAC;AAAA,EACpC;AAAA;AAAA,EAGA,QAAQ,UAA2C;AACjD,WAAO,QAAQ,KAAK,MAAM,QAAQ;AAAA,EACpC;AAAA;AAAA,EAGA,SAAiB;AACf,WAAO,OAAO,KAAK,IAAI;AAAA,EACzB;AAAA;AAAA,EAGA,WAAmB;AACjB,WAAO,QAAQ,KAAK,IAAI;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,WAA0B;AAC5B,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA,EAGA,IAAI,aAA2B;AAC7B,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;","names":["expr","k","import_polyfill"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/ast.ts","../src/error.ts","../src/cron.ts","../src/display.ts","../src/eval.ts","../src/lexer.ts","../src/parser.ts"],"sourcesContent":["// hron-js — Public API\n\nimport type { Temporal } from \"@js-temporal/polyfill\";\nimport type { ScheduleData, ScheduleExpr } from \"./ast.js\";\nimport { fromCron, toCron } from \"./cron.js\";\nimport { display } from \"./display.js\";\nimport {\n between,\n matches,\n nextFrom,\n nextNFrom,\n occurrences,\n previousFrom,\n} from \"./eval.js\";\nimport { parse } from \"./parser.js\";\n\nexport class Schedule {\n private data: ScheduleData;\n\n private constructor(data: ScheduleData) {\n this.data = data;\n }\n\n /** Parse an hron expression string. */\n static parse(input: string): Schedule {\n return new Schedule(parse(input));\n }\n\n /** Convert a 5-field cron expression to a Schedule. */\n static fromCron(cronExpr: string): Schedule {\n return new Schedule(fromCron(cronExpr));\n }\n\n /** Check if an input string is a valid hron expression. */\n static validate(input: string): boolean {\n try {\n parse(input);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Compute the next occurrence after `now`. */\n nextFrom(now: Temporal.ZonedDateTime): Temporal.ZonedDateTime | null {\n return nextFrom(this.data, now);\n }\n\n /** Compute the next `n` occurrences after `now`. */\n nextNFrom(now: Temporal.ZonedDateTime, n: number): Temporal.ZonedDateTime[] {\n return nextNFrom(this.data, now, n);\n }\n\n /** Compute the most recent occurrence strictly before `now`. */\n previousFrom(now: Temporal.ZonedDateTime): Temporal.ZonedDateTime | null {\n return previousFrom(this.data, now);\n }\n\n /** Check if a datetime matches this schedule. */\n matches(datetime: Temporal.ZonedDateTime): boolean {\n return matches(this.data, datetime);\n }\n\n /**\n * Returns a lazy iterator of occurrences starting after `from`.\n * The iterator is unbounded for repeating schedules (will iterate forever unless limited),\n * but respects the `until` clause if specified in the schedule.\n */\n *occurrences(\n from: Temporal.ZonedDateTime,\n ): Generator<Temporal.ZonedDateTime, void, unknown> {\n yield* occurrences(this.data, from);\n }\n\n /**\n * Returns a bounded iterator of occurrences where `from < occurrence <= to`.\n * The iterator yields occurrences strictly after `from` and up to and including `to`.\n */\n *between(\n from: Temporal.ZonedDateTime,\n to: Temporal.ZonedDateTime,\n ): Generator<Temporal.ZonedDateTime, void, unknown> {\n yield* between(this.data, from, to);\n }\n\n /** Convert this schedule to a 5-field cron expression. */\n toCron(): string {\n return toCron(this.data);\n }\n\n /** Render as canonical string (roundtrip-safe). */\n toString(): string {\n return display(this.data);\n }\n\n /** Get the timezone, if specified. */\n get timezone(): string | null {\n return this.data.timezone;\n }\n\n /** Get the underlying schedule expression. */\n get expression(): ScheduleExpr {\n return this.data.expr;\n }\n}\n\nexport { Temporal } from \"@js-temporal/polyfill\";\nexport type {\n DateSpec,\n DayFilter,\n DayOfMonthSpec,\n Exception,\n IntervalUnit,\n MonthName,\n MonthTarget,\n OrdinalPosition,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n UntilSpec,\n Weekday,\n YearTarget,\n} from \"./ast.js\";\nexport type { HronErrorKind, Span } from \"./error.js\";\n// Re-exports\nexport { HronError } from \"./error.js\";\n","// AST types for hron — TypeScript discriminated unions mirroring Rust enums.\n\nexport type Weekday =\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\"\n | \"sunday\";\n\nexport type MonthName =\n | \"jan\"\n | \"feb\"\n | \"mar\"\n | \"apr\"\n | \"may\"\n | \"jun\"\n | \"jul\"\n | \"aug\"\n | \"sep\"\n | \"oct\"\n | \"nov\"\n | \"dec\";\n\nexport type IntervalUnit = \"min\" | \"hours\";\n\nexport type OrdinalPosition =\n | \"first\"\n | \"second\"\n | \"third\"\n | \"fourth\"\n | \"fifth\"\n | \"last\";\n\nexport interface TimeOfDay {\n hour: number;\n minute: number;\n}\n\n// --- Day filter ---\n\nexport type DayFilter =\n | { type: \"every\" }\n | { type: \"weekday\" }\n | { type: \"weekend\" }\n | { type: \"days\"; days: Weekday[] };\n\n// --- Day of month spec ---\n\nexport type DayOfMonthSpec =\n | { type: \"single\"; day: number }\n | { type: \"range\"; start: number; end: number };\n\n// --- Nearest direction ---\n\nexport type NearestDirection = \"next\" | \"previous\";\n\n// --- Month target ---\n\nexport type MonthTarget =\n | { type: \"days\"; specs: DayOfMonthSpec[] }\n | { type: \"lastDay\" }\n | { type: \"lastWeekday\" }\n | { type: \"nearestWeekday\"; day: number; direction: NearestDirection | null }\n | { type: \"ordinalWeekday\"; ordinal: OrdinalPosition; weekday: Weekday };\n\n// --- Year target ---\n\nexport type YearTarget =\n | { type: \"date\"; month: MonthName; day: number }\n | {\n type: \"ordinalWeekday\";\n ordinal: OrdinalPosition;\n weekday: Weekday;\n month: MonthName;\n }\n | { type: \"dayOfMonth\"; day: number; month: MonthName }\n | { type: \"lastWeekday\"; month: MonthName };\n\n// --- Date spec ---\n\nexport type DateSpec =\n | { type: \"named\"; month: MonthName; day: number }\n | { type: \"iso\"; date: string };\n\n// --- Exception ---\n\nexport type Exception =\n | { type: \"named\"; month: MonthName; day: number }\n | { type: \"iso\"; date: string };\n\n// --- Until spec ---\n\nexport type UntilSpec =\n | { type: \"iso\"; date: string }\n | { type: \"named\"; month: MonthName; day: number };\n\n// --- Schedule expression ---\n\nexport type ScheduleExpr =\n | {\n type: \"intervalRepeat\";\n interval: number;\n unit: IntervalUnit;\n from: TimeOfDay;\n to: TimeOfDay;\n dayFilter: DayFilter | null;\n }\n | { type: \"dayRepeat\"; interval: number; days: DayFilter; times: TimeOfDay[] }\n | {\n type: \"weekRepeat\";\n interval: number;\n days: Weekday[];\n times: TimeOfDay[];\n }\n | {\n type: \"monthRepeat\";\n interval: number;\n target: MonthTarget;\n times: TimeOfDay[];\n }\n | { type: \"singleDate\"; date: DateSpec; times: TimeOfDay[] }\n | {\n type: \"yearRepeat\";\n interval: number;\n target: YearTarget;\n times: TimeOfDay[];\n };\n\n// --- Schedule (top-level) ---\n\nexport interface ScheduleData {\n expr: ScheduleExpr;\n timezone: string | null;\n except: Exception[];\n until: UntilSpec | null;\n anchor: string | null; // ISO date string (YYYY-MM-DD)\n during: MonthName[];\n}\n\n// --- Helper functions ---\n\n/** ISO 8601 day number: Monday=1, Sunday=7. */\nexport function weekdayNumber(day: Weekday): number {\n const map: Record<Weekday, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n };\n return map[day];\n}\n\n/** Cron DOW number: Sunday=0, Monday=1, ..., Saturday=6. */\nexport function cronDowNumber(day: Weekday): number {\n const map: Record<Weekday, number> = {\n sunday: 0,\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n };\n return map[day];\n}\n\nexport function weekdayFromNumber(n: number): Weekday | null {\n const map: Record<number, Weekday> = {\n 1: \"monday\",\n 2: \"tuesday\",\n 3: \"wednesday\",\n 4: \"thursday\",\n 5: \"friday\",\n 6: \"saturday\",\n 7: \"sunday\",\n };\n return map[n] ?? null;\n}\n\nexport function monthNumber(month: MonthName): number {\n const map: Record<MonthName, number> = {\n jan: 1,\n feb: 2,\n mar: 3,\n apr: 4,\n may: 5,\n jun: 6,\n jul: 7,\n aug: 8,\n sep: 9,\n oct: 10,\n nov: 11,\n dec: 12,\n };\n return map[month];\n}\n\nexport function parseWeekday(s: string): Weekday | null {\n const map: Record<string, Weekday> = {\n monday: \"monday\",\n mon: \"monday\",\n tuesday: \"tuesday\",\n tue: \"tuesday\",\n wednesday: \"wednesday\",\n wed: \"wednesday\",\n thursday: \"thursday\",\n thu: \"thursday\",\n friday: \"friday\",\n fri: \"friday\",\n saturday: \"saturday\",\n sat: \"saturday\",\n sunday: \"sunday\",\n sun: \"sunday\",\n };\n return map[s.toLowerCase()] ?? null;\n}\n\nexport function parseMonthName(s: string): MonthName | null {\n const map: Record<string, MonthName> = {\n january: \"jan\",\n jan: \"jan\",\n february: \"feb\",\n feb: \"feb\",\n march: \"mar\",\n mar: \"mar\",\n april: \"apr\",\n apr: \"apr\",\n may: \"may\",\n june: \"jun\",\n jun: \"jun\",\n july: \"jul\",\n jul: \"jul\",\n august: \"aug\",\n aug: \"aug\",\n september: \"sep\",\n sep: \"sep\",\n october: \"oct\",\n oct: \"oct\",\n november: \"nov\",\n nov: \"nov\",\n december: \"dec\",\n dec: \"dec\",\n };\n return map[s.toLowerCase()] ?? null;\n}\n\nexport function expandDaySpec(spec: DayOfMonthSpec): number[] {\n if (spec.type === \"single\") {\n return [spec.day];\n }\n const result: number[] = [];\n for (let d = spec.start; d <= spec.end; d++) {\n result.push(d);\n }\n return result;\n}\n\nexport function expandMonthTarget(target: MonthTarget): number[] {\n if (target.type === \"days\") {\n return target.specs.flatMap(expandDaySpec);\n }\n return [];\n}\n\nexport function ordinalToN(ord: OrdinalPosition): number {\n const map: Record<string, number> = {\n first: 1,\n second: 2,\n third: 3,\n fourth: 4,\n fifth: 5,\n };\n return map[ord];\n}\n\nexport const ALL_WEEKDAYS: Weekday[] = [\n \"monday\",\n \"tuesday\",\n \"wednesday\",\n \"thursday\",\n \"friday\",\n];\n\nexport const ALL_WEEKEND: Weekday[] = [\"saturday\", \"sunday\"];\n\nexport function newScheduleData(expr: ScheduleExpr): ScheduleData {\n return {\n expr,\n timezone: null,\n except: [],\n until: null,\n anchor: null,\n during: [],\n };\n}\n","/** Byte range within the input string. */\nexport interface Span {\n start: number;\n end: number;\n}\n\nexport type HronErrorKind = \"lex\" | \"parse\" | \"eval\" | \"cron\";\n\n/** All errors produced by hron. */\nexport class HronError extends Error {\n readonly kind: HronErrorKind;\n readonly span?: Span;\n readonly input?: string;\n readonly suggestion?: string;\n\n constructor(\n kind: HronErrorKind,\n message: string,\n span?: Span,\n input?: string,\n suggestion?: string,\n ) {\n super(message);\n this.name = \"HronError\";\n this.kind = kind;\n this.span = span;\n this.input = input;\n this.suggestion = suggestion;\n }\n\n static lex(message: string, span: Span, input: string): HronError {\n return new HronError(\"lex\", message, span, input);\n }\n\n static parse(\n message: string,\n span: Span,\n input: string,\n suggestion?: string,\n ): HronError {\n return new HronError(\"parse\", message, span, input, suggestion);\n }\n\n static eval(message: string): HronError {\n return new HronError(\"eval\", message);\n }\n\n static cron(message: string): HronError {\n return new HronError(\"cron\", message);\n }\n\n displayRich(): string {\n if (\n (this.kind === \"lex\" || this.kind === \"parse\") &&\n this.span &&\n this.input\n ) {\n let out = `error: ${this.message}\\n`;\n out += ` ${this.input}\\n`;\n const padding = \" \".repeat(this.span.start + 2);\n const underline = \"^\".repeat(\n Math.max(this.span.end - this.span.start, 1),\n );\n out += padding + underline;\n if (this.suggestion) {\n out += ` try: \"${this.suggestion}\"`;\n }\n return out;\n }\n return `error: ${this.message}`;\n }\n}\n","// Cron conversion — to_cron / from_cron for hron schedules.\n\nimport type {\n DayFilter,\n DayOfMonthSpec,\n MonthName,\n MonthTarget,\n OrdinalPosition,\n ScheduleData,\n TimeOfDay,\n Weekday,\n} from \"./ast.js\";\nimport {\n ALL_WEEKDAYS,\n ALL_WEEKEND,\n cronDowNumber,\n monthNumber,\n newScheduleData,\n parseMonthName,\n weekdayNumber,\n} from \"./ast.js\";\nimport { HronError } from \"./error.js\";\n\n/** Convert a Schedule to a 5-field cron expression. */\nexport function toCron(schedule: ScheduleData): string {\n if (schedule.except.length > 0) {\n throw HronError.cron(\n \"not expressible as cron (except clauses not supported)\",\n );\n }\n if (schedule.until) {\n throw HronError.cron(\n \"not expressible as cron (until clauses not supported)\",\n );\n }\n if (schedule.during.length > 0) {\n throw HronError.cron(\n \"not expressible as cron (during clauses not supported)\",\n );\n }\n\n const expr = schedule.expr;\n\n switch (expr.type) {\n case \"dayRepeat\": {\n if (expr.interval > 1) {\n throw HronError.cron(\n \"not expressible as cron (multi-day intervals not supported)\",\n );\n }\n if (expr.times.length !== 1) {\n throw HronError.cron(\n \"not expressible as cron (multiple times not supported)\",\n );\n }\n const time = expr.times[0];\n const dow = dayFilterToCronDow(expr.days);\n return `${time.minute} ${time.hour} * * ${dow}`;\n }\n\n case \"intervalRepeat\": {\n const fullDay =\n expr.from.hour === 0 &&\n expr.from.minute === 0 &&\n expr.to.hour === 23 &&\n expr.to.minute === 59;\n if (!fullDay) {\n throw HronError.cron(\n \"not expressible as cron (partial-day interval windows not supported)\",\n );\n }\n if (expr.dayFilter) {\n throw HronError.cron(\n \"not expressible as cron (interval with day filter not supported)\",\n );\n }\n\n if (expr.unit === \"min\") {\n if (60 % expr.interval !== 0) {\n throw HronError.cron(\n `not expressible as cron (*/${expr.interval} breaks at hour boundaries)`,\n );\n }\n return `*/${expr.interval} * * * *`;\n }\n // hours\n return `0 */${expr.interval} * * *`;\n }\n\n case \"weekRepeat\":\n throw HronError.cron(\n \"not expressible as cron (multi-week intervals not supported)\",\n );\n\n case \"monthRepeat\": {\n if (expr.interval > 1) {\n throw HronError.cron(\n \"not expressible as cron (multi-month intervals not supported)\",\n );\n }\n if (expr.times.length !== 1) {\n throw HronError.cron(\n \"not expressible as cron (multiple times not supported)\",\n );\n }\n const time = expr.times[0];\n const { target } = expr;\n if (target.type === \"days\") {\n const expanded = target.specs.flatMap((s) => {\n if (s.type === \"single\") return [s.day];\n const r: number[] = [];\n for (let d = s.start; d <= s.end; d++) r.push(d);\n return r;\n });\n const dom = expanded.join(\",\");\n return `${time.minute} ${time.hour} ${dom} * *`;\n }\n if (target.type === \"lastDay\") {\n throw HronError.cron(\n \"not expressible as cron (last day of month not supported)\",\n );\n }\n if (target.type === \"lastWeekday\") {\n throw HronError.cron(\n \"not expressible as cron (last weekday of month not supported)\",\n );\n }\n if (target.type === \"ordinalWeekday\") {\n throw HronError.cron(\n \"not expressible as cron (ordinal weekday of month not supported)\",\n );\n }\n // nearestWeekday\n if (target.direction !== null) {\n throw HronError.cron(\n \"not expressible as cron (directional nearest weekday not supported)\",\n );\n }\n return `${time.minute} ${time.hour} ${target.day}W * *`;\n }\n\n case \"singleDate\":\n throw HronError.cron(\n \"not expressible as cron (single dates are not repeating)\",\n );\n\n case \"yearRepeat\":\n throw HronError.cron(\n \"not expressible as cron (yearly schedules not supported in 5-field cron)\",\n );\n }\n}\n\nfunction dayFilterToCronDow(filter: DayFilter): string {\n switch (filter.type) {\n case \"every\":\n return \"*\";\n case \"weekday\":\n return \"1-5\";\n case \"weekend\":\n return \"0,6\";\n case \"days\": {\n const nums = filter.days.map((d) => cronDowNumber(d));\n nums.sort((a, b) => a - b);\n return nums.join(\",\");\n }\n }\n}\n\n// ============================================================================\n// fromCron: Parse 5-field cron expressions (and @ shortcuts)\n// ============================================================================\n\n/** Parse a 5-field cron expression into a ScheduleData. */\nexport function fromCron(cron: string): ScheduleData {\n const trimmed = cron.trim();\n\n // Handle @ shortcuts first\n if (trimmed.startsWith(\"@\")) {\n return parseCronShortcut(trimmed);\n }\n\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 5) {\n throw HronError.cron(`expected 5 cron fields, got ${fields.length}`);\n }\n\n const [minuteField, hourField, domFieldRaw, monthField, dowFieldRaw] = fields;\n\n // Normalize ? to * (semantically equivalent for our purposes)\n const domField = domFieldRaw === \"?\" ? \"*\" : domFieldRaw;\n const dowField = dowFieldRaw === \"?\" ? \"*\" : dowFieldRaw;\n\n // Parse month field into during clause\n const during = parseMonthField(monthField);\n\n // Check for special DOW patterns: nth weekday (#), last weekday (5L)\n const nthWeekdayResult = tryParseNthWeekday(\n minuteField,\n hourField,\n domField,\n dowField,\n during,\n );\n if (nthWeekdayResult) return nthWeekdayResult;\n\n // Check for L (last day) or LW (last weekday) in DOM\n const lastDayResult = tryParseLastDay(\n minuteField,\n hourField,\n domField,\n dowField,\n during,\n );\n if (lastDayResult) return lastDayResult;\n\n // Check for W (nearest weekday): e.g., 15W, 1W\n if (domField.endsWith(\"W\") && domField !== \"LW\") {\n const nearestWeekdayResult = tryParseNearestWeekday(\n minuteField,\n hourField,\n domField,\n dowField,\n during,\n );\n if (nearestWeekdayResult) return nearestWeekdayResult;\n }\n\n // Check for interval patterns: */N or range/N\n const intervalResult = tryParseInterval(\n minuteField,\n hourField,\n domField,\n dowField,\n during,\n );\n if (intervalResult) return intervalResult;\n\n // Standard time-based cron\n const minute = parseSingleValue(minuteField, \"minute\", 0, 59);\n const hour = parseSingleValue(hourField, \"hour\", 0, 23);\n const time: TimeOfDay = { hour, minute };\n\n // DOM-based (monthly) - when DOM is specified and DOW is *\n if (domField !== \"*\" && dowField === \"*\") {\n const target = parseDomField(domField);\n const schedule = newScheduleData({\n type: \"monthRepeat\",\n interval: 1,\n target,\n times: [time],\n });\n schedule.during = during;\n return schedule;\n }\n\n // DOW-based (day repeat)\n const days = parseCronDow(dowField);\n const schedule = newScheduleData({\n type: \"dayRepeat\",\n interval: 1,\n days,\n times: [time],\n });\n schedule.during = during;\n return schedule;\n}\n\n/** Parse @ shortcuts like @daily, @hourly, etc. */\nfunction parseCronShortcut(cron: string): ScheduleData {\n switch (cron.toLowerCase()) {\n case \"@yearly\":\n case \"@annually\":\n return newScheduleData({\n type: \"yearRepeat\",\n interval: 1,\n target: { type: \"date\", month: \"jan\", day: 1 },\n times: [{ hour: 0, minute: 0 }],\n });\n case \"@monthly\":\n return newScheduleData({\n type: \"monthRepeat\",\n interval: 1,\n target: { type: \"days\", specs: [{ type: \"single\", day: 1 }] },\n times: [{ hour: 0, minute: 0 }],\n });\n case \"@weekly\":\n return newScheduleData({\n type: \"dayRepeat\",\n interval: 1,\n days: { type: \"days\", days: [\"sunday\"] },\n times: [{ hour: 0, minute: 0 }],\n });\n case \"@daily\":\n case \"@midnight\":\n return newScheduleData({\n type: \"dayRepeat\",\n interval: 1,\n days: { type: \"every\" },\n times: [{ hour: 0, minute: 0 }],\n });\n case \"@hourly\":\n return newScheduleData({\n type: \"intervalRepeat\",\n interval: 1,\n unit: \"hours\",\n from: { hour: 0, minute: 0 },\n to: { hour: 23, minute: 59 },\n dayFilter: null,\n });\n default:\n throw HronError.cron(`unknown @ shortcut: ${cron}`);\n }\n}\n\n/** Parse month field into a MonthName[] for the `during` clause. */\nfunction parseMonthField(field: string): MonthName[] {\n if (field === \"*\") return [];\n\n const months: MonthName[] = [];\n\n for (const part of field.split(\",\")) {\n // Check for step values FIRST (e.g., 1-12/3 or */3)\n if (part.includes(\"/\")) {\n const [rangePart, stepStr] = part.split(\"/\");\n let start: number, end: number;\n\n if (rangePart === \"*\") {\n start = 1;\n end = 12;\n } else if (rangePart.includes(\"-\")) {\n const [s, e] = rangePart.split(\"-\");\n start = monthNumber(parseMonthValue(s));\n end = monthNumber(parseMonthValue(e));\n } else {\n throw HronError.cron(`invalid month step expression: ${part}`);\n }\n\n const step = parseInt(stepStr, 10);\n if (Number.isNaN(step)) {\n throw HronError.cron(`invalid month step value: ${stepStr}`);\n }\n if (step === 0) {\n throw HronError.cron(\"step cannot be 0\");\n }\n\n for (let n = start; n <= end; n += step) {\n months.push(monthFromNumber(n));\n }\n } else if (part.includes(\"-\")) {\n // Range like 1-3 or JAN-MAR\n const [startStr, endStr] = part.split(\"-\");\n const startMonth = parseMonthValue(startStr);\n const endMonth = parseMonthValue(endStr);\n const startNum = monthNumber(startMonth);\n const endNum = monthNumber(endMonth);\n\n if (startNum > endNum) {\n throw HronError.cron(`invalid month range: ${startStr} > ${endStr}`);\n }\n\n for (let n = startNum; n <= endNum; n++) {\n months.push(monthFromNumber(n));\n }\n } else {\n // Single month\n months.push(parseMonthValue(part));\n }\n }\n\n return months;\n}\n\n/** Parse a single month value (number 1-12 or name JAN-DEC). */\nfunction parseMonthValue(s: string): MonthName {\n // Try as number first\n const n = parseInt(s, 10);\n if (!Number.isNaN(n)) {\n return monthFromNumber(n);\n }\n // Try as name\n const name = parseMonthName(s);\n if (!name) {\n throw HronError.cron(`invalid month: ${s}`);\n }\n return name;\n}\n\nfunction monthFromNumber(n: number): MonthName {\n const map: Record<number, MonthName> = {\n 1: \"jan\",\n 2: \"feb\",\n 3: \"mar\",\n 4: \"apr\",\n 5: \"may\",\n 6: \"jun\",\n 7: \"jul\",\n 8: \"aug\",\n 9: \"sep\",\n 10: \"oct\",\n 11: \"nov\",\n 12: \"dec\",\n };\n const result = map[n];\n if (!result) {\n throw HronError.cron(`invalid month number: ${n}`);\n }\n return result;\n}\n\n/** Try to parse nth weekday patterns like 1#1 (first Monday) or 5L (last Friday). */\nfunction tryParseNthWeekday(\n minuteField: string,\n hourField: string,\n domField: string,\n dowField: string,\n during: MonthName[],\n): ScheduleData | null {\n // Check for # pattern (nth weekday of month)\n if (dowField.includes(\"#\")) {\n const [dowStr, nthStr] = dowField.split(\"#\");\n const dowNum = parseDowValue(dowStr);\n const weekday = cronDowToWeekday(dowNum);\n const nth = parseInt(nthStr, 10);\n\n if (Number.isNaN(nth) || nth < 1 || nth > 5) {\n throw HronError.cron(`nth must be 1-5, got ${nthStr}`);\n }\n\n if (domField !== \"*\" && domField !== \"?\") {\n throw HronError.cron(\"DOM must be * when using # for nth weekday\");\n }\n\n const minute = parseSingleValue(minuteField, \"minute\", 0, 59);\n const hour = parseSingleValue(hourField, \"hour\", 0, 23);\n\n const ordinalMap: Record<number, OrdinalPosition> = {\n 1: \"first\",\n 2: \"second\",\n 3: \"third\",\n 4: \"fourth\",\n 5: \"fifth\",\n };\n\n const schedule = newScheduleData({\n type: \"monthRepeat\",\n interval: 1,\n target: { type: \"ordinalWeekday\", ordinal: ordinalMap[nth], weekday },\n times: [{ hour, minute }],\n });\n schedule.during = during;\n return schedule;\n }\n\n // Check for nL pattern (last weekday of month, e.g., 5L = last Friday)\n if (dowField.endsWith(\"L\") && dowField.length > 1) {\n const dowStr = dowField.slice(0, -1);\n const dowNum = parseDowValue(dowStr);\n const weekday = cronDowToWeekday(dowNum);\n\n if (domField !== \"*\" && domField !== \"?\") {\n throw HronError.cron(\"DOM must be * when using nL for last weekday\");\n }\n\n const minute = parseSingleValue(minuteField, \"minute\", 0, 59);\n const hour = parseSingleValue(hourField, \"hour\", 0, 23);\n\n const schedule = newScheduleData({\n type: \"monthRepeat\",\n interval: 1,\n target: { type: \"ordinalWeekday\", ordinal: \"last\", weekday },\n times: [{ hour, minute }],\n });\n schedule.during = during;\n return schedule;\n }\n\n return null;\n}\n\n/** Try to parse L (last day) or LW (last weekday) patterns. */\nfunction tryParseLastDay(\n minuteField: string,\n hourField: string,\n domField: string,\n dowField: string,\n during: MonthName[],\n): ScheduleData | null {\n if (domField !== \"L\" && domField !== \"LW\") {\n return null;\n }\n\n if (dowField !== \"*\" && dowField !== \"?\") {\n throw HronError.cron(\"DOW must be * when using L or LW in DOM\");\n }\n\n const minute = parseSingleValue(minuteField, \"minute\", 0, 59);\n const hour = parseSingleValue(hourField, \"hour\", 0, 23);\n\n const target: MonthTarget =\n domField === \"LW\" ? { type: \"lastWeekday\" } : { type: \"lastDay\" };\n\n const schedule = newScheduleData({\n type: \"monthRepeat\",\n interval: 1,\n target,\n times: [{ hour, minute }],\n });\n schedule.during = during;\n return schedule;\n}\n\n/** Try to parse W (nearest weekday) patterns: 15W, 1W, etc. */\nfunction tryParseNearestWeekday(\n minuteField: string,\n hourField: string,\n domField: string,\n dowField: string,\n during: MonthName[],\n): ScheduleData | null {\n if (!domField.endsWith(\"W\") || domField === \"LW\") {\n return null;\n }\n\n if (dowField !== \"*\" && dowField !== \"?\") {\n throw HronError.cron(\"DOW must be * when using W in DOM\");\n }\n\n const dayStr = domField.slice(0, -1);\n const day = parseInt(dayStr, 10);\n\n if (Number.isNaN(day)) {\n throw HronError.cron(`invalid W day: ${dayStr}`);\n }\n\n if (day < 1 || day > 31) {\n throw HronError.cron(`W day must be 1-31, got ${day}`);\n }\n\n const minute = parseSingleValue(minuteField, \"minute\", 0, 59);\n const hour = parseSingleValue(hourField, \"hour\", 0, 23);\n\n const target: MonthTarget = {\n type: \"nearestWeekday\",\n day,\n direction: null,\n };\n\n const schedule = newScheduleData({\n type: \"monthRepeat\",\n interval: 1,\n target,\n times: [{ hour, minute }],\n });\n schedule.during = during;\n return schedule;\n}\n\n/** Try to parse interval patterns: star/N, range/N in minute or hour fields. */\nfunction tryParseInterval(\n minuteField: string,\n hourField: string,\n domField: string,\n dowField: string,\n during: MonthName[],\n): ScheduleData | null {\n // Minute interval: */N or range/N\n if (minuteField.includes(\"/\")) {\n const [rangePart, stepStr] = minuteField.split(\"/\");\n const interval = parseInt(stepStr, 10);\n\n if (Number.isNaN(interval)) {\n throw HronError.cron(\"invalid minute interval value\");\n }\n if (interval === 0) {\n throw HronError.cron(\"step cannot be 0\");\n }\n\n let fromMinute: number, toMinute: number;\n if (rangePart === \"*\") {\n fromMinute = 0;\n toMinute = 59;\n } else if (rangePart.includes(\"-\")) {\n const [s, e] = rangePart.split(\"-\");\n fromMinute = parseInt(s, 10);\n toMinute = parseInt(e, 10);\n if (Number.isNaN(fromMinute) || Number.isNaN(toMinute)) {\n throw HronError.cron(\"invalid minute range\");\n }\n if (fromMinute > toMinute) {\n throw HronError.cron(\n `range start must be <= end: ${fromMinute}-${toMinute}`,\n );\n }\n } else {\n // Single value with step\n fromMinute = parseInt(rangePart, 10);\n if (Number.isNaN(fromMinute)) {\n throw HronError.cron(\"invalid minute value\");\n }\n toMinute = 59;\n }\n\n // Determine the hour window\n let fromHour: number, toHour: number;\n if (hourField === \"*\") {\n fromHour = 0;\n toHour = 23;\n } else if (hourField.includes(\"-\") && !hourField.includes(\"/\")) {\n const [s, e] = hourField.split(\"-\");\n fromHour = parseInt(s, 10);\n toHour = parseInt(e, 10);\n if (Number.isNaN(fromHour) || Number.isNaN(toHour)) {\n throw HronError.cron(\"invalid hour range\");\n }\n } else if (hourField.includes(\"/\")) {\n // Hour also has step - complex, skip\n return null;\n } else {\n const h = parseInt(hourField, 10);\n if (Number.isNaN(h)) {\n throw HronError.cron(\"invalid hour\");\n }\n fromHour = h;\n toHour = h;\n }\n\n const dayFilter = dowField === \"*\" ? null : parseCronDow(dowField);\n\n if (domField === \"*\" || domField === \"?\") {\n // Determine end minute based on context\n let endMinute: number;\n if (fromMinute === 0 && toMinute === 59 && toHour === 23) {\n // Full day: 00:00 to 23:59\n endMinute = 59;\n } else if (fromMinute === 0 && toMinute === 59) {\n // Partial day with full minutes range: use :00 for cleaner output\n endMinute = 0;\n } else {\n endMinute = toMinute;\n }\n\n const schedule = newScheduleData({\n type: \"intervalRepeat\",\n interval,\n unit: \"min\",\n from: { hour: fromHour, minute: fromMinute },\n to: { hour: toHour, minute: endMinute },\n dayFilter,\n });\n schedule.during = during;\n return schedule;\n }\n }\n\n // Hour interval: 0 */N or 0 range/N\n if (\n hourField.includes(\"/\") &&\n (minuteField === \"0\" || minuteField === \"00\")\n ) {\n const [rangePart, stepStr] = hourField.split(\"/\");\n const interval = parseInt(stepStr, 10);\n\n if (Number.isNaN(interval)) {\n throw HronError.cron(\"invalid hour interval value\");\n }\n if (interval === 0) {\n throw HronError.cron(\"step cannot be 0\");\n }\n\n let fromHour: number, toHour: number;\n if (rangePart === \"*\") {\n fromHour = 0;\n toHour = 23;\n } else if (rangePart.includes(\"-\")) {\n const [s, e] = rangePart.split(\"-\");\n fromHour = parseInt(s, 10);\n toHour = parseInt(e, 10);\n if (Number.isNaN(fromHour) || Number.isNaN(toHour)) {\n throw HronError.cron(\"invalid hour range\");\n }\n if (fromHour > toHour) {\n throw HronError.cron(\n `range start must be <= end: ${fromHour}-${toHour}`,\n );\n }\n } else {\n fromHour = parseInt(rangePart, 10);\n if (Number.isNaN(fromHour)) {\n throw HronError.cron(\"invalid hour value\");\n }\n toHour = 23;\n }\n\n if (\n (domField === \"*\" || domField === \"?\") &&\n (dowField === \"*\" || dowField === \"?\")\n ) {\n // Use :59 only for full day (00:00 to 23:59), otherwise use :00\n const endMinute = fromHour === 0 && toHour === 23 ? 59 : 0;\n\n const schedule = newScheduleData({\n type: \"intervalRepeat\",\n interval,\n unit: \"hours\",\n from: { hour: fromHour, minute: 0 },\n to: { hour: toHour, minute: endMinute },\n dayFilter: null,\n });\n schedule.during = during;\n return schedule;\n }\n }\n\n return null;\n}\n\n/** Parse a DOM field into a MonthTarget. */\nfunction parseDomField(field: string): MonthTarget {\n const specs: DayOfMonthSpec[] = [];\n\n for (const part of field.split(\",\")) {\n if (part.includes(\"/\")) {\n // Step value: 1-31/2 or */5\n const [rangePart, stepStr] = part.split(\"/\");\n let start: number, end: number;\n\n if (rangePart === \"*\") {\n start = 1;\n end = 31;\n } else if (rangePart.includes(\"-\")) {\n const [s, e] = rangePart.split(\"-\");\n start = parseInt(s, 10);\n end = parseInt(e, 10);\n if (Number.isNaN(start)) {\n throw HronError.cron(`invalid DOM range start: ${s}`);\n }\n if (Number.isNaN(end)) {\n throw HronError.cron(`invalid DOM range end: ${e}`);\n }\n if (start > end) {\n throw HronError.cron(`range start must be <= end: ${start}-${end}`);\n }\n } else {\n start = parseInt(rangePart, 10);\n if (Number.isNaN(start)) {\n throw HronError.cron(`invalid DOM value: ${rangePart}`);\n }\n end = 31;\n }\n\n const step = parseInt(stepStr, 10);\n if (Number.isNaN(step)) {\n throw HronError.cron(`invalid DOM step: ${stepStr}`);\n }\n if (step === 0) {\n throw HronError.cron(\"step cannot be 0\");\n }\n\n validateDom(start);\n validateDom(end);\n\n for (let d = start; d <= end; d += step) {\n specs.push({ type: \"single\", day: d });\n }\n } else if (part.includes(\"-\")) {\n // Range: 1-5\n const [startStr, endStr] = part.split(\"-\");\n const start = parseInt(startStr, 10);\n const end = parseInt(endStr, 10);\n if (Number.isNaN(start)) {\n throw HronError.cron(`invalid DOM range start: ${startStr}`);\n }\n if (Number.isNaN(end)) {\n throw HronError.cron(`invalid DOM range end: ${endStr}`);\n }\n if (start > end) {\n throw HronError.cron(`range start must be <= end: ${start}-${end}`);\n }\n validateDom(start);\n validateDom(end);\n specs.push({ type: \"range\", start, end });\n } else {\n // Single: 15\n const day = parseInt(part, 10);\n if (Number.isNaN(day)) {\n throw HronError.cron(`invalid DOM value: ${part}`);\n }\n validateDom(day);\n specs.push({ type: \"single\", day });\n }\n }\n\n return { type: \"days\", specs };\n}\n\nfunction validateDom(day: number): void {\n if (day < 1 || day > 31) {\n throw HronError.cron(`DOM must be 1-31, got ${day}`);\n }\n}\n\n/** Parse a DOW field into a DayFilter. */\nfunction parseCronDow(field: string): DayFilter {\n if (field === \"*\") return { type: \"every\" };\n\n const days: Weekday[] = [];\n\n for (const part of field.split(\",\")) {\n if (part.includes(\"/\")) {\n // Step value: 0-6/2 or */2\n const [rangePart, stepStr] = part.split(\"/\");\n let start: number, end: number;\n\n if (rangePart === \"*\") {\n start = 0;\n end = 6;\n } else if (rangePart.includes(\"-\")) {\n const [s, e] = rangePart.split(\"-\");\n start = parseDowValueRaw(s);\n end = parseDowValueRaw(e);\n if (start > end) {\n throw HronError.cron(`range start must be <= end: ${s}-${e}`);\n }\n } else {\n start = parseDowValueRaw(rangePart);\n end = 6;\n }\n\n const step = parseInt(stepStr, 10);\n if (Number.isNaN(step)) {\n throw HronError.cron(`invalid DOW step: ${stepStr}`);\n }\n if (step === 0) {\n throw HronError.cron(\"step cannot be 0\");\n }\n\n for (let d = start; d <= end; d += step) {\n const normalized = d === 7 ? 0 : d;\n days.push(cronDowToWeekday(normalized));\n }\n } else if (part.includes(\"-\")) {\n // Range: 1-5 or MON-FRI (parse without normalizing 7 for range checking)\n const [startStr, endStr] = part.split(\"-\");\n const start = parseDowValueRaw(startStr);\n const end = parseDowValueRaw(endStr);\n if (start > end) {\n throw HronError.cron(\n `range start must be <= end: ${startStr}-${endStr}`,\n );\n }\n for (let d = start; d <= end; d++) {\n // Normalize 7 to 0 (Sunday) when converting to weekday\n const normalized = d === 7 ? 0 : d;\n days.push(cronDowToWeekday(normalized));\n }\n } else {\n // Single: 1 or MON\n const dow = parseDowValue(part);\n days.push(cronDowToWeekday(dow));\n }\n }\n\n // Check for special patterns\n if (days.length === 5) {\n const sorted = [...days].sort(\n (a, b) => weekdayNumber(a) - weekdayNumber(b),\n );\n const weekdays = [...ALL_WEEKDAYS].sort(\n (a, b) => weekdayNumber(a) - weekdayNumber(b),\n );\n if (JSON.stringify(sorted) === JSON.stringify(weekdays)) {\n return { type: \"weekday\" };\n }\n }\n if (days.length === 2) {\n const sorted = [...days].sort(\n (a, b) => weekdayNumber(a) - weekdayNumber(b),\n );\n const weekend = [...ALL_WEEKEND].sort(\n (a, b) => weekdayNumber(a) - weekdayNumber(b),\n );\n if (JSON.stringify(sorted) === JSON.stringify(weekend)) {\n return { type: \"weekend\" };\n }\n }\n\n return { type: \"days\", days };\n}\n\n/** Parse a DOW value (number 0-7 or name SUN-SAT), normalizing 7 to 0. */\nfunction parseDowValue(s: string): number {\n const raw = parseDowValueRaw(s);\n // Normalize 7 to 0 (both mean Sunday)\n return raw === 7 ? 0 : raw;\n}\n\n/** Parse a DOW value without normalizing 7 to 0 (for range checking). */\nfunction parseDowValueRaw(s: string): number {\n // Try as number first\n const n = parseInt(s, 10);\n if (!Number.isNaN(n)) {\n if (n > 7) {\n throw HronError.cron(`DOW must be 0-7, got ${n}`);\n }\n return n;\n }\n // Try as name\n const map: Record<string, number> = {\n SUN: 0,\n MON: 1,\n TUE: 2,\n WED: 3,\n THU: 4,\n FRI: 5,\n SAT: 6,\n };\n const result = map[s.toUpperCase()];\n if (result === undefined) {\n throw HronError.cron(`invalid DOW: ${s}`);\n }\n return result;\n}\n\nfunction cronDowToWeekday(n: number): Weekday {\n const map: Record<number, Weekday> = {\n 0: \"sunday\",\n 1: \"monday\",\n 2: \"tuesday\",\n 3: \"wednesday\",\n 4: \"thursday\",\n 5: \"friday\",\n 6: \"saturday\",\n 7: \"sunday\",\n };\n const result = map[n];\n if (!result) {\n throw HronError.cron(`invalid DOW number: ${n}`);\n }\n return result;\n}\n\n/** Parse a single numeric value with validation. */\nfunction parseSingleValue(\n field: string,\n name: string,\n min: number,\n max: number,\n): number {\n const value = parseInt(field, 10);\n if (Number.isNaN(value)) {\n throw HronError.cron(`invalid ${name} field: ${field}`);\n }\n if (value < min || value > max) {\n throw HronError.cron(`${name} must be ${min}-${max}, got ${value}`);\n }\n return value;\n}\n","// Display (toString) for hron schedules — produces canonical form for roundtrip.\n\nimport type {\n DayFilter,\n DayOfMonthSpec,\n IntervalUnit,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n Weekday,\n} from \"./ast.js\";\n\n/** Render a schedule as its canonical string form. */\nexport function display(schedule: ScheduleData): string {\n let out = displayExpr(schedule.expr);\n\n // Trailing clauses in order: except, until, starting, during, timezone\n if (schedule.except.length > 0) {\n out += \" except \";\n out += schedule.except\n .map((exc) => {\n if (exc.type === \"named\") return `${exc.month} ${exc.day}`;\n return exc.date;\n })\n .join(\", \");\n }\n\n if (schedule.until) {\n if (schedule.until.type === \"iso\") {\n out += ` until ${schedule.until.date}`;\n } else {\n out += ` until ${schedule.until.month} ${schedule.until.day}`;\n }\n }\n\n if (schedule.anchor) {\n out += ` starting ${schedule.anchor}`;\n }\n\n if (schedule.during.length > 0) {\n out += ` during ${schedule.during.join(\", \")}`;\n }\n\n if (schedule.timezone) {\n out += ` in ${schedule.timezone}`;\n }\n\n return out;\n}\n\nfunction displayExpr(expr: ScheduleExpr): string {\n switch (expr.type) {\n case \"intervalRepeat\": {\n let out = `every ${expr.interval} ${unitDisplay(expr.interval, expr.unit)}`;\n out += ` from ${formatTime(expr.from)} to ${formatTime(expr.to)}`;\n if (expr.dayFilter) {\n out += ` on ${displayDayFilter(expr.dayFilter)}`;\n }\n return out;\n }\n case \"dayRepeat\":\n if (expr.interval > 1) {\n return `every ${expr.interval} days at ${formatTimeList(expr.times)}`;\n }\n return `every ${displayDayFilter(expr.days)} at ${formatTimeList(expr.times)}`;\n case \"weekRepeat\":\n return `every ${expr.interval} weeks on ${formatDayList(expr.days)} at ${formatTimeList(expr.times)}`;\n case \"monthRepeat\": {\n let targetStr: string;\n if (expr.target.type === \"days\") {\n targetStr = formatOrdinalDaySpecs(expr.target.specs);\n } else if (expr.target.type === \"lastDay\") {\n targetStr = \"last day\";\n } else if (expr.target.type === \"lastWeekday\") {\n targetStr = \"last weekday\";\n } else if (expr.target.type === \"ordinalWeekday\") {\n targetStr = `${expr.target.ordinal} ${expr.target.weekday}`;\n } else if (expr.target.type === \"nearestWeekday\") {\n const { day, direction } = expr.target;\n const dirPrefix = direction ? `${direction} ` : \"\";\n targetStr = `${dirPrefix}nearest weekday to ${day}${ordinalSuffix(day)}`;\n } else {\n throw new Error(\n `unknown month target type: ${(expr.target as { type: string }).type}`,\n );\n }\n if (expr.interval > 1) {\n return `every ${expr.interval} months on the ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n return `every month on the ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n case \"singleDate\": {\n let dateStr: string;\n if (expr.date.type === \"named\") {\n dateStr = `${expr.date.month} ${expr.date.day}`;\n } else {\n dateStr = expr.date.date;\n }\n return `on ${dateStr} at ${formatTimeList(expr.times)}`;\n }\n case \"yearRepeat\": {\n let targetStr: string;\n if (expr.target.type === \"date\") {\n targetStr = `${expr.target.month} ${expr.target.day}`;\n } else if (expr.target.type === \"ordinalWeekday\") {\n targetStr = `the ${expr.target.ordinal} ${expr.target.weekday} of ${expr.target.month}`;\n } else if (expr.target.type === \"dayOfMonth\") {\n targetStr = `the ${expr.target.day}${ordinalSuffix(expr.target.day)} of ${expr.target.month}`;\n } else if (expr.target.type === \"lastWeekday\") {\n targetStr = `the last weekday of ${expr.target.month}`;\n } else {\n throw new Error(\n `unknown year target type: ${(expr.target as { type: string }).type}`,\n );\n }\n if (expr.interval > 1) {\n return `every ${expr.interval} years on ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n return `every year on ${targetStr} at ${formatTimeList(expr.times)}`;\n }\n default: {\n const _exhaustive: never = expr;\n throw new Error(\n `unknown expression type: ${(_exhaustive as { type: string }).type}`,\n );\n }\n }\n}\n\nfunction displayDayFilter(filter: DayFilter): string {\n switch (filter.type) {\n case \"every\":\n return \"day\";\n case \"weekday\":\n return \"weekday\";\n case \"weekend\":\n return \"weekend\";\n case \"days\":\n return formatDayList(filter.days);\n default: {\n const _exhaustive: never = filter;\n throw new Error(\n `unknown day filter type: ${(_exhaustive as { type: string }).type}`,\n );\n }\n }\n}\n\nfunction formatTime(t: TimeOfDay): string {\n return `${String(t.hour).padStart(2, \"0\")}:${String(t.minute).padStart(2, \"0\")}`;\n}\n\nfunction formatTimeList(times: TimeOfDay[]): string {\n return times.map(formatTime).join(\", \");\n}\n\nfunction formatDayList(days: Weekday[]): string {\n return days.join(\", \");\n}\n\nfunction formatOrdinalDaySpecs(specs: DayOfMonthSpec[]): string {\n return specs\n .map((spec) => {\n if (spec.type === \"single\") {\n return `${spec.day}${ordinalSuffix(spec.day)}`;\n }\n return `${spec.start}${ordinalSuffix(spec.start)} to ${spec.end}${ordinalSuffix(spec.end)}`;\n })\n .join(\", \");\n}\n\nexport function ordinalSuffix(n: number): string {\n const mod100 = n % 100;\n if (mod100 >= 11 && mod100 <= 13) return \"th\";\n switch (n % 10) {\n case 1:\n return \"st\";\n case 2:\n return \"nd\";\n case 3:\n return \"rd\";\n default:\n return \"th\";\n }\n}\n\nfunction unitDisplay(interval: number, unit: IntervalUnit): string {\n if (unit === \"min\") {\n return interval === 1 ? \"minute\" : \"min\";\n }\n return interval === 1 ? \"hour\" : \"hours\";\n}\n","// Evaluator — computes next occurrences and matches for hron schedules.\n\nimport { Temporal } from \"@js-temporal/polyfill\";\nimport type {\n DateSpec,\n DayFilter,\n Exception,\n MonthName,\n MonthTarget,\n NearestDirection,\n OrdinalPosition,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n UntilSpec,\n Weekday,\n YearTarget,\n} from \"./ast.js\";\nimport {\n expandMonthTarget,\n monthNumber,\n ordinalToN,\n weekdayNumber,\n} from \"./ast.js\";\n\ntype ZDT = Temporal.ZonedDateTime;\ntype PD = Temporal.PlainDate;\n\n// =============================================================================\n// Iteration Safety Limits\n// =============================================================================\n// MAX_ITERATIONS (1000): Maximum iterations for nextFrom/previousFrom loops.\n// Prevents infinite loops when searching for valid occurrences.\n//\n// Expression-specific limits:\n// - Day repeat: 8 days (covers one week + margin)\n// - Week repeat: 54 weeks (covers one year + margin)\n// - Month repeat: 24 * interval months (covers 2 years scaled by interval)\n// - Year repeat: 8 * interval years (covers reasonable future horizon)\n//\n// These limits are generous safety bounds. In practice, valid schedules\n// find occurrences within the first few iterations.\n// =============================================================================\n\n// =============================================================================\n// DST (Daylight Saving Time) Handling\n// =============================================================================\n// When resolving a wall-clock time to an instant:\n//\n// 1. DST Gap (Spring Forward):\n// - Time doesn't exist (e.g., 2:30 AM during spring forward)\n// - Solution: Push forward to the next valid time after the gap\n// - Example: 2:30 AM -> 3:00 AM (or 3:30 AM depending on gap size)\n//\n// 2. DST Fold (Fall Back):\n// - Time is ambiguous (e.g., 1:30 AM occurs twice)\n// - Solution: Use first occurrence (fold=0 / pre-transition time)\n// - This matches user expectation for scheduling\n//\n// All implementations use the same algorithm for cross-language consistency.\n// =============================================================================\n\n// =============================================================================\n// Interval Alignment (Anchor Date)\n// =============================================================================\n// For schedules with interval > 1 (e.g., \"every 3 days\"), we need to\n// determine which dates are valid based on alignment with an anchor.\n//\n// Formula: (date_offset - anchor_offset) mod interval == 0\n//\n// Where:\n// - date_offset: days/weeks/months from epoch to candidate date\n// - anchor_offset: days/weeks/months from epoch to anchor date\n// - interval: the repeat interval (e.g., 3 for \"every 3 days\")\n//\n// Default anchor: Epoch (1970-01-01)\n// Custom anchor: Set via \"starting YYYY-MM-DD\" clause\n//\n// For week repeats, we use epoch Monday (1970-01-05) as the reference\n// point to align week boundaries correctly.\n// =============================================================================\n\n// --- Timezone resolution ---\n\n/** Resolve timezone, defaulting to UTC for deterministic behavior. */\nfunction resolveTz(tz: string | null): string {\n return tz ?? \"UTC\";\n}\n\n// --- Helpers ---\n\nfunction toPlainTime(tod: TimeOfDay): Temporal.PlainTime {\n return Temporal.PlainTime.from({ hour: tod.hour, minute: tod.minute });\n}\n\nfunction atTimeOnDate(date: PD, time: Temporal.PlainTime, tz: string): ZDT {\n return date.toPlainDateTime(time).toZonedDateTime(tz, {\n disambiguation: \"compatible\",\n });\n}\n\nfunction weekdayNameToNumber(day: Weekday): number {\n return weekdayNumber(day);\n}\n\nfunction matchesDayFilter(date: PD, filter: DayFilter): boolean {\n const dow = date.dayOfWeek; // 1=Monday ... 7=Sunday\n switch (filter.type) {\n case \"every\":\n return true;\n case \"weekday\":\n return dow >= 1 && dow <= 5;\n case \"weekend\":\n return dow === 6 || dow === 7;\n case \"days\":\n return filter.days.some((d) => weekdayNameToNumber(d) === dow);\n }\n}\n\nfunction lastDayOfMonth(year: number, month: number): PD {\n return Temporal.PlainDate.from({ year, month, day: 1 })\n .add({ months: 1 })\n .subtract({ days: 1 });\n}\n\nfunction lastWeekdayOfMonth(year: number, month: number): PD {\n let d = lastDayOfMonth(year, month);\n while (d.dayOfWeek === 6 || d.dayOfWeek === 7) {\n d = d.subtract({ days: 1 });\n }\n return d;\n}\n\n/**\n * Get the nearest weekday to a given day in a month.\n * - direction=null: standard cron W behavior (never crosses month boundary)\n * - direction=\"next\": always prefer following weekday (can cross to next month)\n * - direction=\"previous\": always prefer preceding weekday (can cross to prev month)\n * Returns null if the target_day doesn't exist in the month (e.g., day 31 in February).\n */\nfunction nearestWeekday(\n year: number,\n month: number,\n targetDay: number,\n direction: NearestDirection | null,\n): PD | null {\n const last = lastDayOfMonth(year, month);\n const lastDay = last.day;\n\n // If target day doesn't exist in this month, return null (skip this month)\n if (targetDay > lastDay) {\n return null;\n }\n\n const date = Temporal.PlainDate.from({ year, month, day: targetDay });\n const dow = date.dayOfWeek; // 1=Monday, 7=Sunday\n\n // Already a weekday (Monday=1 through Friday=5)\n if (dow >= 1 && dow <= 5) {\n return date;\n }\n\n // Saturday (dow === 6)\n if (dow === 6) {\n if (direction === null) {\n // Standard: prefer Friday, but if at month start, use Monday\n if (targetDay === 1) {\n // Can't go to previous month, use Monday (day 3)\n return date.add({ days: 2 });\n }\n // Friday\n return date.subtract({ days: 1 });\n }\n if (direction === \"next\") {\n // Always Monday (may cross month)\n return date.add({ days: 2 });\n }\n // direction === \"previous\"\n // Always Friday (may cross month if day==1)\n return date.subtract({ days: 1 });\n }\n\n // Sunday (dow === 7)\n if (direction === null) {\n // Standard: prefer Monday, but if at month end, use Friday\n if (targetDay >= lastDay) {\n // Can't go to next month, use Friday (day - 2)\n return date.subtract({ days: 2 });\n }\n // Monday\n return date.add({ days: 1 });\n }\n if (direction === \"next\") {\n // Always Monday (may cross month)\n return date.add({ days: 1 });\n }\n // direction === \"previous\"\n // Always Friday (go back 2 days, may cross month)\n return date.subtract({ days: 2 });\n}\n\nfunction nthWeekdayOfMonth(\n year: number,\n month: number,\n weekday: Weekday,\n n: number,\n): PD | null {\n const targetDow = weekdayNameToNumber(weekday);\n let d = Temporal.PlainDate.from({ year, month, day: 1 });\n while (d.dayOfWeek !== targetDow) {\n d = d.add({ days: 1 });\n }\n for (let i = 1; i < n; i++) {\n d = d.add({ days: 7 });\n }\n if (d.month !== month) return null;\n return d;\n}\n\nfunction lastWeekdayInMonth(year: number, month: number, weekday: Weekday): PD {\n const targetDow = weekdayNameToNumber(weekday);\n let d = lastDayOfMonth(year, month);\n while (d.dayOfWeek !== targetDow) {\n d = d.subtract({ days: 1 });\n }\n return d;\n}\n\nconst EPOCH_MONDAY: PD = Temporal.PlainDate.from(\"1970-01-05\");\nconst EPOCH_DATE: PD = Temporal.PlainDate.from(\"1970-01-01\");\nconst MIDNIGHT: Temporal.PlainTime = Temporal.PlainTime.from({\n hour: 0,\n minute: 0,\n});\n\nfunction weeksBetween(a: PD, b: PD): number {\n const days = a.until(b, { largestUnit: \"days\" }).days;\n return Math.floor(days / 7);\n}\n\nfunction daysBetween(a: PD, b: PD): number {\n return a.until(b, { largestUnit: \"days\" }).days;\n}\n\nfunction monthsBetweenYM(a: PD, b: PD): number {\n return b.year * 12 + b.month - (a.year * 12 + a.month);\n}\n\n/** Euclidean modulo (always non-negative). */\nfunction euclideanMod(a: number, b: number): number {\n return ((a % b) + b) % b;\n}\n\nfunction isExcepted(date: PD, exceptions: Exception[]): boolean {\n for (const exc of exceptions) {\n if (exc.type === \"named\") {\n if (date.month === monthNumber(exc.month) && date.day === exc.day) {\n return true;\n }\n } else {\n const excDate = Temporal.PlainDate.from(exc.date);\n if (Temporal.PlainDate.compare(date, excDate) === 0) {\n return true;\n }\n }\n }\n return false;\n}\n\ninterface ParsedExceptions {\n named: Array<{ month: number; day: number }>;\n isoDates: PD[];\n}\n\nfunction parseExceptions(exceptions: Exception[]): ParsedExceptions {\n const named: Array<{ month: number; day: number }> = [];\n const isoDates: PD[] = [];\n for (const exc of exceptions) {\n if (exc.type === \"named\") {\n named.push({ month: monthNumber(exc.month), day: exc.day });\n } else {\n isoDates.push(Temporal.PlainDate.from(exc.date));\n }\n }\n return { named, isoDates };\n}\n\nfunction isExceptedParsed(date: PD, parsed: ParsedExceptions): boolean {\n for (const n of parsed.named) {\n if (date.month === n.month && date.day === n.day) return true;\n }\n for (const d of parsed.isoDates) {\n if (Temporal.PlainDate.compare(date, d) === 0) return true;\n }\n return false;\n}\n\nfunction matchesDuring(date: PD, during: MonthName[]): boolean {\n if (during.length === 0) return true;\n return during.some((mn) => monthNumber(mn) === date.month);\n}\n\n/** Find the 1st of the next valid `during` month after `date`. */\nfunction nextDuringMonth(date: PD, during: MonthName[]): PD {\n const currentMonth = date.month;\n const months = during.map((mn) => monthNumber(mn)).sort((a, b) => a - b);\n\n for (const m of months) {\n if (m > currentMonth) {\n return Temporal.PlainDate.from({ year: date.year, month: m, day: 1 });\n }\n }\n // Wrap to first month of next year\n return Temporal.PlainDate.from({\n year: date.year + 1,\n month: months[0],\n day: 1,\n });\n}\n\nfunction resolveUntil(until: UntilSpec, now: ZDT): PD {\n if (until.type === \"iso\") {\n return Temporal.PlainDate.from(until.date);\n }\n const year = now.toPlainDate().year;\n for (const y of [year, year + 1]) {\n try {\n const d = Temporal.PlainDate.from(\n {\n year: y,\n month: monthNumber(until.month),\n day: until.day,\n },\n { overflow: \"reject\" },\n );\n if (Temporal.PlainDate.compare(d, now.toPlainDate()) >= 0) {\n return d;\n }\n } catch {\n // Invalid date, try next year\n }\n }\n return Temporal.PlainDate.from(\n {\n year: year + 1,\n month: monthNumber(until.month),\n day: until.day,\n },\n { overflow: \"reject\" },\n );\n}\n\nfunction earliestFutureAtTimes(\n date: PD,\n times: TimeOfDay[],\n tz: string,\n now: ZDT,\n): ZDT | null {\n let best: ZDT | null = null;\n for (const tod of times) {\n const t = toPlainTime(tod);\n const candidate = atTimeOnDate(date, t, tz);\n if (Temporal.ZonedDateTime.compare(candidate, now) > 0) {\n if (\n best === null ||\n Temporal.ZonedDateTime.compare(candidate, best) < 0\n ) {\n best = candidate;\n }\n }\n }\n return best;\n}\n\n// --- Public API ---\n\nexport function nextFrom(schedule: ScheduleData, now: ZDT): ZDT | null {\n const tz = resolveTz(schedule.timezone);\n\n const untilDate = schedule.until ? resolveUntil(schedule.until, now) : null;\n\n const parsedExceptions = parseExceptions(schedule.except);\n const hasExceptions = schedule.except.length > 0;\n const hasDuring = schedule.during.length > 0;\n\n // Check if expression is NearestWeekday with direction (can cross month boundaries)\n const handlesDuringInternally =\n schedule.expr.type === \"monthRepeat\" &&\n schedule.expr.target.type === \"nearestWeekday\" &&\n schedule.expr.target.direction !== null;\n\n let current = now;\n for (let i = 0; i < 1000; i++) {\n const candidate = nextExpr(\n schedule.expr,\n tz,\n schedule.anchor,\n current,\n schedule.during,\n );\n\n if (candidate === null) return null;\n\n // Convert to target tz once for all filter checks\n const cDate = candidate.withTimeZone(tz).toPlainDate();\n\n // Apply until filter\n if (untilDate) {\n if (Temporal.PlainDate.compare(cDate, untilDate) > 0) {\n return null;\n }\n }\n\n // Apply during filter\n // Skip this check for expressions that handle during internally (NearestWeekday with direction)\n if (\n hasDuring &&\n !handlesDuringInternally &&\n !matchesDuring(cDate, schedule.during)\n ) {\n // Skip ahead to 1st of next valid during month\n const skipTo = nextDuringMonth(cDate, schedule.during);\n current = atTimeOnDate(skipTo, MIDNIGHT, tz).subtract({ seconds: 1 });\n continue;\n }\n\n // Apply except filter\n if (hasExceptions && isExceptedParsed(cDate, parsedExceptions)) {\n const nextDay = cDate.add({ days: 1 });\n current = atTimeOnDate(nextDay, MIDNIGHT, tz).subtract({ seconds: 1 });\n continue;\n }\n\n return candidate;\n }\n\n return null;\n}\n\nfunction nextExpr(\n expr: ScheduleExpr,\n tz: string,\n anchor: string | null,\n now: ZDT,\n during: MonthName[],\n): ZDT | null {\n switch (expr.type) {\n case \"dayRepeat\":\n return nextDayRepeat(\n expr.interval,\n expr.days,\n expr.times,\n tz,\n anchor,\n now,\n );\n case \"intervalRepeat\":\n return nextIntervalRepeat(\n expr.interval,\n expr.unit,\n expr.from,\n expr.to,\n expr.dayFilter,\n tz,\n now,\n );\n case \"weekRepeat\":\n return nextWeekRepeat(\n expr.interval,\n expr.days,\n expr.times,\n tz,\n anchor,\n now,\n );\n case \"monthRepeat\":\n return nextMonthRepeat(\n expr.interval,\n expr.target,\n expr.times,\n tz,\n anchor,\n now,\n during,\n );\n case \"singleDate\":\n return nextSingleDate(expr.date, expr.times, tz, now);\n case \"yearRepeat\":\n return nextYearRepeat(\n expr.interval,\n expr.target,\n expr.times,\n tz,\n anchor,\n now,\n );\n }\n}\n\nexport function nextNFrom(schedule: ScheduleData, now: ZDT, n: number): ZDT[] {\n const results: ZDT[] = [];\n let current = now;\n for (let i = 0; i < n; i++) {\n const next = nextFrom(schedule, current);\n if (next === null) break;\n current = next.add({ minutes: 1 });\n results.push(next);\n }\n return results;\n}\n\nexport function matches(schedule: ScheduleData, datetime: ZDT): boolean {\n const tz = resolveTz(schedule.timezone);\n const zdt = datetime.withTimeZone(tz);\n const date = zdt.toPlainDate();\n\n if (!matchesDuring(date, schedule.during)) return false;\n if (isExcepted(date, schedule.except)) return false;\n\n if (schedule.until) {\n const untilDate = resolveUntil(schedule.until, datetime);\n if (Temporal.PlainDate.compare(date, untilDate) > 0) return false;\n }\n\n // DST-aware time matching: a time matches if either the wall-clock matches\n // directly, or the scheduled time falls in a DST gap and resolves to the\n // candidate's instant (e.g., scheduled 2:00 AM during spring-forward → 3:00 AM).\n const timeMatchesWithDst = (times: TimeOfDay[]) =>\n times.some((tod) => {\n if (zdt.hour === tod.hour && zdt.minute === tod.minute) return true;\n const t = toPlainTime(tod);\n const resolved = atTimeOnDate(date, t, tz);\n return resolved.epochNanoseconds === datetime.epochNanoseconds;\n });\n\n switch (schedule.expr.type) {\n case \"dayRepeat\": {\n if (!matchesDayFilter(date, schedule.expr.days)) return false;\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_DATE;\n const dayOffset = daysBetween(anchorDate, date);\n return dayOffset >= 0 && dayOffset % schedule.expr.interval === 0;\n }\n return true;\n }\n case \"intervalRepeat\": {\n const { interval, unit, from, to, dayFilter } = schedule.expr;\n if (dayFilter && !matchesDayFilter(date, dayFilter)) return false;\n const fromMinutes = from.hour * 60 + from.minute;\n const toMinutes = to.hour * 60 + to.minute;\n const currentMinutes = zdt.hour * 60 + zdt.minute;\n if (currentMinutes < fromMinutes || currentMinutes > toMinutes)\n return false;\n const diff = currentMinutes - fromMinutes;\n const step = unit === \"min\" ? interval : interval * 60;\n return diff >= 0 && diff % step === 0;\n }\n case \"weekRepeat\": {\n const { interval, days, times } = schedule.expr;\n const dow = date.dayOfWeek;\n if (!days.some((d) => weekdayNameToNumber(d) === dow)) return false;\n if (!timeMatchesWithDst(times)) return false;\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_MONDAY;\n const weeks = weeksBetween(anchorDate, date);\n return weeks >= 0 && weeks % interval === 0;\n }\n case \"monthRepeat\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorDate = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor)\n : EPOCH_DATE;\n const monthOffset = monthsBetweenYM(anchorDate, date);\n if (monthOffset < 0 || monthOffset % schedule.expr.interval !== 0) {\n return false;\n }\n }\n const { target } = schedule.expr;\n if (target.type === \"days\") {\n const expanded = expandMonthTarget(target);\n return expanded.includes(date.day);\n }\n if (target.type === \"lastDay\") {\n const last = lastDayOfMonth(date.year, date.month);\n return Temporal.PlainDate.compare(date, last) === 0;\n }\n if (target.type === \"lastWeekday\") {\n const lastWd = lastWeekdayOfMonth(date.year, date.month);\n return Temporal.PlainDate.compare(date, lastWd) === 0;\n }\n if (target.type === \"ordinalWeekday\") {\n let targetDate: PD | null;\n if (target.ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(\n date.year,\n date.month,\n target.weekday,\n );\n } else {\n targetDate = nthWeekdayOfMonth(\n date.year,\n date.month,\n target.weekday,\n ordinalToN(target.ordinal),\n );\n }\n if (!targetDate) return false;\n return Temporal.PlainDate.compare(date, targetDate) === 0;\n }\n // nearestWeekday\n const targetDate = nearestWeekday(\n date.year,\n date.month,\n target.day,\n target.direction,\n );\n if (!targetDate) return false;\n return Temporal.PlainDate.compare(date, targetDate) === 0;\n }\n case \"singleDate\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n const { date: dateSpec } = schedule.expr;\n if (dateSpec.type === \"iso\") {\n const target = Temporal.PlainDate.from(dateSpec.date);\n return Temporal.PlainDate.compare(date, target) === 0;\n }\n if (dateSpec.type === \"named\") {\n return (\n date.month === monthNumber(dateSpec.month) &&\n date.day === dateSpec.day\n );\n }\n return false;\n }\n case \"yearRepeat\": {\n if (!timeMatchesWithDst(schedule.expr.times)) return false;\n if (schedule.expr.interval > 1) {\n const anchorYear = schedule.anchor\n ? Temporal.PlainDate.from(schedule.anchor).year\n : EPOCH_DATE.year;\n const yearOffset = date.year - anchorYear;\n if (yearOffset < 0 || yearOffset % schedule.expr.interval !== 0) {\n return false;\n }\n }\n return matchesYearTarget(schedule.expr.target, date);\n }\n }\n}\n\nfunction matchesYearTarget(target: YearTarget, date: PD): boolean {\n switch (target.type) {\n case \"date\":\n return (\n date.month === monthNumber(target.month) && date.day === target.day\n );\n case \"ordinalWeekday\": {\n if (date.month !== monthNumber(target.month)) return false;\n let targetDate: PD | null;\n if (target.ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(date.year, date.month, target.weekday);\n } else {\n targetDate = nthWeekdayOfMonth(\n date.year,\n date.month,\n target.weekday,\n ordinalToN(target.ordinal),\n );\n }\n if (!targetDate) return false;\n return Temporal.PlainDate.compare(date, targetDate) === 0;\n }\n case \"dayOfMonth\":\n return (\n date.month === monthNumber(target.month) && date.day === target.day\n );\n case \"lastWeekday\": {\n if (date.month !== monthNumber(target.month)) return false;\n const lwd = lastWeekdayOfMonth(date.year, date.month);\n return Temporal.PlainDate.compare(date, lwd) === 0;\n }\n }\n}\n\n// --- Per-variant next functions ---\n\nfunction nextDayRepeat(\n interval: number,\n days: DayFilter,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let date = nowInTz.toPlainDate();\n\n if (interval <= 1) {\n // Original behavior for interval=1\n if (matchesDayFilter(date, days)) {\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) return candidate;\n }\n\n for (let i = 0; i < 8; i++) {\n date = date.add({ days: 1 });\n if (matchesDayFilter(date, days)) {\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) return candidate;\n }\n }\n\n return null;\n }\n\n // Interval > 1: day intervals only apply to DayFilter::Every\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n\n // Find the next aligned day >= today\n const offset = daysBetween(anchorDate, date);\n const remainder = euclideanMod(offset, interval);\n let alignedDate =\n remainder === 0 ? date : date.add({ days: interval - remainder });\n\n for (let i = 0; i < 400; i++) {\n const candidate = earliestFutureAtTimes(alignedDate, times, tz, now);\n if (candidate) return candidate;\n alignedDate = alignedDate.add({ days: interval });\n }\n\n return null;\n}\n\nfunction nextIntervalRepeat(\n interval: number,\n unit: string,\n from: TimeOfDay,\n to: TimeOfDay,\n dayFilter: DayFilter | null,\n tz: string,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const stepMinutes = unit === \"min\" ? interval : interval * 60;\n const fromMinutes = from.hour * 60 + from.minute;\n const toMinutes = to.hour * 60 + to.minute;\n\n let date = nowInTz.toPlainDate();\n\n for (let d = 0; d < 400; d++) {\n if (dayFilter && !matchesDayFilter(date, dayFilter)) {\n date = date.add({ days: 1 });\n continue;\n }\n\n const sameDay =\n Temporal.PlainDate.compare(date, nowInTz.toPlainDate()) === 0;\n const nowMinutes = sameDay ? nowInTz.hour * 60 + nowInTz.minute : -1;\n\n let nextSlot: number;\n if (nowMinutes < fromMinutes) {\n nextSlot = fromMinutes;\n } else {\n const elapsed = nowMinutes - fromMinutes;\n nextSlot =\n fromMinutes + (Math.floor(elapsed / stepMinutes) + 1) * stepMinutes;\n }\n\n if (nextSlot <= toMinutes) {\n const h = Math.floor(nextSlot / 60);\n const m = nextSlot % 60;\n const t = Temporal.PlainTime.from({ hour: h, minute: m });\n const candidate = atTimeOnDate(date, t, tz);\n if (Temporal.ZonedDateTime.compare(candidate, now) > 0) {\n return candidate;\n }\n }\n\n date = date.add({ days: 1 });\n }\n\n return null;\n}\n\nfunction nextWeekRepeat(\n interval: number,\n days: Weekday[],\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_MONDAY;\n\n const date = nowInTz.toPlainDate();\n\n // Sort target DOWs by number for earliest-first matching\n const sortedDays = [...days].sort(\n (a, b) => weekdayNameToNumber(a) - weekdayNameToNumber(b),\n );\n\n // Find Monday of current week and Monday of anchor week\n const dowOffset = date.dayOfWeek - 1;\n let currentMonday = date.subtract({ days: dowOffset });\n\n const anchorDowOffset = anchorDate.dayOfWeek - 1;\n const anchorMonday = anchorDate.subtract({ days: anchorDowOffset });\n\n // Loop up to 54 iterations (covers >1 year for any interval)\n for (let i = 0; i < 54; i++) {\n const weeks = weeksBetween(anchorMonday, currentMonday);\n\n // Skip weeks before anchor - anchor Monday is always the first aligned week\n if (weeks < 0) {\n currentMonday = anchorMonday;\n continue;\n }\n\n if (weeks % interval === 0) {\n // Aligned week — try each target DOW\n for (const wd of sortedDays) {\n const dayOffset = weekdayNameToNumber(wd) - 1;\n const targetDate = currentMonday.add({ days: dayOffset });\n const candidate = earliestFutureAtTimes(targetDate, times, tz, now);\n if (candidate) return candidate;\n }\n }\n\n // Skip to next aligned week\n const remainder = weeks % interval;\n const skipWeeks = remainder === 0 ? interval : interval - remainder;\n currentMonday = currentMonday.add({ days: skipWeeks * 7 });\n }\n\n return null;\n}\n\nfunction nextMonthRepeat(\n interval: number,\n target: MonthTarget,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n during: MonthName[],\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let year = nowInTz.year;\n let month = nowInTz.month;\n\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n const maxIter = interval > 1 ? 24 * interval : 24;\n\n // For NearestWeekday with direction, we need to apply the during filter here\n // because the result can cross month boundaries\n const applyDuringFilter =\n during.length > 0 &&\n target.type === \"nearestWeekday\" &&\n target.direction !== null;\n\n for (let i = 0; i < maxIter; i++) {\n // Check during filter for NearestWeekday with direction\n if (applyDuringFilter && !during.some((mn) => monthNumber(mn) === month)) {\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n continue;\n }\n\n // Check interval alignment\n if (interval > 1) {\n const cur = Temporal.PlainDate.from({ year, month, day: 1 });\n const monthOffset = monthsBetweenYM(anchorDate, cur);\n if (monthOffset < 0 || euclideanMod(monthOffset, interval) !== 0) {\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n continue;\n }\n }\n\n const dateCandidates: PD[] = [];\n\n if (target.type === \"days\") {\n const expanded = expandMonthTarget(target);\n for (const dayNum of expanded) {\n const last = lastDayOfMonth(year, month);\n if (dayNum <= last.day) {\n try {\n dateCandidates.push(\n Temporal.PlainDate.from({ year, month, day: dayNum }),\n );\n } catch {\n // skip invalid\n }\n }\n }\n } else if (target.type === \"lastDay\") {\n dateCandidates.push(lastDayOfMonth(year, month));\n } else if (target.type === \"lastWeekday\") {\n dateCandidates.push(lastWeekdayOfMonth(year, month));\n } else if (target.type === \"ordinalWeekday\") {\n let owDate: PD | null;\n if (target.ordinal === \"last\") {\n owDate = lastWeekdayInMonth(year, month, target.weekday);\n } else {\n owDate = nthWeekdayOfMonth(\n year,\n month,\n target.weekday,\n ordinalToN(target.ordinal),\n );\n }\n if (owDate) {\n dateCandidates.push(owDate);\n }\n } else {\n // nearestWeekday\n const nwDate = nearestWeekday(year, month, target.day, target.direction);\n if (nwDate) {\n dateCandidates.push(nwDate);\n }\n }\n\n let best: ZDT | null = null;\n for (const date of dateCandidates) {\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) {\n if (\n best === null ||\n Temporal.ZonedDateTime.compare(candidate, best) < 0\n ) {\n best = candidate;\n }\n }\n }\n if (best) return best;\n\n month++;\n if (month > 12) {\n month = 1;\n year++;\n }\n }\n\n return null;\n}\n\nfunction nextSingleDate(\n dateSpec: DateSpec,\n times: TimeOfDay[],\n tz: string,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n\n if (dateSpec.type === \"iso\") {\n const date = Temporal.PlainDate.from(dateSpec.date);\n return earliestFutureAtTimes(date, times, tz, now);\n }\n\n if (dateSpec.type === \"named\") {\n const startYear = nowInTz.year;\n for (let y = 0; y < 8; y++) {\n const year = startYear + y;\n try {\n const date = Temporal.PlainDate.from(\n {\n year,\n month: monthNumber(dateSpec.month),\n day: dateSpec.day,\n },\n { overflow: \"reject\" },\n );\n const candidate = earliestFutureAtTimes(date, times, tz, now);\n if (candidate) return candidate;\n } catch {\n // invalid date\n }\n }\n return null;\n }\n\n return null;\n}\n\nfunction nextYearRepeat(\n interval: number,\n target: YearTarget,\n times: TimeOfDay[],\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const startYear = nowInTz.year;\n const anchorYear = anchor\n ? Temporal.PlainDate.from(anchor).year\n : EPOCH_DATE.year;\n\n const maxIter = interval > 1 ? 8 * interval : 8;\n\n for (let y = 0; y < maxIter; y++) {\n const year = startYear + y;\n\n // Check interval alignment\n if (interval > 1) {\n const yearOffset = year - anchorYear;\n if (yearOffset < 0 || euclideanMod(yearOffset, interval) !== 0) {\n continue;\n }\n }\n\n let targetDate: PD | null = null;\n\n switch (target.type) {\n case \"date\":\n try {\n targetDate = Temporal.PlainDate.from(\n {\n year,\n month: monthNumber(target.month),\n day: target.day,\n },\n { overflow: \"reject\" },\n );\n } catch {\n continue;\n }\n break;\n case \"ordinalWeekday\":\n if (target.ordinal === \"last\") {\n targetDate = lastWeekdayInMonth(\n year,\n monthNumber(target.month),\n target.weekday,\n );\n } else {\n targetDate = nthWeekdayOfMonth(\n year,\n monthNumber(target.month),\n target.weekday,\n ordinalToN(target.ordinal),\n );\n }\n break;\n case \"dayOfMonth\":\n try {\n targetDate = Temporal.PlainDate.from(\n {\n year,\n month: monthNumber(target.month),\n day: target.day,\n },\n { overflow: \"reject\" },\n );\n } catch {\n continue;\n }\n break;\n case \"lastWeekday\":\n targetDate = lastWeekdayOfMonth(year, monthNumber(target.month));\n break;\n }\n\n if (targetDate) {\n const candidate = earliestFutureAtTimes(targetDate, times, tz, now);\n if (candidate) return candidate;\n }\n }\n\n return null;\n}\n\n/**\n * Compute the most recent occurrence strictly before `now`.\n * Returns null if no previous occurrence exists (e.g., before a starting anchor\n * or for single dates in the future).\n */\nexport function previousFrom(schedule: ScheduleData, now: ZDT): ZDT | null {\n const tz = resolveTz(schedule.timezone);\n const anchor = schedule.anchor;\n\n // Parse exceptions once\n const parsedExceptions = parseExceptions(schedule.except);\n const hasExceptions = schedule.except.length > 0;\n const hasDuring = schedule.during.length > 0;\n\n // Retry loop for exceptions and during filter\n let current = now;\n for (let i = 0; i < 1000; i++) {\n const candidate = prevExpr(schedule, tz, anchor, current);\n\n if (candidate === null) return null;\n\n const cDate = candidate.withTimeZone(tz).toPlainDate();\n\n // Check starting anchor - if before anchor, no previous occurrence\n if (anchor) {\n const anchorDate = Temporal.PlainDate.from(anchor);\n if (Temporal.PlainDate.compare(cDate, anchorDate) < 0) {\n return null;\n }\n }\n\n // Apply until filter for previousFrom:\n // If candidate is after until, search earlier\n if (schedule.until) {\n const untilDate = resolveUntil(schedule.until, now);\n if (Temporal.PlainDate.compare(cDate, untilDate) > 0) {\n const endOfDay = toPlainTime({ hour: 23, minute: 59 });\n const skipTo = atTimeOnDate(untilDate, endOfDay, tz);\n current = skipTo.add({ seconds: 1 });\n continue;\n }\n }\n\n // Apply during filter\n if (hasDuring && !matchesDuring(cDate, schedule.during)) {\n const skipTo = prevDuringMonth(cDate, schedule.during);\n const endOfDay = toPlainTime({ hour: 23, minute: 59 });\n current = atTimeOnDate(skipTo, endOfDay, tz).add({\n seconds: 1,\n });\n continue;\n }\n\n // Apply except filter\n if (hasExceptions && isExceptedParsed(cDate, parsedExceptions)) {\n const prevDay = cDate.subtract({ days: 1 });\n const endOfDay = toPlainTime({ hour: 23, minute: 59 });\n current = atTimeOnDate(prevDay, endOfDay, tz).add({\n seconds: 1,\n });\n continue;\n }\n\n return candidate;\n }\n\n return null;\n}\n\n/**\n * Compute previous occurrence for the expression part.\n */\nfunction prevExpr(\n schedule: ScheduleData,\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const expr = schedule.expr;\n\n switch (expr.type) {\n case \"dayRepeat\":\n return prevDayRepeat(expr, tz, anchor, now);\n case \"intervalRepeat\":\n return prevIntervalRepeat(expr, tz, now);\n case \"weekRepeat\":\n return prevWeekRepeat(expr, tz, anchor, now);\n case \"monthRepeat\":\n return prevMonthRepeat(expr, tz, anchor, now);\n case \"singleDate\":\n return prevSingleDate(expr, tz, now);\n case \"yearRepeat\":\n return prevYearRepeat(expr, tz, anchor, now);\n default:\n return null;\n }\n}\n\nfunction prevDayRepeat(\n expr: Extract<ScheduleExpr, { type: \"dayRepeat\" }>,\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let date = nowInTz.toPlainDate();\n const { interval, days, times } = expr;\n\n if (interval <= 1) {\n // Check today for times that have passed\n if (matchesDayFilter(date, days)) {\n const candidate = latestPastAtTimes(date, times, tz, now);\n if (candidate !== null) return candidate;\n }\n // Go back day by day\n for (let i = 0; i < 8; i++) {\n date = date.subtract({ days: 1 });\n if (matchesDayFilter(date, days)) {\n const candidate = latestAtTimes(date, times, tz);\n if (candidate !== null) return candidate;\n }\n }\n return null;\n }\n\n // Interval > 1\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n const offset = daysBetween(anchorDate, date);\n const remainder = ((offset % interval) + interval) % interval;\n const alignedDate =\n remainder === 0 ? date : date.subtract({ days: remainder });\n\n for (let i = 0; i < 2; i++) {\n const checkDate = alignedDate.subtract({ days: i * interval });\n const candidate = latestPastAtTimes(checkDate, times, tz, now);\n if (candidate !== null) return candidate;\n const latest = latestAtTimes(checkDate, times, tz);\n if (latest !== null && Temporal.ZonedDateTime.compare(latest, now) < 0) {\n return latest;\n }\n }\n\n return null;\n}\n\nfunction prevIntervalRepeat(\n expr: Extract<ScheduleExpr, { type: \"intervalRepeat\" }>,\n tz: string,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n let date = nowInTz.toPlainDate();\n const { interval, unit, from, to, dayFilter } = expr;\n\n const stepMinutes = unit === \"min\" ? interval : interval * 60;\n const fromMinutes = from.hour * 60 + from.minute;\n const toMinutes = to.hour * 60 + to.minute;\n\n for (let d = 0; d < 8; d++) {\n if (dayFilter && !matchesDayFilter(date, dayFilter)) {\n date = date.subtract({ days: 1 });\n continue;\n }\n\n const nowMinutes =\n d === 0 ? nowInTz.hour * 60 + nowInTz.minute : toMinutes + 1;\n const searchUntil = Math.min(nowMinutes, toMinutes);\n\n if (searchUntil >= fromMinutes) {\n const slotsInRange = Math.floor(\n (searchUntil - fromMinutes) / stepMinutes,\n );\n let lastSlotMinutes = fromMinutes + slotsInRange * stepMinutes;\n\n if (d === 0 && lastSlotMinutes >= nowMinutes) {\n lastSlotMinutes -= stepMinutes;\n }\n\n if (lastSlotMinutes >= fromMinutes) {\n const h = Math.floor(lastSlotMinutes / 60);\n const m = lastSlotMinutes % 60;\n return atTimeOnDate(date, toPlainTime({ hour: h, minute: m }), tz);\n }\n }\n\n date = date.subtract({ days: 1 });\n }\n\n return null;\n}\n\nfunction prevWeekRepeat(\n expr: Extract<ScheduleExpr, { type: \"weekRepeat\" }>,\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const date = nowInTz.toPlainDate();\n const { interval, days, times } = expr;\n\n const dayOfWeek = date.dayOfWeek; // 1=Mon, 7=Sun\n const currentMonday = date.subtract({ days: dayOfWeek - 1 });\n\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_MONDAY;\n const anchorDayOfWeek = anchorDate.dayOfWeek;\n const anchorMonday = anchorDate.subtract({ days: anchorDayOfWeek - 1 });\n\n // Sort days descending (latest first)\n const sortedDays = [...days].sort((a, b) => dayToNumber(b) - dayToNumber(a));\n\n let checkMonday = currentMonday;\n\n for (let w = 0; w < 54; w++) {\n const weeks = weeksBetween(anchorMonday, checkMonday);\n\n if (weeks < 0) {\n return null; // Before anchor\n }\n\n if (weeks % interval === 0) {\n for (const wd of sortedDays) {\n const dayNum = dayToNumber(wd);\n const targetDate = checkMonday.add({ days: dayNum - 1 });\n\n if (Temporal.PlainDate.compare(targetDate, date) < 0) {\n const candidate = latestAtTimes(targetDate, times, tz);\n if (candidate !== null) return candidate;\n } else if (Temporal.PlainDate.compare(targetDate, date) === 0) {\n const candidate = latestPastAtTimes(targetDate, times, tz, now);\n if (candidate !== null) return candidate;\n }\n }\n }\n\n checkMonday = checkMonday.subtract({ days: interval * 7 });\n }\n\n return null;\n}\n\nfunction prevMonthRepeat(\n expr: Extract<ScheduleExpr, { type: \"monthRepeat\" }>,\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const startDate = nowInTz.toPlainDate();\n const { interval, target, times } = expr;\n\n const anchorDate = anchor ? Temporal.PlainDate.from(anchor) : EPOCH_DATE;\n\n let year = startDate.year;\n let month = startDate.month;\n\n const maxIter = interval > 1 ? 24 * interval : 24;\n\n for (let i = 0; i < maxIter; i++) {\n if (interval > 1) {\n const monthOffset = monthsBetweenYM(\n anchorDate,\n Temporal.PlainDate.from({ year, month, day: 1 }),\n );\n if (monthOffset < 0 || monthOffset % interval !== 0) {\n ({ year, month } = prevMonth(year, month));\n continue;\n }\n }\n\n const targetDates = getMonthTargetDates(year, month, target);\n\n for (const d of targetDates.sort((a, b) =>\n Temporal.PlainDate.compare(b, a),\n )) {\n if (Temporal.PlainDate.compare(d, startDate) > 0) continue;\n if (Temporal.PlainDate.compare(d, startDate) === 0) {\n const candidate = latestPastAtTimes(d, times, tz, now);\n if (candidate !== null) return candidate;\n } else {\n const candidate = latestAtTimes(d, times, tz);\n if (candidate !== null) return candidate;\n }\n }\n\n ({ year, month } = prevMonth(year, month));\n }\n\n return null;\n}\n\nfunction prevSingleDate(\n expr: Extract<ScheduleExpr, { type: \"singleDate\" }>,\n tz: string,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const nowDate = nowInTz.toPlainDate();\n const { date: dateSpec, times } = expr;\n\n let targetDate: Temporal.PlainDate;\n\n if (dateSpec.type === \"iso\") {\n targetDate = Temporal.PlainDate.from(dateSpec.date);\n if (Temporal.PlainDate.compare(targetDate, nowDate) > 0) {\n return null; // Future date\n }\n if (Temporal.PlainDate.compare(targetDate, nowDate) === 0) {\n return latestPastAtTimes(targetDate, times, tz, now);\n }\n return latestAtTimes(targetDate, times, tz);\n } else {\n // Named date - find most recent occurrence\n const { month, day } = dateSpec;\n const monthNum = monthNumber(month);\n\n const thisYear = Temporal.PlainDate.from({\n year: nowDate.year,\n month: monthNum,\n day,\n });\n const lastYear = Temporal.PlainDate.from({\n year: nowDate.year - 1,\n month: monthNum,\n day,\n });\n\n if (Temporal.PlainDate.compare(thisYear, nowDate) < 0) {\n targetDate = thisYear;\n } else if (Temporal.PlainDate.compare(thisYear, nowDate) === 0) {\n const candidate = latestPastAtTimes(thisYear, times, tz, now);\n if (candidate !== null) return candidate;\n targetDate = lastYear;\n } else {\n targetDate = lastYear;\n }\n\n return latestAtTimes(targetDate, times, tz);\n }\n}\n\nfunction prevYearRepeat(\n expr: Extract<ScheduleExpr, { type: \"yearRepeat\" }>,\n tz: string,\n anchor: string | null,\n now: ZDT,\n): ZDT | null {\n const nowInTz = now.withTimeZone(tz);\n const startDate = nowInTz.toPlainDate();\n const startYear = startDate.year;\n const { interval, target, times } = expr;\n\n const anchorYear = anchor\n ? Temporal.PlainDate.from(anchor).year\n : EPOCH_DATE.year;\n\n const maxIter = interval > 1 ? 8 * interval : 8;\n\n for (let y = 0; y < maxIter; y++) {\n const year = startYear - y;\n\n if (interval > 1) {\n const yearOffset = year - anchorYear;\n if (yearOffset < 0 || yearOffset % interval !== 0) {\n continue;\n }\n }\n\n const targetDate = getYearTargetDate(year, target);\n\n if (targetDate !== null) {\n if (Temporal.PlainDate.compare(targetDate, startDate) > 0) {\n continue; // Future\n }\n if (Temporal.PlainDate.compare(targetDate, startDate) === 0) {\n const candidate = latestPastAtTimes(targetDate, times, tz, now);\n if (candidate !== null) return candidate;\n } else {\n const candidate = latestAtTimes(targetDate, times, tz);\n if (candidate !== null) return candidate;\n }\n }\n }\n\n return null;\n}\n\n// Helper functions for prev*\n\nfunction latestPastAtTimes(\n date: Temporal.PlainDate,\n times: TimeOfDay[],\n tz: string,\n now: ZDT,\n): ZDT | null {\n const sortedTimes = [...times].sort(\n (a, b) => b.hour * 60 + b.minute - (a.hour * 60 + a.minute),\n );\n\n for (const tod of sortedTimes) {\n const t = toPlainTime(tod);\n const candidate = atTimeOnDate(date, t, tz);\n if (Temporal.ZonedDateTime.compare(candidate, now) < 0) {\n return candidate;\n }\n }\n return null;\n}\n\nfunction latestAtTimes(\n date: Temporal.PlainDate,\n times: TimeOfDay[],\n tz: string,\n): ZDT | null {\n const sortedTimes = [...times].sort(\n (a, b) => a.hour * 60 + a.minute - (b.hour * 60 + b.minute),\n );\n\n if (sortedTimes.length === 0) return null;\n const latest = sortedTimes[sortedTimes.length - 1];\n return atTimeOnDate(date, toPlainTime(latest), tz);\n}\n\nfunction prevMonth(\n year: number,\n month: number,\n): { year: number; month: number } {\n if (month === 1) {\n return { year: year - 1, month: 12 };\n }\n return { year, month: month - 1 };\n}\n\nfunction prevDuringMonth(\n date: Temporal.PlainDate,\n during: MonthName[],\n): Temporal.PlainDate {\n let { year, month } = prevMonth(date.year, date.month);\n\n for (let i = 0; i < 12; i++) {\n const monthName = numberToMonthName(month);\n if (during.includes(monthName)) {\n return lastDayOfMonth(year, month);\n }\n ({ year, month } = prevMonth(year, month));\n }\n\n return date.subtract({ days: 1 });\n}\n\nfunction numberToMonthName(n: number): MonthName {\n const names: MonthName[] = [\n \"jan\",\n \"feb\",\n \"mar\",\n \"apr\",\n \"may\",\n \"jun\",\n \"jul\",\n \"aug\",\n \"sep\",\n \"oct\",\n \"nov\",\n \"dec\",\n ];\n return names[n - 1];\n}\n\nfunction getMonthTargetDates(\n year: number,\n month: number,\n target: MonthTarget,\n): Temporal.PlainDate[] {\n switch (target.type) {\n case \"days\": {\n const expanded = expandMonthTarget(target);\n return expanded\n .map((d) => {\n try {\n return Temporal.PlainDate.from({ year, month, day: d });\n } catch {\n return null;\n }\n })\n .filter((d): d is Temporal.PlainDate => d !== null);\n }\n case \"lastDay\":\n return [lastDayOfMonth(year, month)];\n case \"lastWeekday\":\n return [lastWeekdayOfMonth(year, month)];\n case \"nearestWeekday\": {\n const d = nearestWeekday(year, month, target.day, target.direction);\n return d ? [d] : [];\n }\n case \"ordinalWeekday\": {\n const d = getOrdinalWeekday(year, month, target.ordinal, target.weekday);\n return d ? [d] : [];\n }\n default:\n return [];\n }\n}\n\nfunction getYearTargetDate(\n year: number,\n target: YearTarget,\n): Temporal.PlainDate | null {\n switch (target.type) {\n case \"date\": {\n const monthNum = monthNumber(target.month);\n try {\n return Temporal.PlainDate.from({\n year,\n month: monthNum,\n day: target.day,\n });\n } catch {\n return null;\n }\n }\n case \"ordinalWeekday\": {\n const monthNum = monthNumber(target.month);\n return getOrdinalWeekday(year, monthNum, target.ordinal, target.weekday);\n }\n case \"dayOfMonth\": {\n const monthNum = monthNumber(target.month);\n try {\n return Temporal.PlainDate.from({\n year,\n month: monthNum,\n day: target.day,\n });\n } catch {\n return null;\n }\n }\n case \"lastWeekday\": {\n const monthNum = monthNumber(target.month);\n return lastWeekdayOfMonth(year, monthNum);\n }\n default:\n return null;\n }\n}\n\nfunction getOrdinalWeekday(\n year: number,\n month: number,\n ordinal: OrdinalPosition,\n day: Weekday,\n): Temporal.PlainDate | null {\n if (ordinal === \"last\") {\n return lastWeekdayInMonth(year, month, day);\n }\n return nthWeekdayOfMonth(year, month, day, ordinalToN(ordinal));\n}\n\nfunction dayToNumber(day: Weekday): number {\n const map: Record<Weekday, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n };\n return map[day];\n}\n\n// --- Iterator functions ---\n\n/**\n * Returns a lazy iterator of occurrences starting after `from`.\n * The iterator is unbounded for repeating schedules (will iterate forever unless limited),\n * but respects the `until` clause if specified in the schedule.\n */\nexport function* occurrences(\n schedule: ScheduleData,\n from: ZDT,\n): Generator<ZDT, void, unknown> {\n let current = from;\n for (;;) {\n const next = nextFrom(schedule, current);\n if (next === null) return;\n // Advance cursor by 1 minute to avoid returning same occurrence\n current = next.add({ minutes: 1 });\n yield next;\n }\n}\n\n/**\n * Returns a bounded iterator of occurrences where `from < occurrence <= to`.\n * The iterator yields occurrences strictly after `from` and up to and including `to`.\n */\nexport function* between(\n schedule: ScheduleData,\n from: ZDT,\n to: ZDT,\n): Generator<ZDT, void, unknown> {\n for (const dt of occurrences(schedule, from)) {\n if (Temporal.ZonedDateTime.compare(dt, to) > 0) return;\n yield dt;\n }\n}\n","import { HronError, type Span } from \"./error.js\";\n\nexport interface Token {\n kind: TokenKind;\n span: Span;\n}\n\nexport type TokenKind =\n | { type: \"every\" }\n | { type: \"on\" }\n | { type: \"at\" }\n | { type: \"from\" }\n | { type: \"to\" }\n | { type: \"in\" }\n | { type: \"of\" }\n | { type: \"the\" }\n | { type: \"last\" }\n | { type: \"except\" }\n | { type: \"until\" }\n | { type: \"starting\" }\n | { type: \"during\" }\n | { type: \"year\" }\n | { type: \"nearest\" }\n | { type: \"next\" }\n | { type: \"previous\" }\n | { type: \"day\" }\n | { type: \"weekday\" }\n | { type: \"weekend\" }\n | { type: \"weeks\" }\n | { type: \"month\" }\n | { type: \"dayName\"; name: string }\n | { type: \"monthName\"; name: string }\n | { type: \"ordinal\"; name: string }\n | { type: \"intervalUnit\"; unit: string }\n | { type: \"number\"; value: number }\n | { type: \"ordinalNumber\"; value: number }\n | { type: \"time\"; hour: number; minute: number }\n | { type: \"isoDate\"; date: string }\n | { type: \"comma\" }\n | { type: \"timezone\"; tz: string };\n\nexport function tokenize(input: string): Token[] {\n const lexer = new Lexer(input);\n return lexer.tokenize();\n}\n\nclass Lexer {\n private input: string;\n private pos: number;\n private afterIn: boolean;\n\n constructor(input: string) {\n this.input = input;\n this.pos = 0;\n this.afterIn = false;\n }\n\n tokenize(): Token[] {\n const tokens: Token[] = [];\n while (true) {\n this.skipWhitespace();\n if (this.pos >= this.input.length) break;\n\n if (this.afterIn) {\n this.afterIn = false;\n tokens.push(this.lexTimezone());\n continue;\n }\n\n const start = this.pos;\n const ch = this.input[this.pos];\n\n if (ch === \",\") {\n this.pos++;\n tokens.push({\n kind: { type: \"comma\" },\n span: { start, end: this.pos },\n });\n continue;\n }\n\n if (isDigit(ch)) {\n tokens.push(this.lexNumberOrTimeOrDate());\n continue;\n }\n\n if (isAlpha(ch)) {\n tokens.push(this.lexWord());\n continue;\n }\n\n throw HronError.lex(\n `unexpected character '${ch}'`,\n { start, end: start + 1 },\n this.input,\n );\n }\n return tokens;\n }\n\n private skipWhitespace(): void {\n while (this.pos < this.input.length && isWhitespace(this.input[this.pos])) {\n this.pos++;\n }\n }\n\n private lexTimezone(): Token {\n this.skipWhitespace();\n const start = this.pos;\n while (\n this.pos < this.input.length &&\n !isWhitespace(this.input[this.pos])\n ) {\n this.pos++;\n }\n const tz = this.input.slice(start, this.pos);\n if (tz.length === 0) {\n throw HronError.lex(\n \"expected timezone after 'in'\",\n { start, end: start + 1 },\n this.input,\n );\n }\n return { kind: { type: \"timezone\", tz }, span: { start, end: this.pos } };\n }\n\n private lexNumberOrTimeOrDate(): Token {\n const start = this.pos;\n const numStart = this.pos;\n while (this.pos < this.input.length && isDigit(this.input[this.pos])) {\n this.pos++;\n }\n const digits = this.input.slice(numStart, this.pos);\n\n // Check for ISO date: YYYY-MM-DD\n if (\n digits.length === 4 &&\n this.pos < this.input.length &&\n this.input[this.pos] === \"-\"\n ) {\n const remaining = this.input.slice(start);\n if (\n remaining.length >= 10 &&\n remaining[4] === \"-\" &&\n isDigit(remaining[5]) &&\n isDigit(remaining[6]) &&\n remaining[7] === \"-\" &&\n isDigit(remaining[8]) &&\n isDigit(remaining[9])\n ) {\n this.pos = start + 10;\n return {\n kind: { type: \"isoDate\", date: this.input.slice(start, this.pos) },\n span: { start, end: this.pos },\n };\n }\n }\n\n // Check for time: HH:MM\n if (\n (digits.length === 1 || digits.length === 2) &&\n this.pos < this.input.length &&\n this.input[this.pos] === \":\"\n ) {\n this.pos++; // skip ':'\n const minStart = this.pos;\n while (this.pos < this.input.length && isDigit(this.input[this.pos])) {\n this.pos++;\n }\n const minDigits = this.input.slice(minStart, this.pos);\n if (minDigits.length === 2) {\n const hour = parseInt(digits, 10);\n const minute = parseInt(minDigits, 10);\n if (hour > 23 || minute > 59) {\n throw HronError.lex(\n \"invalid time\",\n { start, end: this.pos },\n this.input,\n );\n }\n return {\n kind: { type: \"time\", hour, minute },\n span: { start, end: this.pos },\n };\n }\n }\n\n const num = parseInt(digits, 10);\n if (Number.isNaN(num)) {\n throw HronError.lex(\n \"invalid number\",\n { start, end: this.pos },\n this.input,\n );\n }\n\n // Check for ordinal suffix: st, nd, rd, th\n if (this.pos + 1 < this.input.length) {\n const suffix = this.input.slice(this.pos, this.pos + 2).toLowerCase();\n if (\n suffix === \"st\" ||\n suffix === \"nd\" ||\n suffix === \"rd\" ||\n suffix === \"th\"\n ) {\n this.pos += 2;\n return {\n kind: { type: \"ordinalNumber\", value: num },\n span: { start, end: this.pos },\n };\n }\n }\n\n return {\n kind: { type: \"number\", value: num },\n span: { start, end: this.pos },\n };\n }\n\n private lexWord(): Token {\n const start = this.pos;\n while (\n this.pos < this.input.length &&\n (isAlphanumeric(this.input[this.pos]) || this.input[this.pos] === \"_\")\n ) {\n this.pos++;\n }\n const word = this.input.slice(start, this.pos).toLowerCase();\n const span = { start, end: this.pos };\n\n const kind = KEYWORD_MAP[word];\n if (kind === undefined) {\n throw HronError.lex(`unknown keyword '${word}'`, span, this.input);\n }\n\n if (kind.type === \"in\") {\n this.afterIn = true;\n }\n\n return { kind, span };\n }\n}\n\nconst KEYWORD_MAP: Record<string, TokenKind> = {\n every: { type: \"every\" },\n on: { type: \"on\" },\n at: { type: \"at\" },\n from: { type: \"from\" },\n to: { type: \"to\" },\n in: { type: \"in\" },\n of: { type: \"of\" },\n the: { type: \"the\" },\n last: { type: \"last\" },\n except: { type: \"except\" },\n until: { type: \"until\" },\n starting: { type: \"starting\" },\n during: { type: \"during\" },\n year: { type: \"year\" },\n years: { type: \"year\" },\n nearest: { type: \"nearest\" },\n next: { type: \"next\" },\n previous: { type: \"previous\" },\n\n day: { type: \"day\" },\n days: { type: \"day\" },\n weekday: { type: \"weekday\" },\n weekdays: { type: \"weekday\" },\n weekend: { type: \"weekend\" },\n weekends: { type: \"weekend\" },\n weeks: { type: \"weeks\" },\n week: { type: \"weeks\" },\n month: { type: \"month\" },\n months: { type: \"month\" },\n\n monday: { type: \"dayName\", name: \"monday\" },\n mon: { type: \"dayName\", name: \"monday\" },\n tuesday: { type: \"dayName\", name: \"tuesday\" },\n tue: { type: \"dayName\", name: \"tuesday\" },\n wednesday: { type: \"dayName\", name: \"wednesday\" },\n wed: { type: \"dayName\", name: \"wednesday\" },\n thursday: { type: \"dayName\", name: \"thursday\" },\n thu: { type: \"dayName\", name: \"thursday\" },\n friday: { type: \"dayName\", name: \"friday\" },\n fri: { type: \"dayName\", name: \"friday\" },\n saturday: { type: \"dayName\", name: \"saturday\" },\n sat: { type: \"dayName\", name: \"saturday\" },\n sunday: { type: \"dayName\", name: \"sunday\" },\n sun: { type: \"dayName\", name: \"sunday\" },\n\n january: { type: \"monthName\", name: \"jan\" },\n jan: { type: \"monthName\", name: \"jan\" },\n february: { type: \"monthName\", name: \"feb\" },\n feb: { type: \"monthName\", name: \"feb\" },\n march: { type: \"monthName\", name: \"mar\" },\n mar: { type: \"monthName\", name: \"mar\" },\n april: { type: \"monthName\", name: \"apr\" },\n apr: { type: \"monthName\", name: \"apr\" },\n may: { type: \"monthName\", name: \"may\" },\n june: { type: \"monthName\", name: \"jun\" },\n jun: { type: \"monthName\", name: \"jun\" },\n july: { type: \"monthName\", name: \"jul\" },\n jul: { type: \"monthName\", name: \"jul\" },\n august: { type: \"monthName\", name: \"aug\" },\n aug: { type: \"monthName\", name: \"aug\" },\n september: { type: \"monthName\", name: \"sep\" },\n sep: { type: \"monthName\", name: \"sep\" },\n october: { type: \"monthName\", name: \"oct\" },\n oct: { type: \"monthName\", name: \"oct\" },\n november: { type: \"monthName\", name: \"nov\" },\n nov: { type: \"monthName\", name: \"nov\" },\n december: { type: \"monthName\", name: \"dec\" },\n dec: { type: \"monthName\", name: \"dec\" },\n\n first: { type: \"ordinal\", name: \"first\" },\n second: { type: \"ordinal\", name: \"second\" },\n third: { type: \"ordinal\", name: \"third\" },\n fourth: { type: \"ordinal\", name: \"fourth\" },\n fifth: { type: \"ordinal\", name: \"fifth\" },\n\n min: { type: \"intervalUnit\", unit: \"min\" },\n mins: { type: \"intervalUnit\", unit: \"min\" },\n minute: { type: \"intervalUnit\", unit: \"min\" },\n minutes: { type: \"intervalUnit\", unit: \"min\" },\n hour: { type: \"intervalUnit\", unit: \"hours\" },\n hours: { type: \"intervalUnit\", unit: \"hours\" },\n hr: { type: \"intervalUnit\", unit: \"hours\" },\n hrs: { type: \"intervalUnit\", unit: \"hours\" },\n};\n\nfunction isDigit(ch: string): boolean {\n return ch >= \"0\" && ch <= \"9\";\n}\n\nfunction isAlpha(ch: string): boolean {\n return (ch >= \"a\" && ch <= \"z\") || (ch >= \"A\" && ch <= \"Z\");\n}\n\nfunction isAlphanumeric(ch: string): boolean {\n return isDigit(ch) || isAlpha(ch);\n}\n\nfunction isWhitespace(ch: string): boolean {\n return ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\";\n}\n","// Hand-rolled recursive descent parser for hron expressions.\n\nimport type {\n DateSpec,\n DayFilter,\n DayOfMonthSpec,\n Exception,\n IntervalUnit,\n MonthName,\n MonthTarget,\n NearestDirection,\n OrdinalPosition,\n ScheduleData,\n ScheduleExpr,\n TimeOfDay,\n UntilSpec,\n Weekday,\n YearTarget,\n} from \"./ast.js\";\nimport { newScheduleData, parseMonthName, parseWeekday } from \"./ast.js\";\nimport { HronError, type Span } from \"./error.js\";\nimport { type Token, type TokenKind, tokenize } from \"./lexer.js\";\n\nclass Parser {\n private tokens: Token[];\n private pos: number;\n private input: string;\n\n constructor(tokens: Token[], input: string) {\n this.tokens = tokens;\n this.pos = 0;\n this.input = input;\n }\n\n peek(): Token | undefined {\n return this.tokens[this.pos];\n }\n\n peekKind(): TokenKind | undefined {\n return this.tokens[this.pos]?.kind;\n }\n\n advance(): Token | undefined {\n const tok = this.tokens[this.pos];\n if (tok) this.pos++;\n return tok;\n }\n\n currentSpan(): Span {\n const tok = this.peek();\n if (tok) return tok.span;\n const last = this.tokens[this.tokens.length - 1];\n if (last) return { start: last.span.end, end: last.span.end };\n return { start: 0, end: 0 };\n }\n\n error(message: string, span: Span): HronError {\n return HronError.parse(message, span, this.input);\n }\n\n errorAtEnd(message: string): HronError {\n const span =\n this.tokens.length > 0\n ? {\n start: this.tokens[this.tokens.length - 1].span.end,\n end: this.tokens[this.tokens.length - 1].span.end,\n }\n : { start: 0, end: 0 };\n return HronError.parse(message, span, this.input);\n }\n\n consumeKind(expected: string, check: (k: TokenKind) => boolean): Token {\n const span = this.currentSpan();\n const tok = this.peek();\n if (tok && check(tok.kind)) {\n this.pos++;\n return tok;\n }\n if (tok) {\n throw this.error(`expected ${expected}, got ${tok.kind.type}`, span);\n }\n throw this.errorAtEnd(`expected ${expected}`);\n }\n\n // --- Grammar productions ---\n\n parseExpression(): ScheduleData {\n const span = this.currentSpan();\n const kind = this.peekKind();\n\n let expr: ScheduleExpr;\n if (kind?.type === \"every\") {\n this.advance();\n expr = this.parseEvery();\n } else if (kind?.type === \"on\") {\n this.advance();\n expr = this.parseOn();\n } else {\n throw this.error(\"expected 'every' or 'on'\", span);\n }\n\n return this.parseTrailingClauses(expr);\n }\n\n private parseTrailingClauses(expr: ScheduleExpr): ScheduleData {\n const schedule = newScheduleData(expr);\n\n // except\n if (this.peekKind()?.type === \"except\") {\n this.advance();\n schedule.except = this.parseExceptionList();\n }\n\n // until\n if (this.peekKind()?.type === \"until\") {\n this.advance();\n schedule.until = this.parseUntilSpec();\n }\n\n // starting\n if (this.peekKind()?.type === \"starting\") {\n this.advance();\n const k = this.peekKind();\n if (k?.type === \"isoDate\") {\n const startDate = (k as { type: \"isoDate\"; date: string }).date;\n this.validateIsoDate(startDate);\n schedule.anchor = startDate;\n this.advance();\n } else {\n throw this.error(\n \"expected ISO date (YYYY-MM-DD) after 'starting'\",\n this.currentSpan(),\n );\n }\n }\n\n // during\n if (this.peekKind()?.type === \"during\") {\n this.advance();\n schedule.during = this.parseMonthList();\n }\n\n // in <timezone>\n if (this.peekKind()?.type === \"in\") {\n this.advance();\n const k = this.peekKind();\n if (k?.type === \"timezone\") {\n schedule.timezone = (k as { type: \"timezone\"; tz: string }).tz;\n this.advance();\n } else {\n throw this.error(\"expected timezone after 'in'\", this.currentSpan());\n }\n }\n\n return schedule;\n }\n\n private parseExceptionList(): Exception[] {\n const exceptions: Exception[] = [this.parseException()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n exceptions.push(this.parseException());\n }\n return exceptions;\n }\n\n private parseException(): Exception {\n const k = this.peekKind();\n if (k?.type === \"isoDate\") {\n const date = (k as { type: \"isoDate\"; date: string }).date;\n this.validateIsoDate(date);\n this.advance();\n return { type: \"iso\", date };\n }\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n );\n if (!month) throw this.error(\"invalid month name\", this.currentSpan());\n this.advance();\n const dayPos = this.currentSpan().start;\n const day = this.parseDayNumber(\n \"expected day number after month name in exception\",\n );\n this.validateNamedDate(month, day, dayPos);\n return { type: \"named\", month, day };\n }\n throw this.error(\n \"expected ISO date or month-day in exception\",\n this.currentSpan(),\n );\n }\n\n private parseUntilSpec(): UntilSpec {\n const k = this.peekKind();\n if (k?.type === \"isoDate\") {\n const date = (k as { type: \"isoDate\"; date: string }).date;\n this.validateIsoDate(date);\n this.advance();\n return { type: \"iso\", date };\n }\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n );\n if (!month) throw this.error(\"invalid month name\", this.currentSpan());\n this.advance();\n const dayPos = this.currentSpan().start;\n const day = this.parseDayNumber(\n \"expected day number after month name in until\",\n );\n this.validateNamedDate(month, day, dayPos);\n return { type: \"named\", month, day };\n }\n throw this.error(\n \"expected ISO date or month-day after 'until'\",\n this.currentSpan(),\n );\n }\n\n private parseDayNumber(errorMsg: string): number {\n const k = this.peekKind();\n if (k?.type === \"number\") {\n const n = (k as { type: \"number\"; value: number }).value;\n if (n < 1 || n > 31) {\n throw this.error(\n `invalid day number ${n} (must be 1-31)`,\n this.currentSpan(),\n );\n }\n this.advance();\n return n;\n }\n if (k?.type === \"ordinalNumber\") {\n const n = (k as { type: \"ordinalNumber\"; value: number }).value;\n if (n < 1 || n > 31) {\n throw this.error(\n `invalid day number ${n} (must be 1-31)`,\n this.currentSpan(),\n );\n }\n this.advance();\n return n;\n }\n throw this.error(errorMsg, this.currentSpan());\n }\n\n // After \"every\": dispatch\n private parseEvery(): ScheduleExpr {\n if (!this.peek()) throw this.errorAtEnd(\"expected repeater\");\n\n const k = this.peekKind();\n if (!k) throw this.errorAtEnd(\"expected repeater\");\n\n if (k.type === \"year\") {\n this.advance();\n return this.parseYearRepeat(1);\n }\n if (k.type === \"day\") {\n return this.parseDayRepeat(1, { type: \"every\" });\n }\n if (k.type === \"weekday\") {\n this.advance();\n return this.parseDayRepeat(1, { type: \"weekday\" });\n }\n if (k.type === \"weekend\") {\n this.advance();\n return this.parseDayRepeat(1, { type: \"weekend\" });\n }\n if (k.type === \"dayName\") {\n const days = this.parseDayList();\n return this.parseDayRepeat(1, { type: \"days\", days });\n }\n if (k.type === \"month\") {\n this.advance();\n return this.parseMonthRepeat(1);\n }\n if (k.type === \"number\") {\n return this.parseNumberRepeat();\n }\n\n throw this.error(\n \"expected day, weekday, weekend, year, day name, month, or number after 'every'\",\n this.currentSpan(),\n );\n }\n\n private parseDayRepeat(interval: number, days: DayFilter): ScheduleExpr {\n if (days.type === \"every\") {\n this.consumeKind(\"'day'\", (k) => k.type === \"day\");\n }\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"dayRepeat\", interval, days, times };\n }\n\n private parseNumberRepeat(): ScheduleExpr {\n const span = this.currentSpan();\n const k = this.peekKind();\n if (!k) throw this.errorAtEnd(\"expected number\");\n const num = (k as { type: \"number\"; value: number }).value;\n if (num === 0) {\n throw this.error(\"interval must be at least 1\", span);\n }\n this.advance();\n\n const next = this.peekKind();\n if (next?.type === \"weeks\") {\n this.advance();\n return this.parseWeekRepeat(num);\n }\n if (next?.type === \"intervalUnit\") {\n return this.parseIntervalRepeat(num);\n }\n if (next?.type === \"day\") {\n return this.parseDayRepeat(num, { type: \"every\" });\n }\n if (next?.type === \"month\") {\n this.advance();\n return this.parseMonthRepeat(num);\n }\n if (next?.type === \"year\") {\n this.advance();\n return this.parseYearRepeat(num);\n }\n\n throw this.error(\n \"expected 'weeks', 'min', 'minutes', 'hour', 'hours', 'day(s)', 'month(s)', or 'year(s)' after number\",\n this.currentSpan(),\n );\n }\n\n private parseIntervalRepeat(interval: number): ScheduleExpr {\n const k = this.peekKind();\n if (!k) throw this.errorAtEnd(\"expected interval unit\");\n const unitStr = (k as { type: \"intervalUnit\"; unit: string }).unit;\n this.advance();\n\n const unit: IntervalUnit = unitStr === \"min\" ? \"min\" : \"hours\";\n\n this.consumeKind(\"'from'\", (k) => k.type === \"from\");\n const from = this.parseTime();\n this.consumeKind(\"'to'\", (k) => k.type === \"to\");\n const to = this.parseTime();\n\n let dayFilter: DayFilter | null = null;\n if (this.peekKind()?.type === \"on\") {\n this.advance();\n dayFilter = this.parseDayTarget();\n }\n\n return { type: \"intervalRepeat\", interval, unit, from, to, dayFilter };\n }\n\n private parseWeekRepeat(interval: number): ScheduleExpr {\n this.consumeKind(\"'on'\", (k) => k.type === \"on\");\n const days = this.parseDayList();\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"weekRepeat\", interval, days, times };\n }\n\n private parseMonthRepeat(interval: number): ScheduleExpr {\n this.consumeKind(\"'on'\", (k) => k.type === \"on\");\n this.consumeKind(\"'the'\", (k) => k.type === \"the\");\n\n let target: MonthTarget;\n const k = this.peekKind();\n\n if (k?.type === \"last\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type === \"day\") {\n this.advance();\n target = { type: \"lastDay\" };\n } else if (next?.type === \"weekday\") {\n this.advance();\n target = { type: \"lastWeekday\" };\n } else if (next?.type === \"dayName\") {\n const weekday = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n );\n if (!weekday) throw this.error(\"invalid weekday\", this.currentSpan());\n this.advance();\n target = { type: \"ordinalWeekday\", ordinal: \"last\", weekday };\n } else {\n throw this.error(\n \"expected 'day', 'weekday', or day name after 'last'\",\n this.currentSpan(),\n );\n }\n } else if (k?.type === \"ordinal\") {\n const ordinal = this.parseOrdinalPosition();\n const next = this.peekKind();\n if (next?.type === \"dayName\") {\n const weekday = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n );\n if (!weekday) throw this.error(\"invalid weekday\", this.currentSpan());\n this.advance();\n target = { type: \"ordinalWeekday\", ordinal, weekday };\n } else {\n throw this.error(\n \"expected day name after ordinal in month expression\",\n this.currentSpan(),\n );\n }\n } else if (k?.type === \"ordinalNumber\") {\n const specs = this.parseOrdinalDayList();\n target = { type: \"days\", specs };\n } else if (\n k?.type === \"next\" ||\n k?.type === \"previous\" ||\n k?.type === \"nearest\"\n ) {\n target = this.parseNearestWeekdayTarget();\n } else {\n throw this.error(\n \"expected ordinal day (1st, 15th), 'last', ordinal weekday, or '[next|previous] nearest' after 'the'\",\n this.currentSpan(),\n );\n }\n\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"monthRepeat\", interval, target, times };\n }\n\n // [next|previous] nearest weekday to <day>\n private parseNearestWeekdayTarget(): MonthTarget {\n // Optional direction: \"next\" or \"previous\"\n let direction: NearestDirection | null = null;\n const k = this.peekKind();\n\n if (k?.type === \"next\") {\n this.advance();\n direction = \"next\";\n } else if (k?.type === \"previous\") {\n this.advance();\n direction = \"previous\";\n }\n\n this.consumeKind(\"'nearest'\", (k) => k.type === \"nearest\");\n this.consumeKind(\"'weekday'\", (k) => k.type === \"weekday\");\n this.consumeKind(\"'to'\", (k) => k.type === \"to\");\n\n const day = this.parseOrdinalDayNumber();\n\n return { type: \"nearestWeekday\", day, direction };\n }\n\n private parseOrdinalDayNumber(): number {\n const k = this.peekKind();\n if (k?.type === \"ordinalNumber\") {\n const d = (k as { type: \"ordinalNumber\"; value: number }).value;\n if (d < 1 || d > 31) {\n throw this.error(\n `invalid day number ${d} (must be 1-31)`,\n this.currentSpan(),\n );\n }\n this.advance();\n return d;\n }\n throw this.error(\"expected ordinal day number\", this.currentSpan());\n }\n\n private parseYearRepeat(interval: number): ScheduleExpr {\n this.consumeKind(\"'on'\", (k) => k.type === \"on\");\n\n let target: YearTarget;\n const k = this.peekKind();\n\n if (k?.type === \"the\") {\n this.advance();\n target = this.parseYearTargetAfterThe();\n } else if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n );\n if (!month) throw this.error(\"invalid month name\", this.currentSpan());\n this.advance();\n const dayPos = this.currentSpan().start;\n const day = this.parseDayNumber(\"expected day number after month name\");\n this.validateNamedDate(month, day, dayPos);\n target = { type: \"date\", month, day };\n } else {\n throw this.error(\n \"expected month name or 'the' after 'every year on'\",\n this.currentSpan(),\n );\n }\n\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"yearRepeat\", interval, target, times };\n }\n\n private parseYearTargetAfterThe(): YearTarget {\n const k = this.peekKind();\n\n if (k?.type === \"last\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type === \"weekday\") {\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"lastWeekday\", month };\n }\n if (next?.type === \"dayName\") {\n const weekday = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n );\n if (!weekday) throw this.error(\"invalid weekday\", this.currentSpan());\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"ordinalWeekday\", ordinal: \"last\", weekday, month };\n }\n throw this.error(\n \"expected 'weekday' or day name after 'last' in yearly expression\",\n this.currentSpan(),\n );\n }\n\n if (k?.type === \"ordinal\") {\n const ordinal = this.parseOrdinalPosition();\n const next = this.peekKind();\n if (next?.type === \"dayName\") {\n const weekday = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n );\n if (!weekday) throw this.error(\"invalid weekday\", this.currentSpan());\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n return { type: \"ordinalWeekday\", ordinal, weekday, month };\n }\n throw this.error(\n \"expected day name after ordinal in yearly expression\",\n this.currentSpan(),\n );\n }\n\n if (k?.type === \"ordinalNumber\") {\n const day = (k as { type: \"ordinalNumber\"; value: number }).value;\n if (day < 1 || day > 31) {\n throw this.error(\n `invalid day number ${day} (must be 1-31)`,\n this.currentSpan(),\n );\n }\n const dayPos = this.currentSpan().start;\n this.advance();\n this.consumeKind(\"'of'\", (k) => k.type === \"of\");\n const month = this.parseMonthNameToken();\n this.validateNamedDate(month, day, dayPos);\n return { type: \"dayOfMonth\", day, month };\n }\n\n throw this.error(\n \"expected ordinal, day number, or 'last' after 'the' in yearly expression\",\n this.currentSpan(),\n );\n }\n\n private parseMonthNameToken(): MonthName {\n const k = this.peekKind();\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n );\n if (!month) throw this.error(\"invalid month name\", this.currentSpan());\n this.advance();\n return month;\n }\n throw this.error(\"expected month name\", this.currentSpan());\n }\n\n private parseOrdinalPosition(): OrdinalPosition {\n const span = this.currentSpan();\n const k = this.peekKind();\n\n if (k?.type === \"ordinal\") {\n const name = (k as { type: \"ordinal\"; name: string }).name;\n this.advance();\n return name as OrdinalPosition;\n }\n if (k?.type === \"last\") {\n this.advance();\n return \"last\";\n }\n throw this.error(\n \"expected ordinal (first, second, third, fourth, fifth, last)\",\n span,\n );\n }\n\n private parseOn(): ScheduleExpr {\n const date = this.parseDateTarget();\n this.consumeKind(\"'at'\", (k) => k.type === \"at\");\n const times = this.parseTimeList();\n return { type: \"singleDate\", date, times };\n }\n\n private validateNamedDate(month: MonthName, day: number, pos: number): void {\n const maxDays: Record<MonthName, number> = {\n jan: 31,\n feb: 29,\n mar: 31,\n apr: 30,\n may: 31,\n jun: 30,\n jul: 31,\n aug: 31,\n sep: 30,\n oct: 31,\n nov: 30,\n dec: 31,\n };\n const max = maxDays[month];\n if (day > max) {\n throw this.error(`invalid day ${day} for ${month} (max ${max})`, {\n start: pos,\n end: pos,\n });\n }\n }\n\n private validateIsoDate(dateStr: string): void {\n const parts = dateStr.split(\"-\");\n const year = parseInt(parts[0], 10);\n const month = parseInt(parts[1], 10);\n const day = parseInt(parts[2], 10);\n if (month < 1 || month > 12 || day < 1) {\n throw this.error(`invalid date: ${dateStr}`, this.currentSpan());\n }\n const daysInMonth = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {\n daysInMonth[2] = 29;\n }\n if (day > daysInMonth[month]) {\n throw this.error(`invalid date: ${dateStr}`, this.currentSpan());\n }\n }\n\n private parseDateTarget(): DateSpec {\n const k = this.peekKind();\n\n if (k?.type === \"isoDate\") {\n const date = (k as { type: \"isoDate\"; date: string }).date;\n this.validateIsoDate(date);\n this.advance();\n return { type: \"iso\", date };\n }\n if (k?.type === \"monthName\") {\n const month = parseMonthName(\n (k as { type: \"monthName\"; name: string }).name,\n );\n if (!month) throw this.error(\"invalid month name\", this.currentSpan());\n this.advance();\n const dayPos = this.currentSpan().start;\n const day = this.parseDayNumber(\"expected day number after month name\");\n this.validateNamedDate(month, day, dayPos);\n return { type: \"named\", month, day };\n }\n throw this.error(\n \"expected date (ISO date or month name)\",\n this.currentSpan(),\n );\n }\n\n private parseDayTarget(): DayFilter {\n const k = this.peekKind();\n if (k?.type === \"day\") {\n this.advance();\n return { type: \"every\" };\n }\n if (k?.type === \"weekday\") {\n this.advance();\n return { type: \"weekday\" };\n }\n if (k?.type === \"weekend\") {\n this.advance();\n return { type: \"weekend\" };\n }\n if (k?.type === \"dayName\") {\n const days = this.parseDayList();\n return { type: \"days\", days };\n }\n throw this.error(\n \"expected 'day', 'weekday', 'weekend', or day name\",\n this.currentSpan(),\n );\n }\n\n private parseDayList(): Weekday[] {\n const k = this.peekKind();\n if (k?.type !== \"dayName\") {\n throw this.error(\"expected day name\", this.currentSpan());\n }\n const firstDay = parseWeekday(\n (k as { type: \"dayName\"; name: string }).name,\n );\n if (!firstDay) throw this.error(\"invalid weekday\", this.currentSpan());\n const days: Weekday[] = [firstDay];\n this.advance();\n\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type !== \"dayName\") {\n throw this.error(\"expected day name after ','\", this.currentSpan());\n }\n const day = parseWeekday(\n (next as { type: \"dayName\"; name: string }).name,\n );\n if (!day) throw this.error(\"invalid weekday\", this.currentSpan());\n days.push(day);\n this.advance();\n }\n return days;\n }\n\n private parseOrdinalDayList(): DayOfMonthSpec[] {\n const specs: DayOfMonthSpec[] = [this.parseOrdinalDaySpec()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n specs.push(this.parseOrdinalDaySpec());\n }\n return specs;\n }\n\n private parseOrdinalDaySpec(): DayOfMonthSpec {\n const k = this.peekKind();\n if (k?.type !== \"ordinalNumber\") {\n throw this.error(\"expected ordinal day number\", this.currentSpan());\n }\n const start = (k as { type: \"ordinalNumber\"; value: number }).value;\n if (start < 1 || start > 31) {\n throw this.error(\n `invalid day number ${start} (must be 1-31)`,\n this.currentSpan(),\n );\n }\n this.advance();\n\n if (this.peekKind()?.type === \"to\") {\n this.advance();\n const next = this.peekKind();\n if (next?.type !== \"ordinalNumber\") {\n throw this.error(\n \"expected ordinal day number after 'to'\",\n this.currentSpan(),\n );\n }\n const end = (next as { type: \"ordinalNumber\"; value: number }).value;\n if (end < 1 || end > 31) {\n throw this.error(\n `invalid day number ${end} (must be 1-31)`,\n this.currentSpan(),\n );\n }\n this.advance();\n if (start > end) {\n throw this.error(\n `invalid day range: ${start} to ${end} (start must be <= end)`,\n this.currentSpan(),\n );\n }\n return { type: \"range\", start, end };\n }\n\n return { type: \"single\", day: start };\n }\n\n private parseMonthList(): MonthName[] {\n const months: MonthName[] = [this.parseMonthNameToken()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n months.push(this.parseMonthNameToken());\n }\n return months;\n }\n\n private parseTimeList(): TimeOfDay[] {\n const times: TimeOfDay[] = [this.parseTime()];\n while (this.peekKind()?.type === \"comma\") {\n this.advance();\n times.push(this.parseTime());\n }\n return times;\n }\n\n private parseTime(): TimeOfDay {\n const span = this.currentSpan();\n const k = this.peekKind();\n if (k?.type === \"time\") {\n const { hour, minute } = k as {\n type: \"time\";\n hour: number;\n minute: number;\n };\n this.advance();\n return { hour, minute };\n }\n throw this.error(\"expected time (HH:MM)\", span);\n }\n}\n\n/** Parse an hron expression string into a ScheduleData AST. */\nexport function parse(input: string): ScheduleData {\n const tokens = tokenize(input);\n\n if (tokens.length === 0) {\n throw HronError.parse(\"empty expression\", { start: 0, end: 0 }, input);\n }\n\n const parser = new Parser(tokens, input);\n const schedule = parser.parseExpression();\n\n if (parser.peek()) {\n throw HronError.parse(\n \"unexpected tokens after expression\",\n parser.currentSpan(),\n input,\n );\n }\n\n return schedule;\n}\n"],"mappings":"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","names":["schedule","targetDate","k","import_polyfill"]}