@cronvello/sdk 0.3.0 → 0.4.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.
- package/README.md +42 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{dispatch-handler-B5b9iCyH.d.cts → dispatch-handler-yHIFEnNG.d.cts} +1 -1
- package/dist/{dispatch-handler-B5b9iCyH.d.ts → dispatch-handler-yHIFEnNG.d.ts} +1 -1
- package/dist/express.d.cts +1 -1
- package/dist/express.d.ts +1 -1
- package/dist/index.cjs +107 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +251 -3
- package/dist/index.d.ts +251 -3
- package/dist/index.js +107 -1
- package/dist/index.js.map +1 -1
- package/dist/next.d.cts +1 -1
- package/dist/next.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/cron-schedule.ts","../src/dev/dashboard-assets.ts","../src/dev/dashboard.ts","../src/internal/errors.ts","../src/internal/http.ts","../src/client/client.ts","../src/registry/format.ts","../src/index.ts","../src/cli/index.ts","../src/cli/ui.ts"],"names":["out","resolve","run","c","header","sorted","engine","startDashboard"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","file":"cli.js","sourcesContent":["/**\n * Cron schedule arithmetic for the local engine — next-occurrence, preview, and an upcoming-window\n * planner, all timezone-aware (IANA / DST) and **zero-dependency**.\n *\n * The cloud SDK only needs to *validate* a cron string (see `cron.ts`), because the server owns the\n * scheduler. The local engine has to actually *fire* jobs, so it needs the next time an expression\n * matches. This module is that calculator.\n *\n * How the timezone math works without a date library:\n * • A cron expression matches against **wall-clock** fields (the time a person reads off a clock in\n * the job's timezone), so the search is done on naive calendar fields and only converted to a\n * real epoch once a full match is found.\n * • To convert a wall-clock time in a zone to an absolute epoch we use the runtime's own IANA\n * database via `Intl.DateTimeFormat`: format a guess into the zone, measure the offset it\n * implies, and correct once. This is the standard offset-probe technique and it handles DST\n * transitions (a daily job at 04:00 stays at 04:00 local; the gap to the previous fire is 23h or\n * 25h across the spring/autumn switch).\n *\n * Supported syntax mirrors `validateCron`: 5-field crontab, an optional leading seconds field\n * (6 fields), the `@macros`, month/weekday names, and `*` / ranges / lists / steps. Day-of-month and\n * day-of-week combine with Vixie cron's OR semantics when both are restricted.\n */\n\nconst MACRO_EXPANSIONS: Record<string, string> = {\n \"@yearly\": \"0 0 1 1 *\",\n \"@annually\": \"0 0 1 1 *\",\n \"@monthly\": \"0 0 1 * *\",\n \"@weekly\": \"0 0 * * 0\",\n \"@daily\": \"0 0 * * *\",\n \"@midnight\": \"0 0 * * *\",\n \"@hourly\": \"0 * * * *\",\n};\n\nconst MONTH_NAMES = [\"jan\", \"feb\", \"mar\", \"apr\", \"may\", \"jun\", \"jul\", \"aug\", \"sep\", \"oct\", \"nov\", \"dec\"];\nconst DOW_NAMES = [\"sun\", \"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\"];\n\ninterface FieldSpec {\n min: number;\n max: number;\n names?: string[];\n /** Offset added to a resolved name index (months are 1-based, weekdays 0-based). */\n nameOffset: number;\n /** Map an expanded value into its canonical form (used to fold weekday 7 → 0). */\n fold?: (v: number) => number;\n label: string;\n}\n\nconst SECOND_SPEC: FieldSpec = { min: 0, max: 59, nameOffset: 0, label: \"second\" };\nconst MINUTE_SPEC: FieldSpec = { min: 0, max: 59, nameOffset: 0, label: \"minute\" };\nconst HOUR_SPEC: FieldSpec = { min: 0, max: 23, nameOffset: 0, label: \"hour\" };\nconst DOM_SPEC: FieldSpec = { min: 1, max: 31, nameOffset: 0, label: \"day-of-month\" };\nconst MONTH_SPEC: FieldSpec = { min: 1, max: 12, names: MONTH_NAMES, nameOffset: 1, label: \"month\" };\nconst DOW_SPEC: FieldSpec = { min: 0, max: 7, names: DOW_NAMES, nameOffset: 0, fold: (v) => v % 7, label: \"day-of-week\" };\n\n/** A cron expression compiled into the set of values each field matches. */\nexport interface ParsedCron {\n /** Allowed seconds. For a 5-field expression this is `{0}`. */\n seconds: Set<number>;\n minutes: Set<number>;\n hours: Set<number>;\n daysOfMonth: Set<number>;\n months: Set<number>;\n /** Allowed weekdays, 0 = Sunday … 6 = Saturday (7 is folded to 0). */\n daysOfWeek: Set<number>;\n /** True when the day-of-month field was anything other than `*`/`?`. */\n domRestricted: boolean;\n /** True when the day-of-week field was anything other than `*`/`?`. */\n dowRestricted: boolean;\n /** True for `@reboot`, which has no scheduled next time (the engine fires it once at start). */\n reboot: boolean;\n}\n\n/** Parse a cron expression into matchable value-sets. Throws on a malformed expression. */\nexport function parseCron(expr: string): ParsedCron {\n if (typeof expr !== \"string\" || !expr.trim()) throw new Error(\"cron expression is empty\");\n let trimmed = expr.trim();\n\n if (trimmed.startsWith(\"@\")) {\n const macro = trimmed.toLowerCase();\n if (macro === \"@reboot\") {\n return {\n seconds: new Set([0]), minutes: new Set(), hours: new Set(), daysOfMonth: new Set(),\n months: new Set(), daysOfWeek: new Set(), domRestricted: false, dowRestricted: false, reboot: true,\n };\n }\n const expanded = MACRO_EXPANSIONS[macro];\n if (!expanded) throw new Error(`unknown cron macro \"${trimmed}\" (try @daily, @hourly, …)`);\n trimmed = expanded;\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5 && parts.length !== 6) {\n throw new Error(`expected 5 fields (min hour dom month dow) or 6 with seconds, got ${parts.length}: \"${trimmed}\"`);\n }\n\n const hasSeconds = parts.length === 6;\n const [secRaw, minRaw, hourRaw, domRaw, monthRaw, dowRaw] = hasSeconds\n ? parts\n : [\"0\", ...parts];\n\n return {\n seconds: expandField(secRaw!, SECOND_SPEC),\n minutes: expandField(minRaw!, MINUTE_SPEC),\n hours: expandField(hourRaw!, HOUR_SPEC),\n daysOfMonth: expandField(domRaw!, DOM_SPEC),\n months: expandField(monthRaw!, MONTH_SPEC),\n daysOfWeek: expandField(dowRaw!, DOW_SPEC),\n domRestricted: isRestricted(domRaw!),\n dowRestricted: isRestricted(dowRaw!),\n reboot: false,\n };\n}\n\nfunction isRestricted(field: string): boolean {\n const f = field.trim();\n return f !== \"*\" && f !== \"?\";\n}\n\n/** Expand one comma-separated field (`*`, ranges, lists, steps, names) into its value set. */\nfunction expandField(raw: string, spec: FieldSpec): Set<number> {\n const set = new Set<number>();\n for (const term of raw.split(\",\")) {\n if (term === \"\") throw new Error(`empty term in ${spec.label} field \"${raw}\"`);\n\n let base = term;\n let step = 1;\n const slash = term.indexOf(\"/\");\n if (slash >= 0) {\n base = term.slice(0, slash);\n const stepStr = term.slice(slash + 1);\n if (!/^\\d+$/.test(stepStr) || Number(stepStr) === 0) {\n throw new Error(`invalid step \"${stepStr}\" in ${spec.label} field \"${raw}\"`);\n }\n step = Number(stepStr);\n }\n\n let lo: number | null;\n let hi: number | null;\n if (base === \"*\" || base === \"?\") {\n lo = spec.min;\n hi = spec.max;\n } else {\n const dash = base.indexOf(\"-\");\n if (dash > 0) {\n lo = resolveValue(base.slice(0, dash), spec);\n hi = resolveValue(base.slice(dash + 1), spec);\n } else {\n lo = resolveValue(base, spec);\n // A bare value with a step (e.g. \"5/15\") runs from the value up to the field max.\n hi = step > 1 ? spec.max : lo;\n }\n }\n\n if (lo === null || hi === null) {\n throw new Error(`value out of range in ${spec.label} field \"${raw}\" (${spec.min}-${spec.max})`);\n }\n if (lo > hi) throw new Error(`range start ${lo} is greater than end ${hi} in ${spec.label} field \"${raw}\"`);\n\n for (let v = lo; v <= hi; v += step) set.add(spec.fold ? spec.fold(v) : v);\n }\n return set;\n}\n\n/** Resolve a numeric or named token to its number, or null when out of range / unknown. */\nfunction resolveValue(token: string, spec: FieldSpec): number | null {\n const t = token.trim();\n if (/^\\d+$/.test(t)) {\n const n = Number(t);\n return n >= spec.min && n <= spec.max ? n : null;\n }\n if (spec.names) {\n const idx = spec.names.indexOf(t.toLowerCase());\n if (idx >= 0) return idx + spec.nameOffset;\n }\n return null;\n}\n\n// ─── Next-occurrence search ──────────────────────────────────────────────────\n\nexport interface NextOccurrenceOptions {\n /** Search strictly after this instant (epoch ms or Date). Defaults to now. */\n from?: Date | number;\n /** IANA timezone the expression is read in. Defaults to \"UTC\". */\n timeZone?: string;\n}\n\n/** How many years ahead the search gives up after — a guard against impossible expressions. */\nconst SEARCH_HORIZON_YEARS = 5;\n\n/**\n * The next instant the expression fires, strictly after `from`, in the given timezone — or `null`\n * when nothing matches within {@link SEARCH_HORIZON_YEARS} (e.g. Feb-30). Throws for `@reboot`.\n */\nexport function nextOccurrence(expr: string | ParsedCron, opts: NextOccurrenceOptions = {}): Date | null {\n const parsed = typeof expr === \"string\" ? parseCron(expr) : expr;\n if (parsed.reboot) throw new Error(\"@reboot has no scheduled next occurrence (the engine fires it once at start)\");\n\n const tz = opts.timeZone ?? \"UTC\";\n const fromMs = opts.from === undefined ? Date.now() : typeof opts.from === \"number\" ? opts.from : opts.from.getTime();\n\n // Move strictly forward by at least one whole second, then search on wall-clock fields.\n const cursor = Math.floor(fromMs / 1000) * 1000 + 1000;\n const p = getZonedParts(cursor, tz);\n const startYear = p.y;\n\n const hourArr = sorted(parsed.hours);\n const minuteArr = sorted(parsed.minutes);\n const secondArr = sorted(parsed.seconds);\n\n let guard = 0;\n while (guard++ < 1_000_000) {\n if (p.y > startYear + SEARCH_HORIZON_YEARS) return null;\n\n if (!parsed.months.has(p.mo)) {\n bumpMonth(p);\n continue;\n }\n if (p.d > daysInMonth(p.y, p.mo)) {\n bumpMonth(p);\n continue;\n }\n if (!dayMatches(parsed, p.y, p.mo, p.d)) {\n bumpDay(p);\n continue;\n }\n const nh = firstAtLeast(hourArr, p.h);\n if (nh === null) {\n bumpDay(p);\n continue;\n }\n if (nh !== p.h) {\n p.h = nh;\n p.mi = 0;\n p.s = 0;\n }\n const nmi = firstAtLeast(minuteArr, p.mi);\n if (nmi === null) {\n p.h += 1;\n p.mi = 0;\n p.s = 0;\n continue;\n }\n if (nmi !== p.mi) {\n p.mi = nmi;\n p.s = 0;\n }\n const ns = firstAtLeast(secondArr, p.s);\n if (ns === null) {\n p.mi += 1;\n p.s = 0;\n continue;\n }\n p.s = ns;\n\n // Full wall-clock match — convert to a real epoch in the zone.\n const epoch = zonedWallToEpoch(p, tz);\n // Guard against a DST fold mapping the candidate back to or before `from`.\n if (epoch <= fromMs) {\n p.s += 1;\n continue;\n }\n return new Date(epoch);\n }\n throw new Error(`nextOccurrence: search exceeded its iteration bound for \"${typeof expr === \"string\" ? expr : \"(parsed)\"}\"`);\n}\n\n/** Whether a day satisfies the day-of-month / day-of-week fields, with Vixie OR semantics. */\nfunction dayMatches(parsed: ParsedCron, y: number, mo: number, d: number): boolean {\n const domOk = parsed.daysOfMonth.has(d);\n const dowOk = parsed.daysOfWeek.has(weekdayOf(y, mo, d));\n if (parsed.domRestricted && parsed.dowRestricted) return domOk || dowOk;\n if (parsed.domRestricted) return domOk;\n if (parsed.dowRestricted) return dowOk;\n return true;\n}\n\ninterface WallParts {\n y: number;\n mo: number;\n d: number;\n h: number;\n mi: number;\n s: number;\n}\n\nfunction bumpMonth(p: WallParts): void {\n p.mo += 1;\n if (p.mo > 12) {\n p.mo = 1;\n p.y += 1;\n }\n p.d = 1;\n p.h = 0;\n p.mi = 0;\n p.s = 0;\n}\n\nfunction bumpDay(p: WallParts): void {\n p.d += 1;\n p.h = 0;\n p.mi = 0;\n p.s = 0;\n}\n\nfunction sorted(set: Set<number>): number[] {\n return [...set].sort((a, b) => a - b);\n}\n\n/** Smallest array element ≥ `v` (array is sorted ascending), or null. */\nfunction firstAtLeast(arr: number[], v: number): number | null {\n for (const x of arr) if (x >= v) return x;\n return null;\n}\n\nfunction daysInMonth(year: number, month: number): number {\n return new Date(Date.UTC(year, month, 0)).getUTCDate();\n}\n\nfunction weekdayOf(year: number, month: number, day: number): number {\n return new Date(Date.UTC(year, month - 1, day)).getUTCDay();\n}\n\n// ─── Timezone conversion (Intl-based, zero-dependency) ───────────────────────\n\nconst FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nfunction formatterFor(timeZone: string): Intl.DateTimeFormat {\n let fmt = FORMATTER_CACHE.get(timeZone);\n if (!fmt) {\n fmt = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n FORMATTER_CACHE.set(timeZone, fmt);\n }\n return fmt;\n}\n\n/** The wall-clock calendar fields a clock in `timeZone` shows at the given epoch. */\nfunction getZonedParts(epochMs: number, timeZone: string): WallParts {\n const parts = formatterFor(timeZone).formatToParts(new Date(epochMs));\n const m: Record<string, string> = {};\n for (const part of parts) if (part.type !== \"literal\") m[part.type] = part.value;\n let h = Number(m[\"hour\"]);\n if (h === 24) h = 0; // some runtimes render midnight as \"24\" under hour12:false\n return { y: Number(m[\"year\"]), mo: Number(m[\"month\"]), d: Number(m[\"day\"]), h, mi: Number(m[\"minute\"]), s: Number(m[\"second\"]) };\n}\n\n/** Offset (ms) the zone is ahead of UTC at the given instant. */\nfunction offsetAt(epochMs: number, timeZone: string): number {\n const p = getZonedParts(epochMs, timeZone);\n const asNaive = Date.UTC(p.y, p.mo - 1, p.d, p.h, p.mi, p.s);\n return asNaive - epochMs;\n}\n\n/** Convert wall-clock fields in `timeZone` to an absolute epoch, correcting for the zone's offset. */\nfunction zonedWallToEpoch(p: WallParts, timeZone: string): number {\n const asUTC = Date.UTC(p.y, p.mo - 1, p.d, p.h, p.mi, p.s);\n const o1 = offsetAt(asUTC, timeZone);\n let epoch = asUTC - o1;\n const o2 = offsetAt(epoch, timeZone);\n if (o2 !== o1) epoch = asUTC - o2;\n return epoch;\n}\n\n// ─── Preview & upcoming-window planning ──────────────────────────────────────\n\nexport interface PreviewOptions {\n /** Start the preview after this instant. Defaults to now. */\n from?: Date | number;\n /** IANA timezone. Defaults to the runtime's local zone. */\n timeZone?: string;\n /** How many fire times to return (default 5, capped at 100). */\n count?: number;\n}\n\n/** The next N times an expression fires — the engine of `cronvello preview`. */\nexport function previewSchedule(expr: string, opts: PreviewOptions = {}): Date[] {\n const parsed = parseCron(expr);\n const timeZone = opts.timeZone ?? localTimeZone();\n const count = Math.min(Math.max(Math.trunc(opts.count ?? 5), 1), 100);\n const out: Date[] = [];\n let from = opts.from === undefined ? Date.now() : typeof opts.from === \"number\" ? opts.from : opts.from.getTime();\n for (let i = 0; i < count; i++) {\n const next = nextOccurrence(parsed, { from, timeZone });\n if (!next) break;\n out.push(next);\n from = next.getTime();\n }\n return out;\n}\n\nexport interface UpcomingJob {\n key: string;\n schedule: string;\n timeZone: string;\n}\n\nexport interface UpcomingFire {\n key: string;\n time: Date;\n schedule: string;\n timeZone: string;\n}\n\nexport interface UpcomingOptions {\n /** Window start (defaults to now). */\n from?: Date | number;\n /** Window length in ms (defaults to 1 hour). */\n withinMs?: number;\n /** Cap per job so a per-second schedule can't flood the plan (default 50). */\n maxPerJob?: number;\n}\n\n/**\n * Every fire across a set of jobs within the next window, merged and sorted by time — what powers\n * `cronvello dev --dry-run`. Jobs whose schedule can't be parsed are skipped (a dev concern surfaced\n * elsewhere); `@reboot` jobs are skipped because they have no scheduled time.\n */\nexport function upcomingFires(jobs: UpcomingJob[], opts: UpcomingOptions = {}): UpcomingFire[] {\n const from = opts.from === undefined ? Date.now() : typeof opts.from === \"number\" ? opts.from : opts.from.getTime();\n const withinMs = opts.withinMs ?? 60 * 60 * 1000;\n const maxPerJob = Math.max(1, opts.maxPerJob ?? 50);\n const horizon = from + withinMs;\n\n const fires: UpcomingFire[] = [];\n for (const job of jobs) {\n let parsed: ParsedCron;\n try {\n parsed = parseCron(job.schedule);\n } catch {\n continue;\n }\n if (parsed.reboot) continue;\n let cursor = from;\n for (let i = 0; i < maxPerJob; i++) {\n const next = nextOccurrence(parsed, { from: cursor, timeZone: job.timeZone });\n if (!next || next.getTime() > horizon) break;\n fires.push({ key: job.key, time: next, schedule: job.schedule, timeZone: job.timeZone });\n cursor = next.getTime();\n }\n }\n fires.sort((a, b) => a.time.getTime() - b.time.getTime());\n return fires;\n}\n\n/** The runtime's local IANA zone, falling back to UTC if it can't be resolved. */\nexport function localTimeZone(): string {\n try {\n return new Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\";\n } catch {\n return \"UTC\";\n }\n}\n","/**\n * The local dashboard's single-page UI — one self-contained HTML document with inline CSS and\n * vanilla JavaScript, no framework and no build step. It is served verbatim by\n * {@link ./dashboard.ts}, talks only to that server's same-origin JSON + SSE API, and never reaches\n * the network. Kept as a string constant (not a file read) so it works regardless of the bundled\n * `dist/` layout, and so it only loads when the dashboard is actually started.\n *\n * Two things shape the implementation:\n *\n * - **One read model.** Everything on screen comes from a single `/api/state` snapshot. The live\n * event stream appends to the feed and marks the snapshot stale; a debounced refetch reconciles.\n * Nothing re-renders per event.\n * - **The timeline is a fixed track that slides.** Run and fire positions are absolute in time, so\n * they are written once per snapshot; the passing second is a single `translateX` on the track\n * rather than a repositioning pass over every mark.\n *\n * Branding follows BRAND.md: indigo primary, teal/green for healthy runs, amber for retries, red for\n * failures, slate neutrals, light + dark, monospace for cron expressions.\n */\nexport const DASHBOARD_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<meta name=\"robots\" content=\"noindex\" />\n<title>Cronvello — local engine</title>\n<style>\n :root {\n --indigo: #4F46E5;\n --indigo-soft: #6366F1;\n --teal: #14B8A6;\n --green: #10B981;\n --amber: #F59E0B;\n --red: #EF4444;\n --bg: #f7f8fa;\n --panel: #ffffff;\n --panel-2: #f1f5f9;\n --panel-3: #e9edf3;\n --border: #e3e8ef;\n --border-strong: #cbd5e1;\n --text: #0f172a;\n --muted: #64748b;\n --faint: #94a3b8;\n --shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.06);\n --focus: rgba(79, 70, 229, 0.35);\n }\n [data-theme=\"dark\"] {\n --bg: #0a0f1c;\n --panel: #111827;\n --panel-2: #161f2f;\n --panel-3: #1c2740;\n --border: #1f2937;\n --border-strong: #334155;\n --text: #e6e9ef;\n --muted: #94a3b8;\n --faint: #64748b;\n --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.35);\n --focus: rgba(99, 102, 241, 0.45);\n }\n /* Dark-mode-first: follow the OS preference unless the user has explicitly chosen light. */\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n --bg: #0a0f1c;\n --panel: #111827;\n --panel-2: #161f2f;\n --panel-3: #1c2740;\n --border: #1f2937;\n --border-strong: #334155;\n --text: #e6e9ef;\n --muted: #94a3b8;\n --faint: #64748b;\n --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.35);\n --focus: rgba(99, 102, 241, 0.45);\n }\n }\n\n * { box-sizing: border-box; }\n html, body { margin: 0; padding: 0; }\n body {\n background: var(--bg);\n color: var(--text);\n font-family: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Inter, Roboto, sans-serif;\n font-size: 13.5px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n }\n code, .mono, .num {\n font-family: ui-monospace, \"SF Mono\", \"JetBrains Mono\", Menlo, Consolas, monospace;\n font-variant-numeric: tabular-nums;\n }\n .num { font-variant-numeric: tabular-nums; }\n :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }\n\n /* ── Header ─────────────────────────────────────────────────────────────── */\n header.top {\n display: flex; align-items: center; gap: 12px;\n padding: 0 20px; height: 52px;\n border-bottom: 1px solid var(--border);\n background: var(--panel);\n position: sticky; top: 0; z-index: 20;\n }\n .mark {\n width: 26px; height: 26px; border-radius: 7px; flex: none;\n display: grid; place-items: center;\n background: linear-gradient(140deg, var(--indigo), var(--teal));\n color: #fff;\n }\n .mark svg { width: 15px; height: 15px; }\n .wordmark { font-weight: 650; letter-spacing: -0.012em; font-size: 14px; }\n .wordmark span { color: var(--muted); font-weight: 450; margin-left: 7px; }\n .spacer { flex: 1; }\n\n .chip {\n display: inline-flex; align-items: center; gap: 7px;\n height: 26px; padding: 0 10px; border-radius: 7px;\n font-size: 12px; font-weight: 500;\n border: 1px solid var(--border); background: var(--panel-2); color: var(--muted);\n white-space: nowrap;\n }\n .chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); flex: none; }\n .chip.live .dot { background: var(--green); animation: pulse 2.4s ease-out infinite; }\n .chip.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, var(--border)); }\n .chip.down .dot { background: var(--red); }\n @keyframes pulse {\n 0% { box-shadow: 0 0 0 0 rgba(16,185,129,0.45); }\n 70% { box-shadow: 0 0 0 5px rgba(16,185,129,0); }\n 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); }\n }\n\n button {\n font: inherit; cursor: pointer; color: var(--text);\n background: var(--panel-2); border: 1px solid var(--border);\n border-radius: 7px; padding: 5px 11px;\n transition: background-color .12s ease, border-color .12s ease;\n }\n button:hover:not(:disabled) { background: var(--panel-3); border-color: var(--border-strong); }\n button:disabled { opacity: .55; cursor: default; }\n button.primary { background: var(--indigo); color: #fff; border-color: var(--indigo); }\n button.primary:hover:not(:disabled) { background: var(--indigo-soft); border-color: var(--indigo-soft); }\n button.icon { padding: 5px 7px; line-height: 0; color: var(--muted); }\n button.icon svg { width: 15px; height: 15px; display: block; }\n button.ghost { background: transparent; border-color: transparent; color: var(--muted); }\n button.ghost:hover:not(:disabled) { background: var(--panel-2); border-color: var(--border); }\n button.tiny { font-size: 11.5px; padding: 3px 8px; border-radius: 6px; }\n\n main { padding: 16px 20px 8px; display: flex; flex-direction: column; gap: 14px; }\n\n /* ── Stat row ───────────────────────────────────────────────────────────── */\n .stats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; }\n @media (max-width: 900px) { .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }\n .stat {\n background: var(--panel); border: 1px solid var(--border); border-radius: 10px;\n padding: 11px 13px; box-shadow: var(--shadow); min-width: 0;\n }\n .stat .label {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--faint); font-weight: 600;\n }\n .stat .value {\n margin-top: 3px; font-size: 21px; font-weight: 600; letter-spacing: -0.02em;\n font-variant-numeric: tabular-nums; line-height: 1.2;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .stat .sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .stat.ok .value { color: var(--green); }\n .stat.bad .value { color: var(--red); }\n .stat.bad.zero .value { color: var(--text); }\n\n /* ── Cards ──────────────────────────────────────────────────────────────── */\n .card {\n background: var(--panel); border: 1px solid var(--border); border-radius: 11px;\n box-shadow: var(--shadow); overflow: hidden; min-width: 0;\n }\n .card > .head {\n display: flex; align-items: center; gap: 10px;\n padding: 9px 14px; border-bottom: 1px solid var(--border);\n background: var(--panel);\n }\n .card > .head h2 {\n margin: 0; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--muted); font-weight: 650;\n }\n .card > .head .hint { font-size: 11.5px; color: var(--faint); }\n select {\n font: inherit; font-size: 11.5px; color: var(--muted); cursor: pointer;\n background: var(--panel-2); border: 1px solid var(--border); border-radius: 6px; padding: 3px 6px;\n }\n\n /* ── Timeline ───────────────────────────────────────────────────────────── */\n .tl { display: flex; align-items: stretch; }\n .tl-gutter {\n flex: none; width: 168px; border-right: 1px solid var(--border);\n background: var(--panel); padding-bottom: 8px;\n }\n @media (max-width: 700px) { .tl-gutter { width: 108px; } }\n .tl-gutter .axis-pad { height: 22px; border-bottom: 1px solid var(--border); }\n .tl-gutter .lane-label {\n height: 26px; display: flex; align-items: center; padding: 0 12px;\n font-size: 12px; font-weight: 550;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .tl-viewport { position: relative; flex: 1; overflow: hidden; padding-bottom: 8px; min-width: 0; }\n .tl-track { position: relative; width: 100%; will-change: transform; }\n .tl-axis { position: relative; height: 22px; border-bottom: 1px solid var(--border); }\n .tl-axis .gl {\n position: absolute; top: 0; bottom: -1000px; width: 1px;\n background: var(--border); opacity: .75;\n }\n .tl-axis .gt {\n position: absolute; top: 4px; font-size: 10.5px; color: var(--faint);\n transform: translateX(4px); white-space: nowrap; font-variant-numeric: tabular-nums;\n }\n .tl-lane { position: relative; height: 26px; }\n .tl-lane + .tl-lane { border-top: 1px dashed transparent; }\n .tl-lane:hover { background: color-mix(in srgb, var(--panel-2) 60%, transparent); }\n .mk { position: absolute; top: 7px; height: 12px; border-radius: 2px; }\n .mk.run { width: 4px; margin-left: -2px; }\n .mk.success { background: var(--green); }\n .mk.error, .mk.timed_out { background: var(--red); }\n .mk.skipped { background: var(--faint); }\n .mk.retried { background: var(--amber); }\n .mk.up {\n width: 0; height: 12px; margin-left: -1px;\n border-left: 1px dashed var(--border-strong); border-radius: 0; opacity: .5;\n }\n .mk.up.first { border-left-color: var(--indigo-soft); border-left-style: solid; opacity: 1; }\n .lane-note {\n position: absolute; right: 8px; top: 6px;\n font-size: 10.5px; color: var(--faint); white-space: nowrap;\n font-variant-numeric: tabular-nums; pointer-events: none;\n }\n .tl-now {\n position: absolute; left: 50%; top: 0; bottom: 0; width: 1px;\n background: var(--indigo); opacity: .75; pointer-events: none; z-index: 3;\n }\n .tl-now::before {\n content: \"\"; position: absolute; top: 0; left: -3px;\n border: 3.5px solid transparent; border-top-color: var(--indigo);\n }\n .tl-empty { padding: 22px 16px; color: var(--muted); text-align: center; font-size: 12.5px; }\n .tl-legend { display: flex; gap: 14px; align-items: center; font-size: 11px; color: var(--faint); }\n .tl-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }\n @media (max-width: 700px) { .tl-legend { display: none; } }\n\n /* ── Grid ───────────────────────────────────────────────────────────────── */\n .grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 14px; align-items: start; }\n @media (max-width: 980px) { .grid { grid-template-columns: minmax(0, 1fr); } }\n\n /* ── Jobs table ─────────────────────────────────────────────────────────── */\n table { width: 100%; border-collapse: collapse; }\n th, td { text-align: left; padding: 9px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }\n th {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.055em;\n color: var(--faint); font-weight: 650; padding-top: 8px; padding-bottom: 8px;\n }\n tbody tr:last-child td { border-bottom: none; }\n tbody tr.job { cursor: pointer; }\n tbody tr.job:hover { background: var(--panel-2); }\n tbody tr.job.is-running { background: color-mix(in srgb, var(--indigo) 6%, transparent); }\n .jobkey { font-weight: 600; }\n .jobdesc { color: var(--muted); font-size: 11.5px; margin-top: 1px; }\n td.sched code { font-size: 12px; color: var(--muted); }\n td.next { white-space: nowrap; }\n td.act { text-align: right; width: 1%; white-space: nowrap; }\n tbody tr.job .act button { opacity: 0; transition: opacity .12s ease; }\n tbody tr.job:hover .act button, tbody tr.job .act button:focus-visible { opacity: 1; }\n @media (hover: none) { tbody tr.job .act button { opacity: 1; } }\n\n .badge {\n display: inline-block; padding: 1.5px 8px; border-radius: 999px;\n font-size: 10.5px; font-weight: 650; letter-spacing: 0.01em;\n }\n .badge.success { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green); }\n .badge.error, .badge.timed_out { background: color-mix(in srgb, var(--red) 16%, transparent); color: var(--red); }\n .badge.skipped { background: color-mix(in srgb, var(--faint) 20%, transparent); color: var(--muted); }\n .badge.running { background: color-mix(in srgb, var(--indigo) 16%, transparent); color: var(--indigo-soft); }\n .badge.none { background: var(--panel-2); color: var(--faint); }\n\n /* ── Feed ───────────────────────────────────────────────────────────────── */\n .feed { max-height: 62vh; overflow-y: auto; overscroll-behavior: contain; }\n .ev {\n display: flex; gap: 9px; align-items: baseline;\n padding: 7px 14px; border-bottom: 1px solid var(--border); font-size: 12.5px;\n }\n .ev:last-child { border-bottom: none; }\n .ev .glyph { width: 13px; text-align: center; flex: none; font-size: 11px; }\n .ev .body { flex: 1; min-width: 0; overflow-wrap: anywhere; }\n .ev .when { color: var(--faint); font-size: 10.5px; font-variant-numeric: tabular-nums; flex: none; }\n .ev .k { font-weight: 600; }\n .ev.success .glyph { color: var(--green); }\n .ev.error .glyph, .ev.timeout .glyph { color: var(--red); }\n .ev.retry .glyph { color: var(--amber); }\n .ev.fire .glyph { color: var(--indigo-soft); }\n .ev.skipped .glyph, .ev.engine .glyph { color: var(--faint); }\n .ev .detail { color: var(--muted); }\n .paused-note {\n padding: 6px 14px; font-size: 11.5px; color: var(--amber);\n background: color-mix(in srgb, var(--amber) 10%, transparent);\n border-bottom: 1px solid var(--border);\n }\n\n .empty { padding: 26px 16px; color: var(--muted); text-align: center; font-size: 12.5px; }\n .empty .lead { color: var(--text); font-weight: 550; margin-bottom: 3px; }\n\n footer {\n padding: 14px 20px 30px; color: var(--faint); font-size: 11.5px;\n display: flex; gap: 8px; flex-wrap: wrap; align-items: center;\n }\n footer .sep { opacity: .5; }\n\n /* ── Drawer ─────────────────────────────────────────────────────────────── */\n .overlay {\n position: fixed; inset: 0; background: rgba(2, 6, 23, 0.5);\n display: none; justify-content: flex-end; z-index: 40;\n }\n .overlay.open { display: flex; }\n .drawer {\n width: min(560px, 94vw); background: var(--panel); border-left: 1px solid var(--border);\n height: 100%; overflow-y: auto; display: flex; flex-direction: column;\n }\n .drawer .dhead {\n display: flex; align-items: center; gap: 10px; padding: 12px 16px;\n border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--panel); z-index: 2;\n }\n .drawer .dtitle { font-weight: 650; letter-spacing: -0.01em; }\n .drawer .pad { padding: 16px; }\n .kv { display: flex; gap: 10px; padding: 5px 0; font-size: 12.5px; }\n .kv > span:first-child { color: var(--muted); min-width: 92px; flex: none; }\n .section-title {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--faint); font-weight: 650; margin: 20px 0 7px;\n }\n ul.plain { list-style: none; margin: 0; padding: 0; }\n ul.plain > li {\n padding: 7px 0; border-bottom: 1px solid var(--border);\n display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px;\n }\n ul.plain > li:last-child { border-bottom: none; }\n .runline { display: block; }\n .runline .row1 { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }\n .runline .meta { color: var(--faint); font-size: 11px; font-variant-numeric: tabular-nums; }\n .runline pre {\n margin: 6px 0 0; padding: 8px 10px; border-radius: 7px;\n background: var(--panel-2); border: 1px solid var(--border);\n font-size: 11.5px; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 180px; overflow: auto;\n }\n .runline pre.err { color: var(--red); border-color: color-mix(in srgb, var(--red) 30%, var(--border)); }\n</style>\n</head>\n<body>\n\n<header class=\"top\">\n <div class=\"mark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 7.2V12l3.4 2\"></path></svg>\n </div>\n <div class=\"wordmark\">Cronvello <span>local engine</span></div>\n <span id=\"engine-chip\" class=\"chip\"><span class=\"dot\"></span><span id=\"engine-text\">starting…</span></span>\n <div class=\"spacer\"></div>\n <span id=\"conn\" class=\"chip\"><span class=\"dot\"></span><span id=\"conn-text\">connecting…</span></span>\n <button id=\"theme-btn\" class=\"icon\" title=\"Toggle light / dark\" aria-label=\"Toggle light or dark theme\">\n <svg id=\"icon-moon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 14.5A8.5 8.5 0 0 1 9.5 4a8.5 8.5 0 1 0 10.5 10.5Z\"></path></svg>\n <svg id=\"icon-sun\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" hidden><circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4\"></path></svg>\n </button>\n</header>\n\n<main>\n <section class=\"stats\" aria-label=\"Engine summary\">\n <div class=\"stat\"><div class=\"label\">Jobs</div><div class=\"value num\" id=\"s-jobs\">—</div><div class=\"sub\" id=\"s-jobs-sub\"> </div></div>\n <div class=\"stat\"><div class=\"label\">Runs this session</div><div class=\"value num\" id=\"s-runs\">—</div><div class=\"sub\" id=\"s-runs-sub\"> </div></div>\n <div class=\"stat ok\"><div class=\"label\">Succeeded</div><div class=\"value num\" id=\"s-ok\">—</div><div class=\"sub\" id=\"s-ok-sub\"> </div></div>\n <div class=\"stat bad zero\"><div class=\"label\">Failed</div><div class=\"value num\" id=\"s-bad\">—</div><div class=\"sub\" id=\"s-bad-sub\"> </div></div>\n <div class=\"stat\"><div class=\"label\">Next fire</div><div class=\"value num\" id=\"s-next\">—</div><div class=\"sub\" id=\"s-next-sub\"> </div></div>\n </section>\n\n <section class=\"card\">\n <div class=\"head\">\n <h2>Timeline</h2>\n <span class=\"hint\" id=\"tl-hint\"></span>\n <div class=\"spacer\"></div>\n <div class=\"tl-legend\" aria-hidden=\"true\">\n <span><i style=\"background:var(--green)\"></i>ok</span>\n <span><i style=\"background:var(--red)\"></i>failed</span>\n <span><i style=\"background:var(--faint)\"></i>skipped</span>\n <span><i style=\"border-left:2px dashed var(--border-strong);width:2px;border-radius:0\"></i>upcoming</span>\n </div>\n <label class=\"hint\" for=\"tl-span\">Window</label>\n <select id=\"tl-span\" aria-label=\"Timeline window\">\n <option value=\"120000\">2 min</option>\n <option value=\"600000\" selected>10 min</option>\n <option value=\"3600000\">1 hour</option>\n <option value=\"21600000\">6 hours</option>\n </select>\n </div>\n <div class=\"tl\" id=\"tl\">\n <div class=\"tl-gutter\" id=\"tl-gutter\"><div class=\"axis-pad\"></div></div>\n <div class=\"tl-viewport\" id=\"tl-viewport\">\n <div class=\"tl-track\" id=\"tl-track\"><div class=\"tl-axis\" id=\"tl-axis\"></div></div>\n <div class=\"tl-now\" aria-hidden=\"true\"></div>\n </div>\n </div>\n <div class=\"tl-empty\" id=\"tl-empty\" hidden>No jobs to plot.</div>\n </section>\n\n <div class=\"grid\">\n <section class=\"card\">\n <div class=\"head\"><h2>Jobs</h2><span class=\"hint\" id=\"jobs-hint\"></span></div>\n <table>\n <thead><tr><th>Job</th><th>Schedule</th><th>Zone</th><th>Next fire</th><th>Last run</th><th></th></tr></thead>\n <tbody id=\"jobs\"><tr><td colspan=\"6\" class=\"empty\">Loading…</td></tr></tbody>\n </table>\n </section>\n\n <section class=\"card\">\n <div class=\"head\">\n <h2>Live feed</h2>\n <div class=\"spacer\"></div>\n <button id=\"feed-pause\" class=\"tiny ghost\" aria-pressed=\"false\">Pause</button>\n <button id=\"feed-clear\" class=\"tiny ghost\">Clear</button>\n </div>\n <div id=\"feed-paused\" class=\"paused-note\" hidden></div>\n <div id=\"feed\" class=\"feed\" role=\"log\" aria-label=\"Live run feed\">\n <div class=\"empty\"><div class=\"lead\">Waiting for the first run.</div><div id=\"feed-hint\">Every fire shows up here as it happens.</div></div>\n </div>\n </section>\n </div>\n</main>\n\n<footer>\n <span>Local engine</span><span class=\"sep\">·</span>\n <span>no account</span><span class=\"sep\">·</span>\n <span>no cloud</span><span class=\"sep\">·</span>\n <span>no outbound network</span><span class=\"sep\">·</span>\n <span>this process is the only source of truth</span>\n</footer>\n\n<div id=\"overlay\" class=\"overlay\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"drawer-title\" hidden>\n <div class=\"drawer\">\n <div class=\"dhead\">\n <div class=\"dtitle\" id=\"drawer-title\">Job</div>\n <div class=\"spacer\"></div>\n <button id=\"drawer-run\" class=\"primary tiny\">Run now</button>\n <button id=\"drawer-close\" class=\"tiny\">Close</button>\n </div>\n <div class=\"pad\" id=\"drawer-body\"></div>\n </div>\n</div>\n\n<script>\n(function () {\n \"use strict\";\n\n var MAX_FEED = 250;\n var REFRESH_MS = 10000; // reconciliation poll behind the event stream\n var DEBOUNCE_MS = 400; // collapse a burst of events into one refetch\n var UPCOMING = 40; // fire times requested per job\n\n var state = { engine: {}, jobs: [], runs: [] };\n var jobsByKey = {};\n var rows = {}; // key -> { tr, next, last, running }\n var lanes = {}; // key -> { lane, label }\n var laneOrder = [];\n var anchorNow = Date.now();\n var spanMs = 600000;\n var openKey = null;\n var lastFocus = null;\n var paused = false;\n var pausedCount = 0;\n var refreshTimer = null;\n\n function el(id) { return document.getElementById(id); }\n function pad2(n) { return n < 10 ? \"0\" + n : \"\" + n; }\n function clockTime(ms) {\n var d = new Date(ms);\n return pad2(d.getHours()) + \":\" + pad2(d.getMinutes()) + \":\" + pad2(d.getSeconds());\n }\n function fmtDuration(ms) {\n if (ms == null) return \"\";\n if (ms < 1000) return ms + \"ms\";\n if (ms < 60000) return (ms / 1000).toFixed(ms < 10000 ? 2 : 1) + \"s\";\n var m = Math.floor(ms / 60000);\n return m + \"m \" + Math.round((ms % 60000) / 1000) + \"s\";\n }\n function fmtElapsed(ms) {\n var s = Math.max(0, Math.floor(ms / 1000));\n var d = Math.floor(s / 86400); s -= d * 86400;\n var h = Math.floor(s / 3600); s -= h * 3600;\n var m = Math.floor(s / 60); s -= m * 60;\n if (d) return d + \"d \" + h + \"h\";\n if (h) return h + \"h \" + m + \"m\";\n if (m) return m + \"m \" + s + \"s\";\n return s + \"s\";\n }\n /** A round duration, for labels rather than countdowns: \"5m\", not \"5m 0s\". */\n function fmtSpan(ms) {\n if (ms % 3600000 === 0) return (ms / 3600000) + \"h\";\n if (ms % 60000 === 0) return (ms / 60000) + \"m\";\n return Math.round(ms / 1000) + \"s\";\n }\n function countdown(iso) {\n if (!iso) return \"\\\\u2014\";\n var diff = new Date(iso).getTime() - Date.now();\n if (diff <= 0) return \"due now\";\n return \"in \" + fmtElapsed(diff);\n }\n function localTime(iso) {\n try { return new Date(iso).toLocaleString(); } catch (e) { return String(iso); }\n }\n function setText(node, text) { if (node && node.textContent !== text) node.textContent = text; }\n\n // ── Theme ──────────────────────────────────────────────────────────────────\n function applyTheme(t) {\n if (t === \"dark\" || t === \"light\") document.documentElement.setAttribute(\"data-theme\", t);\n else document.documentElement.removeAttribute(\"data-theme\");\n }\n function resolvedTheme() {\n var t = document.documentElement.getAttribute(\"data-theme\");\n if (t) return t;\n return window.matchMedia && window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n }\n // The icon offers the theme you would switch *to*, which is the only reading that stays true\n // whether the current theme came from the OS or from a previous click.\n function paintThemeIcon() {\n var dark = resolvedTheme() === \"dark\";\n el(\"icon-sun\").hidden = !dark;\n el(\"icon-moon\").hidden = dark;\n el(\"theme-btn\").title = dark ? \"Switch to light\" : \"Switch to dark\";\n }\n try { applyTheme(localStorage.getItem(\"cronvello-theme\")); } catch (e) {}\n paintThemeIcon();\n el(\"theme-btn\").addEventListener(\"click\", function () {\n var next = resolvedTheme() === \"dark\" ? \"light\" : \"dark\";\n applyTheme(next);\n paintThemeIcon();\n try { localStorage.setItem(\"cronvello-theme\", next); } catch (e) {}\n });\n\n // ── Badges ─────────────────────────────────────────────────────────────────\n function badge(status) {\n var span = document.createElement(\"span\");\n span.className = \"badge \" + (status || \"none\");\n span.textContent = status || \"\\\\u2014\";\n return span;\n }\n function replaceChild1(cell, node) {\n cell.textContent = \"\";\n cell.appendChild(node);\n }\n\n // ── Stats ──────────────────────────────────────────────────────────────────\n function renderStats() {\n var jobs = state.jobs, runs = state.runs;\n var ok = 0, bad = 0, skipped = 0, retried = 0;\n for (var i = 0; i < runs.length; i++) {\n var s = runs[i].status;\n if (s === \"success\") { ok++; if (runs[i].attempts > 1) retried++; }\n else if (s === \"skipped\") skipped++;\n else bad++;\n }\n var active = 0;\n for (var j = 0; j < jobs.length; j++) if (jobs[j].running) active++;\n\n setText(el(\"s-jobs\"), String(jobs.length));\n setText(el(\"s-jobs-sub\"), active ? active + \" running now\" : \"idle\");\n\n setText(el(\"s-runs\"), String(runs.length));\n var upSince = state.engine.startedAt ? \"up \" + fmtElapsed(Date.now() - state.engine.startedAt) : \"not started\";\n setText(el(\"s-runs-sub\"), upSince);\n\n setText(el(\"s-ok\"), String(ok));\n setText(el(\"s-ok-sub\"), retried ? retried + \" after a retry\" : (skipped ? skipped + \" skipped (overlap)\" : \"\\\\u00a0\"));\n\n setText(el(\"s-bad\"), String(bad));\n el(\"s-bad\").parentNode.className = \"stat bad\" + (bad ? \"\" : \" zero\");\n setText(el(\"s-bad-sub\"), bad ? \"check the feed\" : \"nothing failed\");\n\n // Soonest upcoming fire across all jobs.\n var soonest = null, soonestKey = \"\";\n for (var k = 0; k < jobs.length; k++) {\n if (!jobs[k].nextFire) continue;\n var t = new Date(jobs[k].nextFire).getTime();\n if (soonest === null || t < soonest) { soonest = t; soonestKey = jobs[k].key; }\n }\n if (soonest === null) {\n setText(el(\"s-next\"), \"\\\\u2014\");\n setText(el(\"s-next-sub\"), jobs.length ? \"nothing scheduled\" : \"\\\\u00a0\");\n } else {\n setText(el(\"s-next\"), countdown(new Date(soonest).toISOString()).replace(/^in /, \"\"));\n setText(el(\"s-next-sub\"), soonestKey);\n }\n }\n\n // ── Jobs table ─────────────────────────────────────────────────────────────\n // \"No jobs\" and \"not loaded yet\" both leave the row map empty, so this flag is what separates\n // them. Without it the first snapshot of an empty registry would sit on \"Loading\" forever.\n var built = false;\n\n function sameKeys(jobs) {\n if (!built) return false;\n var keys = Object.keys(rows);\n if (keys.length !== jobs.length) return false;\n for (var i = 0; i < jobs.length; i++) if (!rows[jobs[i].key]) return false;\n return true;\n }\n\n function buildRows(jobs) {\n var tbody = el(\"jobs\");\n tbody.textContent = \"\";\n rows = {};\n if (!jobs.length) {\n var tr0 = document.createElement(\"tr\");\n var td0 = document.createElement(\"td\");\n td0.colSpan = 6; td0.className = \"empty\";\n td0.innerHTML = '<div class=\"lead\">No jobs registered.</div>Add one to <code>jobs</code> in your config and restart.';\n tr0.appendChild(td0); tbody.appendChild(tr0);\n return;\n }\n for (var i = 0; i < jobs.length; i++) {\n var j = jobs[i];\n var tr = document.createElement(\"tr\");\n tr.className = \"job\";\n tr.tabIndex = 0;\n tr.setAttribute(\"role\", \"button\");\n tr.setAttribute(\"aria-label\", \"Details for \" + j.key);\n tr.dataset.key = j.key;\n\n var tdName = document.createElement(\"td\");\n var name = document.createElement(\"div\");\n name.className = \"jobkey\"; name.textContent = j.key;\n tdName.appendChild(name);\n if (j.description) {\n var desc = document.createElement(\"div\");\n desc.className = \"jobdesc\"; desc.textContent = j.description;\n tdName.appendChild(desc);\n }\n\n var tdSched = document.createElement(\"td\");\n tdSched.className = \"sched\";\n var code = document.createElement(\"code\"); code.textContent = j.schedule;\n tdSched.appendChild(code);\n\n var tdZone = document.createElement(\"td\");\n tdZone.style.color = \"var(--muted)\";\n tdZone.textContent = j.timeZone;\n\n var tdNext = document.createElement(\"td\");\n tdNext.className = \"next num\";\n\n var tdLast = document.createElement(\"td\");\n\n var tdAct = document.createElement(\"td\");\n tdAct.className = \"act\";\n var btn = document.createElement(\"button\");\n btn.className = \"tiny\"; btn.textContent = \"Run\";\n btn.setAttribute(\"aria-label\", \"Run \" + j.key + \" now\");\n btn.dataset.key = j.key;\n tdAct.appendChild(btn);\n\n tr.appendChild(tdName); tr.appendChild(tdSched); tr.appendChild(tdZone);\n tr.appendChild(tdNext); tr.appendChild(tdLast); tr.appendChild(tdAct);\n tbody.appendChild(tr);\n\n rows[j.key] = { tr: tr, next: tdNext, last: tdLast, btn: btn };\n }\n }\n\n function paintRows(jobs) {\n for (var i = 0; i < jobs.length; i++) {\n var j = jobs[i], r = rows[j.key];\n if (!r) continue;\n r.tr.classList.toggle(\"is-running\", !!j.running);\n r.next.dataset.next = j.nextFire || \"\";\n setText(r.next, j.nextFire ? countdown(j.nextFire) : \"\\\\u2014\");\n var status = j.running ? \"running\" : (j.lastRun ? j.lastRun.status : \"\");\n if (r.lastStatus !== status) {\n r.lastStatus = status;\n replaceChild1(r.last, badge(status));\n }\n }\n }\n\n function tickCountdowns() {\n for (var key in rows) {\n if (!Object.prototype.hasOwnProperty.call(rows, key)) continue;\n var cell = rows[key].next;\n var iso = cell.dataset.next;\n setText(cell, iso ? countdown(iso) : \"\\\\u2014\");\n }\n if (state.engine.startedAt) {\n setText(el(\"s-runs-sub\"), \"up \" + fmtElapsed(Date.now() - state.engine.startedAt));\n }\n var jobs = state.jobs, soonest = null, soonestKey = \"\";\n for (var i = 0; i < jobs.length; i++) {\n if (!jobs[i].nextFire) continue;\n var t = new Date(jobs[i].nextFire).getTime();\n if (soonest === null || t < soonest) { soonest = t; soonestKey = jobs[i].key; }\n }\n if (soonest !== null) {\n setText(el(\"s-next\"), countdown(new Date(soonest).toISOString()).replace(/^in /, \"\"));\n setText(el(\"s-next-sub\"), soonestKey);\n }\n }\n\n // ── Timeline ───────────────────────────────────────────────────────────────\n //\n // The track covers a fixed absolute window [anchorNow - span/2, anchorNow + span/2] and every mark\n // is positioned once, as a percentage of that window. The passing second only shifts the whole\n // track, so an idle dashboard writes one transform per frame-ish instead of touching every mark.\n function buildLanes(jobs) {\n var gutter = el(\"tl-gutter\"), track = el(\"tl-track\");\n gutter.textContent = \"\";\n var pad = document.createElement(\"div\"); pad.className = \"axis-pad\";\n gutter.appendChild(pad);\n\n // Keep the axis, drop the lanes.\n var axis = el(\"tl-axis\");\n track.textContent = \"\";\n track.appendChild(axis);\n\n lanes = {}; laneOrder = [];\n for (var i = 0; i < jobs.length; i++) {\n var key = jobs[i].key;\n var label = document.createElement(\"div\");\n label.className = \"lane-label\"; label.textContent = key; label.title = key;\n gutter.appendChild(label);\n\n var lane = document.createElement(\"div\");\n lane.className = \"tl-lane\"; lane.dataset.key = key;\n track.appendChild(lane);\n\n lanes[key] = { lane: lane, label: label };\n laneOrder.push(key);\n }\n el(\"tl\").hidden = jobs.length === 0;\n el(\"tl-empty\").hidden = jobs.length !== 0;\n }\n\n function axisStep(span) {\n var steps = [1000, 5000, 15000, 30000, 60000, 300000, 900000, 1800000, 3600000, 10800000, 21600000];\n for (var i = 0; i < steps.length; i++) if (span / steps[i] <= 10) return steps[i];\n return steps[steps.length - 1];\n }\n\n function paintTimeline() {\n var jobs = state.jobs;\n anchorNow = Date.now();\n var start = anchorNow - spanMs / 2;\n var pct = function (t) { return ((t - start) / spanMs) * 100; };\n el(\"tl-track\").style.transform = \"translateX(0%)\";\n\n // Axis gridlines.\n var axis = el(\"tl-axis\");\n axis.textContent = \"\";\n var step = axisStep(spanMs);\n var first = Math.ceil(start / step) * step;\n for (var t = first; t < start + spanMs; t += step) {\n var p = pct(t);\n var gl = document.createElement(\"div\");\n gl.className = \"gl\"; gl.style.left = p + \"%\";\n axis.appendChild(gl);\n var gt = document.createElement(\"div\");\n gt.className = \"gt\"; gt.style.left = p + \"%\"; gt.textContent = clockTime(t);\n axis.appendChild(gt);\n }\n\n // Marks per lane: past runs, then upcoming fires.\n var runsByKey = {};\n for (var i = 0; i < state.runs.length; i++) {\n var run = state.runs[i];\n (runsByKey[run.key] || (runsByKey[run.key] = [])).push(run);\n }\n\n for (var l = 0; l < laneOrder.length; l++) {\n var key = laneOrder[l];\n var lane = lanes[key].lane;\n lane.textContent = \"\";\n\n var list = runsByKey[key] || [];\n for (var r = 0; r < list.length; r++) {\n var rec = list[r];\n if (rec.startedAt < start || rec.startedAt > start + spanMs) continue;\n var mk = document.createElement(\"div\");\n mk.className = \"mk run \" + rec.status + (rec.status === \"success\" && rec.attempts > 1 ? \" retried\" : \"\");\n mk.style.left = pct(rec.startedAt) + \"%\";\n mk.title = key + \" \\\\u00b7 \" + rec.status + \" \\\\u00b7 \" + clockTime(rec.startedAt) +\n (rec.durationMs ? \" \\\\u00b7 \" + fmtDuration(rec.durationMs) : \"\") +\n (rec.attempts > 1 ? \" \\\\u00b7 \" + rec.attempts + \" attempts\" : \"\");\n lane.appendChild(mk);\n }\n\n var ups = jobsByKey[key] && jobsByKey[key].upcoming ? jobsByKey[key].upcoming : [];\n var plotted = 0;\n for (var u = 0; u < ups.length; u++) {\n var at = new Date(ups[u]).getTime();\n if (at > start + spanMs) break;\n if (at < anchorNow) continue;\n var um = document.createElement(\"div\");\n um.className = \"mk up\" + (plotted === 0 ? \" first\" : \"\");\n um.style.left = pct(at) + \"%\";\n um.title = key + \" \\\\u00b7 next fire \" + clockTime(at);\n lane.appendChild(um);\n plotted++;\n }\n\n // A lane whose whole schedule sits outside the window would otherwise read as \"nothing here\",\n // which is indistinguishable from a broken job. Say when it actually fires.\n if (!lane.childNodes.length) {\n var note = document.createElement(\"div\");\n note.className = \"lane-note\";\n var job = jobsByKey[key];\n note.textContent = job && job.nextFire ? \"next \" + countdown(job.nextFire) : \"not scheduled\";\n lane.appendChild(note);\n }\n }\n\n el(\"tl-hint\").textContent = fmtSpan(spanMs / 2) + \" back, \" + fmtSpan(spanMs / 2) + \" ahead\";\n }\n\n function slideTimeline() {\n var drift = Date.now() - anchorNow;\n // Re-anchor rather than sliding forever, so marks that left the window get dropped.\n if (Math.abs(drift) > spanMs / 4) { paintTimeline(); return; }\n el(\"tl-track\").style.transform = \"translateX(\" + (-(drift / spanMs) * 100) + \"%)\";\n }\n\n el(\"tl-span\").addEventListener(\"change\", function () {\n spanMs = Number(this.value) || 600000;\n paintTimeline();\n });\n\n // ── Live feed ──────────────────────────────────────────────────────────────\n var glyphs = {\n fire: \"\\\\u25b8\", success: \"\\\\u2713\", error: \"\\\\u2717\", timeout: \"\\\\u29d6\",\n retry: \"\\\\u21ba\", skipped: \"\\\\u2298\", scheduled: \"\\\\u00b7\",\n \"engine-start\": \"\\\\u25cf\", \"engine-stop\": \"\\\\u25a0\"\n };\n\n function describe(ev) {\n var frag = document.createDocumentFragment();\n function k(text) { var s = document.createElement(\"span\"); s.className = \"k\"; s.textContent = text; return s; }\n function plain(text) { return document.createTextNode(text); }\n function dim(text) { var s = document.createElement(\"span\"); s.className = \"detail\"; s.textContent = text; return s; }\n\n switch (ev.type) {\n case \"fire\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" fired\"));\n if (ev.attempt > 1) frag.appendChild(dim(\" (attempt \" + ev.attempt + \")\"));\n break;\n case \"success\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" succeeded \"));\n frag.appendChild(dim(\"in \" + fmtDuration(ev.durationMs) + (ev.attempts > 1 ? \", after \" + ev.attempts + \" attempts\" : \"\")));\n break;\n case \"error\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" errored: \" + ev.error));\n frag.appendChild(dim(ev.willRetry ? \" (retrying)\" : \" (gave up)\"));\n break;\n case \"timeout\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" timed out \"));\n frag.appendChild(dim(\"after \" + fmtDuration(ev.durationMs) + (ev.willRetry ? \", retrying\" : \", gave up\")));\n break;\n case \"retry\":\n frag.appendChild(k(ev.key));\n frag.appendChild(dim(\" retrying in \" + fmtDuration(ev.delayMs) + \" (attempt \" + ev.attempt + \")\"));\n break;\n case \"skipped\":\n frag.appendChild(k(ev.key)); frag.appendChild(dim(\" skipped, previous run still in flight\"));\n break;\n case \"scheduled\":\n // This event's timestamp is the *next fire*, not the moment it was emitted. Saying so keeps\n // the feed's right-hand clock strictly the arrival time and never looks out of order.\n frag.appendChild(k(ev.key)); frag.appendChild(dim(\" scheduled for \" + clockTime(ev.at)));\n break;\n case \"engine-start\":\n frag.appendChild(plain(\"Engine started with \" + ev.jobs + \" job\" + (ev.jobs === 1 ? \"\" : \"s\")));\n break;\n case \"engine-stop\":\n frag.appendChild(plain(\"Engine stopped\"));\n break;\n default:\n frag.appendChild(plain(ev.type));\n }\n return frag;\n }\n\n function feedClass(type) {\n if (type === \"engine-start\" || type === \"engine-stop\" || type === \"scheduled\") return \"engine\";\n return type;\n }\n\n function pushEvent(ev) {\n var feed = el(\"feed\");\n var firstChild = feed.firstChild;\n if (firstChild && firstChild.className === \"empty\") feed.textContent = \"\";\n\n var div = document.createElement(\"div\");\n div.className = \"ev \" + feedClass(ev.type);\n\n var g = document.createElement(\"div\");\n g.className = \"glyph\"; g.textContent = glyphs[ev.type] || \"\\\\u2022\";\n var b = document.createElement(\"div\");\n b.className = \"body\"; b.appendChild(describe(ev));\n var w = document.createElement(\"div\");\n w.className = \"when\";\n w.textContent = clockTime(ev.type === \"scheduled\" ? Date.now() : (ev.at || Date.now()));\n\n div.appendChild(g); div.appendChild(b); div.appendChild(w);\n feed.insertBefore(div, feed.firstChild);\n while (feed.childNodes.length > MAX_FEED) feed.removeChild(feed.lastChild);\n }\n\n el(\"feed-pause\").addEventListener(\"click\", function () {\n paused = !paused;\n this.textContent = paused ? \"Resume\" : \"Pause\";\n this.setAttribute(\"aria-pressed\", paused ? \"true\" : \"false\");\n if (!paused) { pausedCount = 0; el(\"feed-paused\").hidden = true; }\n });\n el(\"feed-clear\").addEventListener(\"click\", function () {\n el(\"feed\").textContent = \"\";\n var d = document.createElement(\"div\");\n d.className = \"empty\"; d.textContent = \"Cleared. New events appear here.\";\n el(\"feed\").appendChild(d);\n });\n\n // ── Connection ─────────────────────────────────────────────────────────────\n function setConn(stateName) {\n var chip = el(\"conn\");\n chip.className = \"chip \" + stateName;\n setText(el(\"conn-text\"), stateName === \"live\" ? \"live\" : (stateName === \"down\" ? \"reconnecting\" : \"connecting\\\\u2026\"));\n }\n function setEngineChip() {\n var chip = el(\"engine-chip\");\n var running = state.engine.running;\n chip.className = \"chip\" + (running ? \" live\" : \"\");\n var n = state.jobs.length;\n setText(el(\"engine-text\"), (running ? \"running\" : \"stopped\") + \" \\\\u00b7 \" + n + \" job\" + (n === 1 ? \"\" : \"s\"));\n }\n\n function connect() {\n setConn(\"connecting\");\n var src = new EventSource(\"/api/events\");\n src.onopen = function () { setConn(\"live\"); scheduleRefresh(0); };\n src.onmessage = function (m) {\n var ev;\n try { ev = JSON.parse(m.data); } catch (e) { return; }\n if (paused) {\n pausedCount++;\n el(\"feed-paused\").hidden = false;\n el(\"feed-paused\").textContent = \"Paused \\\\u00b7 \" + pausedCount + \" event\" + (pausedCount === 1 ? \"\" : \"s\") + \" not shown\";\n } else {\n pushEvent(ev);\n }\n // Terminal events change job status / history; reconcile on the next tick.\n if (ev.type !== \"fire\") scheduleRefresh(DEBOUNCE_MS);\n };\n src.onerror = function () { setConn(\"down\"); };\n }\n\n // ── State ──────────────────────────────────────────────────────────────────\n function scheduleRefresh(delay) {\n if (refreshTimer) return;\n refreshTimer = setTimeout(function () { refreshTimer = null; refresh(); }, delay);\n }\n\n function refresh() {\n return fetch(\"/api/state?upcoming=\" + UPCOMING)\n .then(function (r) { return r.json(); })\n .then(function (next) {\n var structureChanged = !sameKeys(next.jobs);\n state = next;\n jobsByKey = {};\n for (var i = 0; i < next.jobs.length; i++) jobsByKey[next.jobs[i].key] = next.jobs[i];\n\n if (structureChanged) { buildRows(next.jobs); buildLanes(next.jobs); built = true; }\n paintRows(next.jobs);\n paintTimeline();\n renderStats();\n setEngineChip();\n if (openKey) paintDrawer(openKey);\n })\n .catch(function () { /* the poll below retries */ });\n }\n\n // ── Drawer ─────────────────────────────────────────────────────────────────\n function openDrawer(key) {\n if (!jobsByKey[key]) return;\n openKey = key;\n lastFocus = document.activeElement;\n el(\"overlay\").hidden = false;\n el(\"overlay\").classList.add(\"open\");\n paintDrawer(key);\n el(\"drawer-close\").focus();\n }\n\n function closeDrawer() {\n openKey = null;\n el(\"overlay\").classList.remove(\"open\");\n el(\"overlay\").hidden = true;\n if (lastFocus && lastFocus.focus) lastFocus.focus();\n }\n\n function runLine(run) {\n var li = document.createElement(\"li\");\n var wrap = document.createElement(\"div\");\n wrap.className = \"runline\";\n\n var row1 = document.createElement(\"div\");\n row1.className = \"row1\";\n var left = document.createElement(\"span\");\n left.appendChild(badge(run.status));\n var when = document.createElement(\"span\");\n when.className = \"meta\";\n when.textContent = \" \" + localTime(new Date(run.startedAt).toISOString());\n left.appendChild(when);\n var right = document.createElement(\"span\");\n right.className = \"meta\";\n right.textContent = fmtDuration(run.durationMs) + (run.attempts > 1 ? \" \\\\u00b7 \" + run.attempts + \" attempts\" : \"\");\n row1.appendChild(left); row1.appendChild(right);\n wrap.appendChild(row1);\n\n if (run.error) {\n var pre = document.createElement(\"pre\");\n pre.className = \"err\"; pre.textContent = run.error;\n wrap.appendChild(pre);\n } else if (run.result !== undefined && run.result !== null) {\n var pre2 = document.createElement(\"pre\");\n try { pre2.textContent = JSON.stringify(run.result, null, 2); }\n catch (e) { pre2.textContent = String(run.result); }\n wrap.appendChild(pre2);\n }\n\n li.appendChild(wrap);\n li.style.display = \"block\";\n return li;\n }\n\n function paintDrawer(key) {\n var job = jobsByKey[key];\n if (!job) { closeDrawer(); return; }\n setText(el(\"drawer-title\"), key);\n\n var body = el(\"drawer-body\");\n body.textContent = \"\";\n\n function kv(label, valueNode) {\n var d = document.createElement(\"div\");\n d.className = \"kv\";\n var l = document.createElement(\"span\"); l.textContent = label;\n d.appendChild(l); d.appendChild(valueNode);\n body.appendChild(d);\n }\n function textNode(t) { var s = document.createElement(\"span\"); s.textContent = t; return s; }\n function codeNode(t) { var s = document.createElement(\"code\"); s.textContent = t; return s; }\n\n kv(\"Schedule\", codeNode(job.schedule));\n kv(\"Time zone\", textNode(job.timeZone));\n if (job.description) kv(\"Description\", textNode(job.description));\n kv(\"Status\", job.running ? badge(\"running\") : badge(job.lastRun ? job.lastRun.status : \"\"));\n\n var t1 = document.createElement(\"div\");\n t1.className = \"section-title\"; t1.textContent = \"Next fire times\";\n body.appendChild(t1);\n\n var ups = job.upcoming || [];\n if (ups.length) {\n var ul = document.createElement(\"ul\");\n ul.className = \"plain\";\n for (var i = 0; i < ups.length && i < 8; i++) {\n var li = document.createElement(\"li\");\n var a = document.createElement(\"span\"); a.textContent = localTime(ups[i]);\n var b = document.createElement(\"span\"); b.className = \"meta num\"; b.textContent = countdown(ups[i]);\n li.appendChild(a); li.appendChild(b);\n ul.appendChild(li);\n }\n body.appendChild(ul);\n } else {\n var e1 = document.createElement(\"div\");\n e1.className = \"empty\"; e1.textContent = \"No upcoming fires for this expression.\";\n body.appendChild(e1);\n }\n\n var t2 = document.createElement(\"div\");\n t2.className = \"section-title\"; t2.textContent = \"Recent runs\";\n body.appendChild(t2);\n\n var mine = [];\n for (var r = 0; r < state.runs.length; r++) if (state.runs[r].key === key) mine.push(state.runs[r]);\n if (mine.length) {\n var ul2 = document.createElement(\"ul\");\n ul2.className = \"plain\";\n for (var m = 0; m < mine.length && m < 25; m++) ul2.appendChild(runLine(mine[m]));\n body.appendChild(ul2);\n } else {\n var e2 = document.createElement(\"div\");\n e2.className = \"empty\"; e2.textContent = \"No runs yet in this session.\";\n body.appendChild(e2);\n }\n }\n\n function runNow(key, btn) {\n var label = btn.textContent;\n btn.disabled = true; btn.textContent = \"Running\\\\u2026\";\n fetch(\"/api/trigger/\" + encodeURIComponent(key), { method: \"POST\", headers: { \"content-type\": \"application/json\" } })\n .then(function (r) { return r.json(); })\n .then(function () { btn.textContent = \"Ran\"; scheduleRefresh(0); })\n .catch(function () { btn.textContent = \"Failed\"; })\n .then(function () {\n setTimeout(function () { btn.disabled = false; btn.textContent = label; }, 1200);\n });\n }\n\n el(\"drawer-close\").addEventListener(\"click\", closeDrawer);\n el(\"drawer-run\").addEventListener(\"click\", function () { if (openKey) runNow(openKey, this); });\n el(\"overlay\").addEventListener(\"click\", function (e) { if (e.target === el(\"overlay\")) closeDrawer(); });\n document.addEventListener(\"keydown\", function (e) {\n if (e.key === \"Escape\" && openKey) closeDrawer();\n });\n\n // Row interactions are delegated, so rebuilding the table never leaks listeners.\n el(\"jobs\").addEventListener(\"click\", function (e) {\n var btn = e.target.closest ? e.target.closest(\"button[data-key]\") : null;\n if (btn) { e.stopPropagation(); runNow(btn.dataset.key, btn); return; }\n var tr = e.target.closest ? e.target.closest(\"tr.job\") : null;\n if (tr) openDrawer(tr.dataset.key);\n });\n el(\"jobs\").addEventListener(\"keydown\", function (e) {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n var tr = e.target.closest ? e.target.closest(\"tr.job\") : null;\n if (tr) { e.preventDefault(); openDrawer(tr.dataset.key); }\n });\n el(\"tl-gutter\").addEventListener(\"click\", function (e) {\n var label = e.target.closest ? e.target.closest(\".lane-label\") : null;\n if (label) openDrawer(label.textContent);\n });\n\n // ── Boot ───────────────────────────────────────────────────────────────────\n refresh();\n connect();\n setInterval(tickCountdowns, 1000);\n setInterval(slideTimeline, 1000);\n setInterval(function () { scheduleRefresh(0); }, REFRESH_MS);\n})();\n</script>\n</body>\n</html>`;\n","/**\n * The **local dashboard** — a tiny `node:http` server (zero runtime dependencies) that observes a\n * running {@link LocalEngine} and renders it in a branded single-page UI. The engine stays the only\n * source of truth for scheduling; the dashboard only *reads* it (snapshot / history / live events)\n * and offers exactly one write path: a manual \"run now\" trigger.\n *\n * It is a developer tool, not a public server: it binds to `127.0.0.1` by default, never `0.0.0.0`,\n * speaks only to same-origin callers for mutations, makes no outbound network calls, and sends no\n * telemetry. Start it with {@link startDashboard}, or via `app.dev({ dashboard: true })` /\n * `cronvello dev --dashboard`.\n */\nimport http from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport type { LocalEngine } from \"./engine.js\";\nimport { previewSchedule } from \"../internal/cron-schedule.js\";\nimport { DASHBOARD_HTML } from \"./dashboard-assets.js\";\n\nexport interface DashboardOptions {\n /** Port to listen on. Default `4747`. Use `0` to let the OS pick a free port (handy in tests). */\n port?: number;\n /** Host/interface to bind. Default `127.0.0.1` — keep it loopback; this is not a public server. */\n host?: string;\n}\n\nexport interface DashboardHandle {\n /** The local URL the dashboard is reachable at, e.g. `http://127.0.0.1:4747`. */\n url: string;\n /** The actual port bound (resolved even when `port: 0` was requested). */\n port: number;\n /** Stop the server and drop every live SSE connection. Idempotent. */\n close(): Promise<void>;\n}\n\nconst DEFAULT_PORT = 4747;\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst HEARTBEAT_MS = 15_000;\nconst MAX_PREVIEW = 50;\n\n/**\n * Start the dashboard server for an engine. Resolves once it is listening; rejects with a clear\n * message if the port is already in use. Bind defaults to loopback.\n */\nexport function startDashboard(engine: LocalEngine, options: DashboardOptions = {}): Promise<DashboardHandle> {\n const host = options.host ?? DEFAULT_HOST;\n const port = options.port ?? DEFAULT_PORT;\n const sseClients = new Set<http.ServerResponse>();\n\n const server = http.createServer((req, res) => handleRequest(engine, sseClients, req, res));\n\n return new Promise<DashboardHandle>((resolve, reject) => {\n const onError = (err: NodeJS.ErrnoException): void => {\n server.removeListener(\"error\", onError);\n if (err.code === \"EADDRINUSE\") {\n reject(new Error(`Cronvello dashboard: port ${port} on ${host} is already in use — pass a different --port.`));\n } else {\n reject(err);\n }\n };\n server.once(\"error\", onError);\n\n server.listen(port, host, () => {\n server.removeListener(\"error\", onError);\n const actualPort = (server.address() as AddressInfo).port;\n const shown = host === \"0.0.0.0\" || host === \"::\" ? \"127.0.0.1\" : host;\n const url = `http://${shown}:${actualPort}`;\n\n let closed = false;\n const close = (): Promise<void> => {\n if (closed) return Promise.resolve();\n closed = true;\n for (const client of sseClients) client.end();\n sseClients.clear();\n return new Promise<void>((res2) => {\n // closeAllConnections (Node ≥18.2) drops lingering keep-alive sockets so this resolves\n // promptly instead of waiting on idle connections.\n server.closeAllConnections?.();\n server.close(() => res2());\n });\n };\n\n resolve({ url, port: actualPort, close });\n });\n });\n}\n\nfunction handleRequest(\n engine: LocalEngine,\n sseClients: Set<http.ServerResponse>,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): void {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const path = url.pathname;\n const method = req.method ?? \"GET\";\n\n // Landing page.\n if (method === \"GET\" && path === \"/\") {\n return sendHtml(res, DASHBOARD_HTML);\n }\n\n // Live event stream (Server-Sent Events).\n if (method === \"GET\" && path === \"/api/events\") {\n return openEventStream(engine, sseClients, req, res);\n }\n\n // Health.\n if (method === \"GET\" && path === \"/api/health\") {\n return sendJson(res, 200, {\n ok: true,\n jobs: engine.jobs().length,\n activeRuns: engine.activeRuns,\n running: engine.running,\n startedAt: engine.startedAt,\n });\n }\n\n // Everything the UI needs for a full repaint, in one round-trip. The dashboard polls this as a\n // reconciliation net behind the live event stream, so a second request per refresh would double\n // the cost of the thing that runs most often.\n if (method === \"GET\" && path === \"/api/state\") {\n const runs = engine.runs();\n const lastByKey = new Map<string, ReturnType<typeof engine.runs>[number]>();\n for (const run of runs) if (!lastByKey.has(run.key)) lastByKey.set(run.key, run);\n const upcomingCount = clampCount(url.searchParams.get(\"upcoming\"));\n return sendJson(res, 200, {\n engine: {\n running: engine.running,\n startedAt: engine.startedAt,\n activeRuns: engine.activeRuns,\n now: Date.now(),\n },\n jobs: engine.snapshot().map((j) => ({\n key: j.key,\n schedule: j.schedule,\n timeZone: j.timeZone,\n description: j.description ?? null,\n nextFire: j.nextFire ? j.nextFire.toISOString() : null,\n running: j.running,\n lastRun: lastByKey.get(j.key) ?? null,\n upcoming: upcoming(j.schedule, j.timeZone, upcomingCount),\n })),\n runs,\n });\n }\n\n // Run history as NDJSON (check before the `/api/runs` prefix).\n if (method === \"GET\" && path === \"/api/runs.ndjson\") {\n res.writeHead(200, { \"content-type\": \"application/x-ndjson; charset=utf-8\", \"cache-control\": \"no-store\" });\n const body = engine.toNdjson();\n return void res.end(body.length ? body + \"\\n\" : \"\");\n }\n\n // Run history (all, or `?key=`).\n if (method === \"GET\" && path === \"/api/runs\") {\n const key = url.searchParams.get(\"key\");\n return sendJson(res, 200, key ? engine.runsFor(key) : engine.runs());\n }\n\n // Run history for one job.\n if (method === \"GET\" && path.startsWith(\"/api/runs/\")) {\n return sendJson(res, 200, engine.runsFor(decodeKey(path, \"/api/runs/\")));\n }\n\n // Upcoming fire times for one job.\n if (method === \"GET\" && path.startsWith(\"/api/preview/\")) {\n const key = decodeKey(path, \"/api/preview/\");\n const job = engine.snapshot().find((j) => j.key === key);\n if (!job) return sendJson(res, 404, { error: `unknown job '${key}'` });\n const n = clampCount(url.searchParams.get(\"n\"));\n try {\n const fires = previewSchedule(job.schedule, { timeZone: job.timeZone, count: n });\n return sendJson(res, 200, fires.map((d) => d.toISOString()));\n } catch {\n return sendJson(res, 200, []); // an unschedulable expression simply has no upcoming fires\n }\n }\n\n // Snapshot of all jobs.\n if (method === \"GET\" && path === \"/api/jobs\") {\n const jobs = engine.snapshot().map((j) => ({\n key: j.key,\n schedule: j.schedule,\n timeZone: j.timeZone,\n description: j.description,\n nextFire: j.nextFire ? j.nextFire.toISOString() : null,\n running: j.running,\n }));\n return sendJson(res, 200, jobs);\n }\n\n // Manual trigger — the one mutating path. Guard against cross-origin POSTs.\n if (method === \"POST\" && path.startsWith(\"/api/trigger/\")) {\n if (!isSameOrigin(req)) return sendJson(res, 403, { error: \"cross-origin request rejected\" });\n const key = decodeKey(path, \"/api/trigger/\");\n return void engine\n .trigger(key)\n .then((record) => sendJson(res, 200, record))\n .catch((err: Error) => {\n const status = /unknown job/.test(err.message) ? 404 : 400;\n sendJson(res, status, { error: err.message });\n });\n }\n\n sendJson(res, 404, { error: \"not found\" });\n}\n\n/** Open an SSE stream that forwards every engine event until the client disconnects. */\nfunction openEventStream(\n engine: LocalEngine,\n sseClients: Set<http.ServerResponse>,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): void {\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-store\",\n connection: \"keep-alive\",\n \"x-accel-buffering\": \"no\",\n });\n res.write(\": connected\\n\\n\");\n sseClients.add(res);\n\n const unsubscribe = engine.subscribe((event) => {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n });\n // Heartbeat comment keeps proxies from idling the connection out.\n const heartbeat = setInterval(() => res.write(\": ping\\n\\n\"), HEARTBEAT_MS);\n if (typeof heartbeat.unref === \"function\") heartbeat.unref();\n\n const cleanup = (): void => {\n clearInterval(heartbeat);\n unsubscribe();\n sseClients.delete(res);\n };\n res.on(\"close\", cleanup);\n req.on(\"close\", cleanup);\n}\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nfunction sendJson(res: http.ServerResponse, status: number, body: unknown): void {\n const payload = JSON.stringify(body);\n res.writeHead(status, { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\" });\n res.end(payload);\n}\n\nfunction sendHtml(res: http.ServerResponse, html: string): void {\n res.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" });\n res.end(html);\n}\n\nfunction decodeKey(path: string, prefix: string): string {\n return decodeURIComponent(path.slice(prefix.length));\n}\n\n/**\n * The next `count` fire times of a schedule, as ISO strings. An expression the previewer can't\n * resolve (`@reboot`, or a typo that slipped past define-time validation) simply has no upcoming\n * fires — that is a display fact, not an error worth failing the whole state request over.\n */\nfunction upcoming(schedule: string, timeZone: string, count: number): string[] {\n try {\n return previewSchedule(schedule, { timeZone, count }).map((d) => d.toISOString());\n } catch {\n return [];\n }\n}\n\nfunction clampCount(raw: string | null): number {\n const n = raw ? Number.parseInt(raw, 10) : 5;\n if (!Number.isFinite(n) || n < 1) return 5;\n return Math.min(n, MAX_PREVIEW);\n}\n\n/**\n * Reject a mutating request whose `Origin` points at a different host than the one it was sent to.\n * Loopback binding is the primary defence; this stops a page on another local origin from POSTing.\n */\nfunction isSameOrigin(req: http.IncomingMessage): boolean {\n const origin = req.headers.origin;\n if (!origin) return true; // non-browser clients (curl, tests) send no Origin\n try {\n return new URL(origin).host === req.headers.host;\n } catch {\n return false;\n }\n}\n","/**\n * Error taxonomy for the SDK. Everything thrown by the public surface is a\n * `CronvelloError` (or subclass), so callers can `catch (e) { if (e instanceof CronvelloError) … }`.\n */\n\nexport class CronvelloError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CronvelloError\";\n // Restore prototype chain for instanceof across transpilation targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** A non-2xx response from the Cronvello API. */\nexport class CronvelloApiError extends CronvelloError {\n /** HTTP status code. */\n readonly status: number;\n /** Machine-readable error code from the API body, when present. */\n readonly code: string | undefined;\n /** The method + path that failed, e.g. `POST /v1/jobs`. */\n readonly endpoint: string;\n /** Parsed response body (best effort). */\n readonly body: unknown;\n /** Seconds to wait before retrying, parsed from `Retry-After` / rate-limit payload (429 only). */\n readonly retryAfterSeconds: number | undefined;\n\n constructor(args: {\n status: number;\n endpoint: string;\n message: string;\n code?: string;\n body?: unknown;\n retryAfterSeconds?: number;\n }) {\n super(`[${args.status}] ${args.endpoint}: ${args.message}`);\n this.name = \"CronvelloApiError\";\n this.status = args.status;\n this.code = args.code;\n this.endpoint = args.endpoint;\n this.body = args.body;\n this.retryAfterSeconds = args.retryAfterSeconds;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n get isNotFound(): boolean {\n return this.status === 404;\n }\n}\n\n/** A network/transport failure (DNS, connection reset, timeout) before any HTTP status. */\nexport class CronvelloNetworkError extends CronvelloError {\n readonly endpoint: string;\n override readonly cause: unknown;\n constructor(endpoint: string, cause: unknown) {\n super(`Network error calling ${endpoint}: ${describe(cause)}`);\n this.name = \"CronvelloNetworkError\";\n this.endpoint = endpoint;\n this.cause = cause;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** A misconfiguration caught before any network call (missing apiKey, bad URL, …). */\nexport class CronvelloConfigError extends CronvelloError {\n constructor(message: string) {\n super(message);\n this.name = \"CronvelloConfigError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nfunction describe(cause: unknown): string {\n if (cause instanceof Error) return cause.message;\n return String(cause);\n}\n","/**\n * Minimal HTTP transport over the global `fetch` (Node 20+). No axios, no node-fetch —\n * zero runtime dependencies. Adds bearer auth, JSON (de)serialization, typed error mapping,\n * bounded retries with backoff for transient failures, and optional idempotency keys.\n */\n\nimport {\n CronvelloApiError,\n CronvelloConfigError,\n CronvelloNetworkError,\n} from \"./errors.js\";\n\nexport type FetchLike = (\n input: string,\n init?: {\n method?: string;\n headers?: Record<string, string>;\n body?: string;\n signal?: AbortSignal;\n },\n) => Promise<{\n ok: boolean;\n status: number;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}>;\n\nexport interface TransportOptions {\n baseUrl: string;\n apiKey: string;\n /** Per-request timeout in ms. Default 30_000. */\n timeoutMs?: number;\n /** Max retry attempts for 429/5xx/network errors. Default 2 (=> up to 3 tries). */\n maxRetries?: number;\n /** Override the fetch implementation (testing / custom agents). */\n fetch?: FetchLike;\n /** Extra headers sent on every request (e.g. a custom User-Agent). */\n defaultHeaders?: Record<string, string>;\n /** Telemetry hook — called once per completed attempt. */\n onRequest?: (info: { method: string; path: string; status: number; attempt: number; durationMs: number }) => void;\n}\n\nexport interface RequestOptions {\n method: string;\n path: string;\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n /** Idempotency-Key header value — replays of the same key are de-duplicated server-side. */\n idempotencyKey?: string;\n signal?: AbortSignal;\n}\n\nconst RETRYABLE_STATUS = new Set([429, 500, 502, 503, 504]);\n\nexport class Transport {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeoutMs: number;\n private readonly maxRetries: number;\n private readonly fetchImpl: FetchLike;\n private readonly defaultHeaders: Record<string, string>;\n private readonly onRequest: TransportOptions[\"onRequest\"];\n\n constructor(opts: TransportOptions) {\n if (!opts.apiKey) throw new CronvelloConfigError(\"apiKey is required\");\n if (!opts.baseUrl) throw new CronvelloConfigError(\"baseUrl is required\");\n const resolvedFetch = opts.fetch ?? (globalThis.fetch as unknown as FetchLike | undefined);\n if (!resolvedFetch) {\n throw new CronvelloConfigError(\n \"No global fetch found. Use Node 20+ or pass a `fetch` implementation in the client options.\",\n );\n }\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n this.maxRetries = opts.maxRetries ?? 2;\n this.fetchImpl = resolvedFetch;\n this.defaultHeaders = opts.defaultHeaders ?? {};\n this.onRequest = opts.onRequest;\n }\n\n async request<T>(opts: RequestOptions): Promise<T> {\n const url = this.buildUrl(opts.path, opts.query);\n const endpoint = `${opts.method} ${opts.path}`;\n const headers: Record<string, string> = {\n authorization: `Bearer ${this.apiKey}`,\n accept: \"application/json\",\n ...this.defaultHeaders,\n };\n let payload: string | undefined;\n if (opts.body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n payload = JSON.stringify(opts.body);\n }\n if (opts.idempotencyKey) headers[\"idempotency-key\"] = opts.idempotencyKey;\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const startedAt = Date.now();\n const { signal, cancel } = this.withTimeout(opts.signal);\n try {\n const res = await this.fetchImpl(url, {\n method: opts.method,\n headers,\n ...(payload !== undefined ? { body: payload } : {}),\n signal,\n });\n cancel();\n const durationMs = Date.now() - startedAt;\n this.onRequest?.({ method: opts.method, path: opts.path, status: res.status, attempt, durationMs });\n\n const text = await res.text();\n const parsed = text ? safeJson(text) : null;\n\n if (res.ok) return unwrapEnvelope(parsed) as T;\n\n const retryAfter = parseRetryAfter(res, parsed);\n if (RETRYABLE_STATUS.has(res.status) && attempt < this.maxRetries) {\n await sleep(this.backoff(attempt, retryAfter));\n continue;\n }\n throw new CronvelloApiError({\n status: res.status,\n endpoint,\n message: extractMessage(parsed) ?? `Request failed`,\n code: extractCode(parsed),\n body: parsed,\n ...(retryAfter !== undefined ? { retryAfterSeconds: retryAfter } : {}),\n });\n } catch (err) {\n cancel();\n if (err instanceof CronvelloApiError) throw err;\n // Network/abort error — retry if attempts remain.\n lastError = err;\n if (attempt < this.maxRetries) {\n await sleep(this.backoff(attempt));\n continue;\n }\n throw new CronvelloNetworkError(endpoint, err);\n }\n }\n // Unreachable, but satisfies the type checker.\n throw new CronvelloNetworkError(endpoint, lastError);\n }\n\n private buildUrl(path: string, query?: RequestOptions[\"query\"]): string {\n const base = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n if (!query) return base;\n const params = Object.entries(query)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return params.length ? `${base}?${params.join(\"&\")}` : base;\n }\n\n private withTimeout(external?: AbortSignal): { signal: AbortSignal; cancel: () => void } {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n const onExternalAbort = () => controller.abort();\n if (external) {\n if (external.aborted) controller.abort();\n else external.addEventListener(\"abort\", onExternalAbort, { once: true });\n }\n return {\n signal: controller.signal,\n cancel: () => {\n clearTimeout(timer);\n external?.removeEventListener(\"abort\", onExternalAbort);\n },\n };\n }\n\n private backoff(attempt: number, retryAfterSeconds?: number): number {\n if (retryAfterSeconds !== undefined) return Math.min(retryAfterSeconds * 1000, 30_000);\n // Exponential backoff with full jitter: base 300ms, capped at 5s.\n const base = Math.min(300 * 2 ** attempt, 5_000);\n return Math.floor(Math.random() * base);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\n/**\n * The Cronvello server wraps every successful `/v1` response in a `{ success, message, data }`\n * envelope, while the typed client methods are declared in terms of the inner payload. Unwrap\n * it here — centrally — so every resource method (and the high-level `sync()`) sees the data it\n * expects. Bodies that aren't enveloped (no boolean `success` + `data`) pass through unchanged,\n * so non-enveloped or future endpoints keep working.\n */\nfunction unwrapEnvelope(body: unknown): unknown {\n if (\n body !== null &&\n typeof body === \"object\" &&\n \"success\" in body &&\n typeof (body as { success: unknown }).success === \"boolean\" &&\n \"data\" in body\n ) {\n return (body as { data: unknown }).data;\n }\n return body;\n}\n\nfunction extractMessage(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"message\" in body) {\n const m = (body as { message?: unknown }).message;\n if (typeof m === \"string\") return m;\n }\n return undefined;\n}\n\nfunction extractCode(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"code\" in body) {\n const c = (body as { code?: unknown }).code;\n if (typeof c === \"string\") return c;\n }\n return undefined;\n}\n\nfunction parseRetryAfter(\n res: { headers: { get(name: string): string | null } },\n body: unknown,\n): number | undefined {\n const header = res.headers.get(\"retry-after\");\n if (header) {\n const n = Number(header);\n if (Number.isFinite(n)) return n;\n }\n if (body && typeof body === \"object\" && \"data\" in body) {\n const data = (body as { data?: { retryAfterSeconds?: unknown } }).data;\n if (data && typeof data.retryAfterSeconds === \"number\") return data.retryAfterSeconds;\n }\n return undefined;\n}\n","/**\n * Low-level, fully-typed client for the Cronvello public `/v1` API.\n *\n * This is the thin REST layer: one method per endpoint, request/response types straight\n * from the server contract. The high-level registry (`defineCronvello`) is built on top of\n * it. Use this directly when you need ad-hoc control beyond the registry model.\n */\n\nimport { Transport, type FetchLike } from \"../internal/http.js\";\nimport { CronvelloConfigError } from \"../internal/errors.js\";\nimport type {\n AccountRunsQuery,\n AccountTasksQuery,\n JobCreateBody,\n JobUpdateBody,\n MeResponse,\n PublicJob,\n PublicRun,\n PublicTask,\n RunNowResult,\n RegistryReconcileRequest,\n RegistryReconcileResponse,\n RunsPage,\n RunsQuery,\n TaskCreateBody,\n TasksPage,\n TaskUpdateBody,\n UsageResponse,\n} from \"../internal/wire.js\";\n\n/** The production Cronvello API. Override `baseUrl` only for self-hosting or testing. */\nexport const CRONVELLO_DEFAULT_BASE_URL = \"https://api.cronvello.com\";\n\nexport interface CronvelloClientOptions {\n /** Account API key (`crn_live_…`). Required. */\n apiKey: string;\n /** API base URL. Defaults to https://api.cronvello.com. */\n baseUrl?: string;\n /** Per-request timeout in ms (default 30_000). */\n timeoutMs?: number;\n /** Retry attempts for 429/5xx/network errors (default 2). */\n maxRetries?: number;\n /** Custom fetch implementation (default: global fetch). */\n fetch?: FetchLike;\n /** Telemetry hook for every request attempt. */\n onRequest?: (info: { method: string; path: string; status: number; attempt: number; durationMs: number }) => void;\n}\n\nexport class CronvelloClient {\n private readonly transport: Transport;\n /** The resolved base URL in use. */\n readonly baseUrl: string;\n\n /** Job container operations. */\n readonly jobs: JobsResource;\n /** Scheduled task operations. */\n readonly tasks: TasksResource;\n /** Execution-history (run) operations. */\n readonly runs: RunsResource;\n /** Account identity + usage. */\n readonly account: AccountResource;\n\n constructor(options: CronvelloClientOptions) {\n if (!options || !options.apiKey) {\n throw new CronvelloConfigError(\"CronvelloClient requires an `apiKey` (crn_live_…).\");\n }\n this.baseUrl = (options.baseUrl ?? CRONVELLO_DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.transport = new Transport({\n baseUrl: this.baseUrl,\n apiKey: options.apiKey,\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.maxRetries !== undefined ? { maxRetries: options.maxRetries } : {}),\n ...(options.fetch ? { fetch: options.fetch } : {}),\n ...(options.onRequest ? { onRequest: options.onRequest } : {}),\n defaultHeaders: { \"user-agent\": \"cronvello-sdk\" },\n });\n this.jobs = new JobsResource(this.transport);\n this.tasks = new TasksResource(this.transport);\n this.runs = new RunsResource(this.transport);\n this.account = new AccountResource(this.transport);\n }\n\n /**\n * Atomically reconcile a whole code registry server-side (`PUT /v1/registry`): one job\n * container + its tasks, created/updated/pruned/started in a single call. This is what\n * `defineCronvello().sync()` prefers; the high-level API builds the body for you.\n */\n reconcileRegistry(body: RegistryReconcileRequest, opts?: { idempotencyKey?: string }): Promise<RegistryReconcileResponse> {\n return this.transport.request({\n method: \"PUT\",\n path: \"/v1/registry\",\n body,\n ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),\n });\n }\n\n /**\n * Escape hatch for endpoints not yet wrapped by a typed method (heartbeat monitors,\n * maintenance windows, DLQ, notification channels, audit log, API-key self-service …).\n * `T` is the response shape you expect.\n */\n request<T>(method: string, path: string, opts?: { query?: Record<string, string | number | boolean | undefined>; body?: unknown; idempotencyKey?: string }): Promise<T> {\n return this.transport.request<T>({\n method,\n path,\n ...(opts?.query ? { query: opts.query } : {}),\n ...(opts?.body !== undefined ? { body: opts.body } : {}),\n ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),\n });\n }\n}\n\nclass JobsResource {\n constructor(private readonly t: Transport) {}\n\n list(): Promise<PublicJob[]> {\n return this.t.request({ method: \"GET\", path: \"/v1/jobs\" });\n }\n get(jobId: string): Promise<PublicJob> {\n return this.t.request({ method: \"GET\", path: `/v1/jobs/${enc(jobId)}` });\n }\n create(body: JobCreateBody, opts?: { idempotencyKey?: string }): Promise<PublicJob> {\n return this.t.request({ method: \"POST\", path: \"/v1/jobs\", body, ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}) });\n }\n update(jobId: string, body: JobUpdateBody): Promise<PublicJob> {\n return this.t.request({ method: \"PATCH\", path: `/v1/jobs/${enc(jobId)}`, body });\n }\n delete(jobId: string): Promise<null> {\n return this.t.request({ method: \"DELETE\", path: `/v1/jobs/${enc(jobId)}` });\n }\n start(jobId: string): Promise<PublicJob> {\n return this.t.request({ method: \"POST\", path: `/v1/jobs/${enc(jobId)}/start` });\n }\n stop(jobId: string): Promise<PublicJob> {\n return this.t.request({ method: \"POST\", path: `/v1/jobs/${enc(jobId)}/stop` });\n }\n listTasks(jobId: string): Promise<PublicTask[]> {\n return this.t.request({ method: \"GET\", path: `/v1/jobs/${enc(jobId)}/tasks` });\n }\n createTask(jobId: string, body: TaskCreateBody, opts?: { idempotencyKey?: string }): Promise<PublicTask> {\n return this.t.request({ method: \"POST\", path: `/v1/jobs/${enc(jobId)}/tasks`, body, ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}) });\n }\n}\n\nclass TasksResource {\n constructor(private readonly t: Transport) {}\n\n /** Account-wide paginated task table. */\n list(query?: AccountTasksQuery): Promise<TasksPage> {\n return this.t.request({ method: \"GET\", path: \"/v1/tasks\", ...(query ? { query: query as Record<string, string | number | boolean | undefined> } : {}) });\n }\n get(taskId: string): Promise<PublicTask> {\n return this.t.request({ method: \"GET\", path: `/v1/tasks/${enc(taskId)}` });\n }\n update(taskId: string, body: TaskUpdateBody): Promise<PublicTask> {\n return this.t.request({ method: \"PATCH\", path: `/v1/tasks/${enc(taskId)}`, body });\n }\n delete(taskId: string): Promise<null> {\n return this.t.request({ method: \"DELETE\", path: `/v1/tasks/${enc(taskId)}` });\n }\n start(taskId: string): Promise<PublicTask> {\n return this.t.request({ method: \"POST\", path: `/v1/tasks/${enc(taskId)}/start` });\n }\n stop(taskId: string): Promise<PublicTask> {\n return this.t.request({ method: \"POST\", path: `/v1/tasks/${enc(taskId)}/stop` });\n }\n /** Trigger a one-off manual execution (does not change the schedule). */\n runNow(taskId: string): Promise<RunNowResult> {\n return this.t.request({ method: \"POST\", path: `/v1/tasks/${enc(taskId)}/run` });\n }\n listRuns(taskId: string, query?: RunsQuery): Promise<RunsPage> {\n return this.t.request({ method: \"GET\", path: `/v1/tasks/${enc(taskId)}/runs`, ...(query ? { query: query as Record<string, string | number | boolean | undefined> } : {}) });\n }\n}\n\nclass RunsResource {\n constructor(private readonly t: Transport) {}\n\n /** Account-wide paginated activity feed. */\n list(query?: AccountRunsQuery): Promise<RunsPage> {\n return this.t.request({ method: \"GET\", path: \"/v1/runs\", ...(query ? { query: query as Record<string, string | number | boolean | undefined> } : {}) });\n }\n get(runId: string): Promise<PublicRun> {\n return this.t.request({ method: \"GET\", path: `/v1/runs/${enc(runId)}` });\n }\n}\n\nclass AccountResource {\n constructor(private readonly t: Transport) {}\n\n me(): Promise<MeResponse> {\n return this.t.request({ method: \"GET\", path: \"/v1/me\" });\n }\n usage(): Promise<UsageResponse> {\n return this.t.request({ method: \"GET\", path: \"/v1/usage\" });\n }\n}\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment);\n}\n","/**\n * Render a `ReconcileResult` as a clean, human-readable summary — for boot logs, CI output, and\n * `npx cronvello sync`. Zero-dependency ANSI colouring, opt-in via `color: true`.\n */\n\nimport type { ReconcileResult, ReconcileTaskChange } from \"./types.js\";\n\nexport interface FormatOptions {\n /** Emit ANSI colour codes (default false — safe for log files). */\n color?: boolean;\n /** Label the summary as a preview (\"would …\") rather than an applied change. */\n dryRun?: boolean;\n}\n\nconst ESC = String.fromCharCode(27); // ANSI escape\nconst ANSI = {\n reset: `${ESC}[0m`,\n dim: `${ESC}[2m`,\n bold: `${ESC}[1m`,\n green: `${ESC}[32m`,\n yellow: `${ESC}[33m`,\n red: `${ESC}[31m`,\n cyan: `${ESC}[36m`,\n gray: `${ESC}[90m`,\n} as const;\n\ntype Color = keyof typeof ANSI;\n\nconst GLYPH: Record<ReconcileTaskChange[\"action\"], { sign: string; color: Color }> = {\n created: { sign: \"+\", color: \"green\" },\n updated: { sign: \"~\", color: \"yellow\" },\n unchanged: { sign: \"=\", color: \"gray\" },\n deleted: { sign: \"-\", color: \"red\" },\n skipped: { sign: \"·\", color: \"cyan\" },\n};\n\n/** Build the multi-line summary string. */\nexport function formatSyncResult(result: ReconcileResult, options: FormatOptions = {}): string {\n const paint = (s: string, c: Color) => (options.color ? `${ANSI[c]}${s}${ANSI.reset}` : s);\n const verb = options.dryRun ? \"would sync\" : \"synced\";\n const lines: string[] = [];\n\n lines.push(\n `${paint(\"Cronvello\", \"cyan\")} ${verb} ${paint(`\"${result.jobName}\"`, \"bold\")} ${paint(`(${result.jobId})`, \"gray\")}`,\n );\n\n // Per-task lines, in a stable, readable order.\n const order: ReconcileTaskChange[\"action\"][] = [\"created\", \"updated\", \"deleted\", \"skipped\", \"unchanged\"];\n const sorted = [...result.changes].sort((a, b) => order.indexOf(a.action) - order.indexOf(b.action));\n for (const c of sorted) {\n const g = GLYPH[c.action];\n const detail =\n c.changedFields && c.changedFields.length\n ? paint(` (${c.changedFields.join(\", \")})`, \"gray\")\n : c.reason\n ? paint(` (${c.reason})`, \"gray\")\n : \"\";\n lines.push(` ${paint(g.sign, g.color)} ${paint(c.action.padEnd(9), g.color)} ${c.key}${detail}`);\n }\n\n const tally = [\n result.created && `${result.created} created`,\n result.updated && `${result.updated} updated`,\n result.unchanged && `${result.unchanged} unchanged`,\n result.deleted && `${result.deleted} deleted`,\n result.skipped && `${result.skipped} skipped`,\n ].filter(Boolean);\n const summary = tally.length ? tally.join(\", \") : \"no changes\";\n const containerNote = result.jobCreated ? paint(\" · container created\", \"gray\") : \"\";\n lines.push(` ${paint(summary, \"bold\")}${containerNote}`);\n\n return lines.join(\"\\n\");\n}\n","/**\n * @cronvello/sdk — code-first cron jobs for Cronvello.\n *\n * Two layers, one package:\n * • High-level registry: `defineCronvello({ jobs })` → `.sync()` + `.expressHandler()` / `.nextHandler()`.\n * Define jobs in code; the SDK reconciles them to https://api.cronvello.com and runs them.\n * • Low-level client: `new CronvelloClient({ apiKey })` → typed access to the whole `/v1` API.\n */\n\n// ── High-level registry ────────────────────────────────────────────────────\nexport { defineCronvello, type CronvelloApp, type CronvelloEnvConfig } from \"./registry/define.js\";\nexport { formatSyncResult, type FormatOptions } from \"./registry/format.js\";\nexport type {\n CronvelloAppConfig,\n CronvelloJobConfig,\n CronvelloJobConfigWithKey,\n CronvelloJobsInput,\n CronvelloJobContext,\n CronvelloJobHandler,\n CronvelloLogger,\n CronvelloHooks,\n CronvelloRunSource,\n ReconcileResult,\n ReconcileTaskChange,\n SyncOptions,\n} from \"./registry/types.js\";\nexport type { DispatchRequest, DispatchResponse } from \"./registry/dispatch.js\";\n\n// ── Schedule builders ──────────────────────────────────────────────────────\nexport {\n cron,\n every,\n everyMinutes,\n everyHours,\n hourly,\n daily,\n weekly,\n monthly,\n weekdays,\n weekends,\n schedule,\n type Weekday,\n} from \"./schedule/index.js\";\nexport { validateCron, isValidTimeZone, type CronValidation } from \"./internal/cron.js\";\n\n// ── Schedule preview (pure, no account) ─────────────────────────────────────\n// The local engine itself lives under the `@cronvello/sdk/dev` subpath; these two pure helpers are\n// surfaced here too because reasoning about *when* a schedule fires is useful everywhere.\nexport {\n nextOccurrence,\n previewSchedule,\n type NextOccurrenceOptions,\n type PreviewOptions,\n} from \"./internal/cron-schedule.js\";\n\n// ── Low-level client ───────────────────────────────────────────────────────\nexport {\n CronvelloClient,\n CRONVELLO_DEFAULT_BASE_URL,\n type CronvelloClientOptions,\n} from \"./client/client.js\";\n\n// ── Errors ─────────────────────────────────────────────────────────────────\nexport {\n CronvelloError,\n CronvelloApiError,\n CronvelloNetworkError,\n CronvelloConfigError,\n} from \"./internal/errors.js\";\n\n// ── Wire types ─────────────────────────────────────────────────────────────\nexport type {\n Urgency,\n ExecutionMode,\n HttpMethod,\n JobStatus,\n RunStatus,\n RunType,\n CallbackStatus,\n SuccessCriteria,\n PublicJob,\n PublicTask,\n PublicRun,\n JobCreateBody,\n JobUpdateBody,\n TaskCreateBody,\n TaskUpdateBody,\n RunsPage,\n TasksPage,\n RunNowResult,\n RegistryTaskInput,\n RegistryReconcileRequest,\n RegistryReconcileResponse,\n RegistryReconcileChange,\n MeResponse,\n UsageResponse,\n Pagination,\n RunsQuery,\n AccountTasksQuery,\n AccountRunsQuery,\n} from \"./internal/wire.js\";\n\n/**\n * Generate a strong random dispatch secret (hex). Convenience for setup scripts:\n * node -e \"console.log(require('@cronvello/sdk').generateDispatchSecret())\"\n */\nexport function generateDispatchSecret(bytes = 32): string {\n const buf = new Uint8Array(bytes);\n crypto.getRandomValues(buf);\n return Array.from(buf)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n","#!/usr/bin/env node\n/**\n * The `cronvello` CLI — inspect and drive your Cronvello account from the terminal.\n *\n * cronvello whoami account, plan, limits, usage\n * cronvello list [jobName] job containers, or the tasks inside one\n * cronvello tasks [--job name] account-wide task table\n * cronvello runs [--limit n] [--status failed] recent activity feed\n * cronvello run <taskId> trigger one task now\n * cronvello run <jobName> <task> …resolved by name\n * cronvello status health overview (active tasks, open DLQ, recent failures)\n * cronvello sync [configPath] [--dry] reconcile a code registry (loads your module)\n * cronvello dev [configPath] [--dry-run] start the local engine (run jobs locally, no account)\n * cronvello preview \"<cron>\" [--tz <z>] [-n 5] print the next N fire times of an expression\n * cronvello trigger [configPath] <jobKey> run a single job's handler once, locally\n * cronvello secret generate a strong dispatch secret\n *\n * Auth comes from the environment: CRONVELLO_API_KEY (required), CRONVELLO_API_URL (optional base).\n * Global flags: --json (machine output), --no-color, -h/--help, -v/--version.\n */\n\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL, fileURLToPath } from \"node:url\";\nimport { resolve } from \"node:path\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { CronvelloClient } from \"../client/client.js\";\nimport { CronvelloApiError, CronvelloConfigError } from \"../internal/errors.js\";\nimport { formatSyncResult } from \"../registry/format.js\";\nimport { generateDispatchSecret } from \"../index.js\";\nimport type { CronvelloApp } from \"../registry/define.js\";\nimport type { EngineEvent, JobSnapshot } from \"../dev/engine.js\";\nimport { previewSchedule, upcomingFires, localTimeZone, type UpcomingFire } from \"../internal/cron-schedule.js\";\nimport type { PublicJob, PublicRun, PublicTask } from \"../internal/wire.js\";\nimport { box, brand, c, ICON, relativeTime, setColor, sym, table } from \"./ui.js\";\n\nconst require2 = createRequire(import.meta.url);\nconst VERSION: string = (() => {\n try {\n return (require2(\"../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n})();\n\ninterface Args {\n command: string;\n positionals: string[];\n flags: Record<string, string | boolean>;\n}\n\n/** Long flags that take a following value (e.g. `--limit 20`, `--tz Europe/Berlin`). */\nconst VALUE_FLAGS = [\"limit\", \"status\", \"job\", \"type\", \"runType\", \"tz\", \"window\", \"count\", \"n\", \"port\", \"host\"];\n/** Short flags that take a following value (e.g. `-n 5`). */\nconst SHORT_VALUE_FLAGS = [\"n\", \"c\"];\n\nfunction parseArgs(argv: string[]): Args {\n const positionals: string[] = [];\n const flags: Record<string, string | boolean> = {};\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i]!;\n if (a.startsWith(\"--\")) {\n const key = a.slice(2);\n const next = argv[i + 1];\n if (next !== undefined && !next.startsWith(\"-\") && VALUE_FLAGS.includes(key)) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = true;\n }\n } else if (a.startsWith(\"-\") && a.length > 1) {\n const key = a.slice(1);\n const next = argv[i + 1];\n if (next !== undefined && !next.startsWith(\"-\") && SHORT_VALUE_FLAGS.includes(key)) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = true;\n }\n } else {\n positionals.push(a);\n }\n }\n return { command: positionals[0] ?? \"\", positionals: positionals.slice(1), flags };\n}\n\nconst out = (s = \"\"): void => void process.stdout.write(s + \"\\n\");\nconst json = (v: unknown): void => out(JSON.stringify(v, null, 2));\n\nfunction makeClient(): CronvelloClient {\n const apiKey = process.env[\"CRONVELLO_API_KEY\"];\n if (!apiKey) {\n throw new CronvelloConfigError(\"CRONVELLO_API_KEY is not set. Export your crn_live_… key first.\");\n }\n const baseUrl = process.env[\"CRONVELLO_API_URL\"];\n return new CronvelloClient({ apiKey, ...(baseUrl ? { baseUrl } : {}) });\n}\n\nfunction statusColor(status: string): string {\n const s = status.toUpperCase();\n if (s === \"ACTIVE\" || s === \"COMPLETED\") return c.green(status);\n if (s === \"DISABLED\" || s === \"QUEUED\" || s === \"RUNNING\") return c.cyan(status);\n if (s.startsWith(\"ERROR\") || s === \"FAILED\") return c.red(status);\n return c.yellow(status);\n}\n\nfunction header(subtitle: string): void {\n out(`${ICON} ${brand(\"Cronvello\")} ${c.gray(subtitle)}`);\n out();\n}\n\n// ─── Commands ────────────────────────────────────────────────────────────────\n\nasync function cmdWhoami(useJson: boolean): Promise<void> {\n const me = await makeClient().account.me();\n if (useJson) return json(me);\n const u = me.usage;\n const quota = u.executionQuota == null ? \"∞\" : String(u.executionQuota);\n out(\n box(`${me.accountName}`, [\n `${c.dim(\"account\")} #${me.accountId} ${me.isActive ? sym.ok : sym.fail} ${me.email}`,\n `${c.dim(\"plan\")} ${brand(me.plan?.displayName ?? \"—\")}`,\n `${c.dim(\"limits\")} ${me.limits.maxJobs ?? \"∞\"} jobs · ${me.limits.maxTasksPerJob ?? \"∞\"} tasks/job · ${me.limits.rateLimitPerMinute ?? \"∞\"}/min`,\n `${c.dim(\"usage\")} ${c.bold(String(u.executionCount))} / ${quota} executions ${c.gray(`(${u.jobsUsed} jobs)`)}`,\n `${c.dim(\"attention\")} ${me.summary.openDlqCount} DLQ · ${me.summary.heartbeatNeedsAttention} heartbeats · ${me.summary.activeMaintenanceWindows} maintenance`,\n ]),\n );\n}\n\nasync function cmdList(jobName: string | undefined, useJson: boolean): Promise<void> {\n const client = makeClient();\n if (jobName) {\n const container = (await client.jobs.list()).find((j) => j.name === jobName);\n if (!container) throw new CronvelloConfigError(`No job container named \"${jobName}\".`);\n const tasks = await client.jobs.listTasks(container.id);\n if (useJson) return json(tasks);\n header(`tasks in \"${container.name}\"`);\n out(renderTasks(tasks));\n return;\n }\n const jobs = await client.jobs.list();\n if (useJson) return json(jobs);\n header(\"job containers\");\n out(\n table(\n [{ header: \"NAME\" }, { header: \"STATUS\" }, { header: \"TASKS\", align: \"right\" }, { header: \"ACTIVE\", align: \"right\" }, { header: \"ERRORS\", align: \"right\" }, { header: \"ID\" }],\n jobs.map((j: PublicJob) => [\n c.bold(j.name),\n statusColor(j.status),\n String(j.taskCount),\n String(j.activeTaskCount),\n j.errorTaskCount ? c.red(String(j.errorTaskCount)) : c.gray(\"0\"),\n c.gray(j.id),\n ]),\n ),\n );\n out();\n out(c.gray(`${jobs.length} container(s) · ${jobs.reduce((n, j) => n + j.taskCount, 0)} task(s)`));\n}\n\nfunction renderTasks(tasks: PublicTask[]): string {\n const now = Date.now();\n return table(\n [{ header: \"TASK\" }, { header: \"STATUS\" }, { header: \"SCHEDULE\" }, { header: \"NEXT RUN\" }, { header: \"LAST\" }],\n tasks.map((t) => [\n c.bold(t.name),\n statusColor(t.status),\n c.cyan(t.schedule),\n relativeTime(t.nextRun, now),\n t.lastRunStatus ? statusColor(t.lastRunStatus) : c.gray(\"—\"),\n ]),\n );\n}\n\nasync function cmdTasks(flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const client = makeClient();\n const jobName = typeof flags[\"job\"] === \"string\" ? flags[\"job\"] : undefined;\n let jobId: string | undefined;\n if (jobName) {\n const container = (await client.jobs.list()).find((j) => j.name === jobName);\n if (!container) throw new CronvelloConfigError(`No job container named \"${jobName}\".`);\n jobId = container.id;\n }\n const page = await client.tasks.list({ limit: 100, ...(jobId ? { jobId } : {}) });\n if (useJson) return json(page);\n header(jobName ? `tasks · ${jobName}` : \"all tasks\");\n out(renderTasks(page.tasks));\n}\n\nasync function cmdRuns(flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const client = makeClient();\n const limit = clampLimit(flags[\"limit\"]);\n const status = typeof flags[\"status\"] === \"string\" ? (flags[\"status\"] as PublicRun[\"status\"]) : undefined;\n const page = await client.runs.list({ limit, ...(status ? { status } : {}) });\n if (useJson) return json(page);\n header(`recent runs${status ? ` · ${status}` : \"\"}`);\n const now = Date.now();\n out(\n table(\n [{ header: \"WHEN\" }, { header: \"TASK\" }, { header: \"JOB\" }, { header: \"STATUS\" }, { header: \"HTTP\", align: \"right\" }, { header: \"TOOK\", align: \"right\" }],\n page.runs.map((r: PublicRun) => [\n relativeTime(r.startedAt, now),\n c.bold(r.taskName),\n c.gray(r.jobName),\n statusColor(r.status),\n r.httpStatusCode == null ? c.gray(\"—\") : String(r.httpStatusCode),\n r.durationMs == null ? c.gray(\"—\") : `${r.durationMs}ms`,\n ]),\n ),\n );\n out();\n out(c.gray(`showing ${page.runs.length} of ${page.pagination.total} runs`));\n}\n\nasync function cmdRun(positionals: string[], useJson: boolean): Promise<void> {\n const client = makeClient();\n let taskId: string;\n if (positionals.length >= 2) {\n const [jobName, taskName] = positionals;\n const container = (await client.jobs.list()).find((j) => j.name === jobName);\n if (!container) throw new CronvelloConfigError(`No job container named \"${jobName}\".`);\n const task = (await client.jobs.listTasks(container.id)).find((t) => t.name === taskName);\n if (!task) throw new CronvelloConfigError(`No task \"${taskName}\" in \"${jobName}\".`);\n taskId = task.id;\n } else if (positionals.length === 1) {\n taskId = positionals[0]!;\n } else {\n throw new CronvelloConfigError(\"Usage: cronvello run <taskId> | cronvello run <jobName> <taskName>\");\n }\n const res = await client.tasks.runNow(taskId);\n if (useJson) return json(res);\n if (res.success) out(`${sym.ok} triggered ${c.bold(taskId)} ${res.runId ? c.gray(`→ ${res.runId}`) : \"\"}`);\n else out(`${sym.fail} ${c.red(res.error ?? \"run failed\")}`);\n}\n\nasync function cmdStatus(useJson: boolean): Promise<void> {\n const client = makeClient();\n const [me, jobs, failures] = await Promise.all([\n client.account.me(),\n client.jobs.list(),\n client.runs.list({ limit: 5, status: \"failed\" }),\n ]);\n if (useJson) return json({ me, jobs, recentFailures: failures.runs });\n const totalTasks = jobs.reduce((n, j) => n + j.taskCount, 0);\n const activeTasks = jobs.reduce((n, j) => n + j.activeTaskCount, 0);\n const errorTasks = jobs.reduce((n, j) => n + j.errorTaskCount, 0);\n const healthy = errorTasks === 0 && me.summary.openDlqCount === 0;\n header(\"status\");\n out(`${healthy ? sym.ok : sym.warn} ${healthy ? c.green(\"healthy\") : c.yellow(\"needs attention\")}`);\n out();\n out(` ${c.dim(\"containers\")} ${jobs.length}`);\n out(` ${c.dim(\"tasks\")} ${activeTasks}/${totalTasks} active${errorTasks ? c.red(` · ${errorTasks} errored`) : \"\"}`);\n out(` ${c.dim(\"open DLQ\")} ${me.summary.openDlqCount ? c.red(String(me.summary.openDlqCount)) : c.gray(\"0\")}`);\n out(` ${c.dim(\"executions\")} ${me.usage.executionCount} this period`);\n if (failures.runs.length) {\n out();\n out(c.dim(\" recent failures:\"));\n const now = Date.now();\n for (const r of failures.runs) out(` ${sym.fail} ${c.bold(r.taskName)} ${c.gray(r.jobName)} ${relativeTime(r.startedAt, now)} ${r.error ? c.red(truncate(r.error, 50)) : \"\"}`);\n }\n}\n\nasync function cmdSync(positionals: string[], flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const app = await loadApp(positionals[0]);\n const dryRun = !!flags[\"dry\"] || !!flags[\"dry-run\"];\n const result = await app.sync({ dryRun });\n if (useJson) return json(result);\n out(formatSyncResult(result, { color: true, dryRun }));\n}\n\n/**\n * `cronvello dev [entry]` — start the **local engine**: load the config module and actually run the\n * jobs on this machine (no account, no cloud). `--dry-run` prints what would fire in the next window\n * instead of executing anything. Runs until SIGINT, then shuts down cleanly.\n */\nasync function cmdDevEngine(positionals: string[], flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const app = await loadApp(positionals[0]);\n const dryRun = !!flags[\"dry-run\"] || !!flags[\"dry\"];\n\n if (dryRun) {\n const engine = app.dev({ autoStart: false, installSignalHandlers: false });\n const windowMs = parseDurationFlag(flags[\"window\"], 60 * 60 * 1000);\n const maxPerJob = 50;\n const fires = upcomingFires(\n engine.jobs().map((j) => ({ key: j.key, schedule: j.schedule, timeZone: j.timeZone })),\n { withinMs: windowMs, maxPerJob },\n );\n // Be honest when a high-frequency schedule hit the per-job cap — the window isn't fully shown.\n const cappedJobs = [...new Set(fires.map((f) => f.key))].filter(\n (key) => fires.filter((f) => f.key === key).length >= maxPerJob,\n );\n if (useJson) {\n return json({\n window: { ms: windowMs },\n capped: cappedJobs,\n fires: fires.map((f) => ({ key: f.key, time: f.time.toISOString(), schedule: f.schedule, timeZone: f.timeZone })),\n });\n }\n header(`dev · dry-run · next ${formatDuration(windowMs)}`);\n out(renderUpcoming(fires));\n out();\n out(c.gray(fires.length ? `${fires.length} fire(s) would run — no handlers were executed` : \"nothing scheduled in this window\"));\n if (cappedJobs.length) {\n out(c.yellow(`▲ output capped at ${maxPerJob} per job (${cappedJobs.join(\", \")}) — high-frequency schedule, not the full window`));\n }\n return;\n }\n\n const engine = app.dev({ autoStart: false, installSignalHandlers: false, onEvent: (e) => renderEvent(e, useJson) });\n\n // Start first so the snapshot has each job's computed next-fire time, then print the table.\n engine.start();\n\n // Optional local dashboard. Loaded lazily so it never weighs on the non-dashboard path.\n let dashboardUrl: string | undefined;\n if (flags[\"dashboard\"]) {\n const { startDashboard } = await import(\"../dev/dashboard.js\");\n const port = typeof flags[\"port\"] === \"string\" ? Number.parseInt(flags[\"port\"], 10) : undefined;\n const host = typeof flags[\"host\"] === \"string\" ? flags[\"host\"] : undefined;\n try {\n const dash = await startDashboard(engine, { port, host });\n dashboardUrl = dash.url;\n engine.onStop(() => dash.close()); // Ctrl-C → engine.stop() tears the dashboard down too.\n } catch (err) {\n await engine.stop();\n throw err; // surfaced cleanly (e.g. \"port … already in use\") by run()'s catch\n }\n }\n\n if (!useJson) {\n header(`dev · local engine ${c.gray(\"· no account, no cloud\")}`);\n out(renderSchedule(engine.snapshot()));\n out();\n if (dashboardUrl) out(`${sym.ok} dashboard → ${c.cyan(dashboardUrl)}`);\n out(c.gray(`watching ${engine.jobs().length} job(s) — press Ctrl-C to stop`));\n out();\n }\n\n // Block until interrupted, then drain in-flight runs and print a short summary.\n await new Promise<void>((resolve) => {\n const onSignal = (): void => {\n process.removeListener(\"SIGINT\", onSignal);\n process.removeListener(\"SIGTERM\", onSignal);\n void engine.stop().then(resolve);\n };\n process.once(\"SIGINT\", onSignal);\n process.once(\"SIGTERM\", onSignal);\n });\n\n if (!useJson) {\n out();\n const runs = engine.runs();\n const ok = runs.filter((r) => r.status === \"success\").length;\n const bad = runs.filter((r) => r.status === \"error\" || r.status === \"timed_out\").length;\n out(c.gray(`stopped — ${runs.length} run(s) this session (${ok} ok${bad ? `, ${c.red(`${bad} failed`)}` : \"\"})`));\n }\n}\n\n/** `cronvello trigger [entry] <jobKey>` — run a single job's handler once, locally (no deploy). */\nasync function cmdTrigger(positionals: string[], useJson: boolean): Promise<void> {\n // Last positional is the job key; an optional earlier one is the config path.\n const jobKey = positionals[positionals.length - 1];\n const configPath = positionals.length >= 2 ? positionals[0] : undefined;\n if (!jobKey) throw new CronvelloConfigError(\"Usage: cronvello trigger [configPath] <jobKey>\");\n const app = await loadApp(configPath);\n if (!app.keys().includes(jobKey)) {\n throw new CronvelloConfigError(`Unknown job \"${jobKey}\". Known: ${app.keys().join(\", \") || \"(none)\"}`);\n }\n if (!useJson) out(`${sym.arrow} running ${c.bold(jobKey)} locally…`);\n const started = Date.now();\n const result = await app.trigger(jobKey);\n if (useJson) return json({ job: jobKey, result });\n out(`${sym.ok} ${c.bold(jobKey)} ${c.gray(`done in ${Date.now() - started}ms`)}`);\n if (result !== undefined && result !== null) {\n out(c.dim(\" result:\"));\n out(JSON.stringify(result, null, 2).split(\"\\n\").map((l) => \" \" + l).join(\"\\n\"));\n }\n}\n\n/** `cronvello preview \"<cron>\" [--tz <IANA>] [-n 5]` — print the next N fire times of an expression. */\nfunction cmdPreview(positionals: string[], flags: Args[\"flags\"], useJson: boolean): void {\n const expr = positionals[0];\n if (!expr) throw new CronvelloConfigError('Usage: cronvello preview \"<cron>\" [--tz <IANA>] [-n 5]');\n const tz = typeof flags[\"tz\"] === \"string\" ? flags[\"tz\"] : localTimeZone();\n const count = clampLimit(flags[\"n\"] ?? flags[\"count\"] ?? flags[\"limit\"]);\n\n let times: Date[];\n try {\n times = previewSchedule(expr, { timeZone: tz, count });\n } catch (err) {\n throw new CronvelloConfigError(err instanceof Error ? err.message : String(err));\n }\n\n if (useJson) return json({ schedule: expr, timeZone: tz, next: times.map((t) => t.toISOString()) });\n header(`preview ${c.cyan(expr)} ${c.gray(`· ${tz}`)}`);\n if (!times.length) {\n out(c.gray(\"no upcoming fire times (does this expression ever match?)\"));\n return;\n }\n const now = Date.now();\n out(\n table(\n [{ header: \"#\", align: \"right\" }, { header: \"LOCAL TIME\" }, { header: \"WHEN\" }, { header: \"UTC\" }],\n times.map((t, i) => [\n c.gray(String(i + 1)),\n c.bold(formatInZone(t, tz)),\n relativeTime(t.toISOString(), now),\n c.gray(t.toISOString()),\n ]),\n ),\n );\n}\n\n// ─── Dev rendering ───────────────────────────────────────────────────────────\n\n/** The schedule table shown when the engine starts. */\nfunction renderSchedule(snapshot: JobSnapshot[]): string {\n const now = Date.now();\n return table(\n [{ header: \"JOB\" }, { header: \"SCHEDULE\" }, { header: \"TZ\" }, { header: \"NEXT RUN\" }, { header: \"WHEN\" }],\n snapshot.map((s) => [\n c.bold(s.key),\n c.cyan(s.schedule),\n c.gray(s.timeZone),\n s.nextFire ? formatInZone(s.nextFire, s.timeZone) : c.gray(\"—\"),\n s.nextFire ? relativeTime(s.nextFire.toISOString(), now) : c.gray(\"—\"),\n ]),\n );\n}\n\n/** The dry-run table of upcoming fires. */\nfunction renderUpcoming(fires: UpcomingFire[]): string {\n const now = Date.now();\n return table(\n [{ header: \"WHEN\" }, { header: \"LOCAL TIME\" }, { header: \"JOB\" }, { header: \"SCHEDULE\" }],\n fires.map((f) => [\n relativeTime(f.time.toISOString(), now),\n c.bold(formatInZone(f.time, f.timeZone)),\n c.cyan(f.key),\n c.gray(f.schedule),\n ]),\n );\n}\n\n/** Render one live engine event as a timestamped line (or an NDJSON line under --json). */\nfunction renderEvent(event: EngineEvent, useJson: boolean): void {\n if (useJson) return out(JSON.stringify(event));\n const ts = c.gray(clockStamp(Date.now()));\n switch (event.type) {\n case \"fire\":\n out(`${ts} ${sym.arrow} ${c.bold(event.key)} ${c.gray(event.attempt > 1 ? `(attempt ${event.attempt})` : \"fired\")}`);\n break;\n case \"success\":\n out(`${ts} ${sym.ok} ${c.bold(event.key)} ${c.gray(`${event.durationMs}ms${event.attempts > 1 ? ` · ${event.attempts} attempts` : \"\"}`)}`);\n break;\n case \"error\":\n out(`${ts} ${sym.fail} ${c.bold(event.key)} ${c.red(event.error)} ${c.gray(event.willRetry ? \"· will retry\" : \"· gave up\")}`);\n break;\n case \"timeout\":\n out(`${ts} ${sym.fail} ${c.bold(event.key)} ${c.red(\"timed out\")} ${c.gray(`after ${event.durationMs}ms${event.willRetry ? \" · will retry\" : \" · gave up\"}`)}`);\n break;\n case \"retry\":\n out(`${ts} ${sym.warn} ${c.bold(event.key)} ${c.gray(`retrying in ${event.delayMs}ms (attempt ${event.attempt})`)}`);\n break;\n case \"skipped\":\n out(`${ts} ${sym.warn} ${c.bold(event.key)} ${c.gray(\"skipped — previous run still in flight\")}`);\n break;\n // \"scheduled\" / \"engine-start\" / \"engine-stop\" are intentionally quiet in the live feed.\n }\n}\n\n/** Format an instant in an IANA zone as \"YYYY-MM-DD HH:MM:SS\". */\nfunction formatInZone(date: Date, timeZone: string): string {\n try {\n const parts = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone,\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\",\n hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\", hour12: false,\n }).formatToParts(date);\n const m: Record<string, string> = {};\n for (const p of parts) if (p.type !== \"literal\") m[p.type] = p.value;\n const hour = m[\"hour\"] === \"24\" ? \"00\" : m[\"hour\"];\n return `${m[\"year\"]}-${m[\"month\"]}-${m[\"day\"]} ${hour}:${m[\"minute\"]}:${m[\"second\"]}`;\n } catch {\n return date.toISOString();\n }\n}\n\n/** Wall-clock HH:MM:SS in the local zone, for live-feed line stamps. */\nfunction clockStamp(nowMs: number): string {\n return formatInZone(new Date(nowMs), localTimeZone()).slice(11);\n}\n\nfunction parseDurationFlag(value: string | boolean | undefined, fallback: number): number {\n if (typeof value !== \"string\") return fallback;\n const m = /^(\\d+)\\s*(s|m|h|d)?$/i.exec(value.trim());\n if (!m) return fallback;\n const n = Number(m[1]);\n const unit = (m[2] ?? \"m\").toLowerCase();\n const mult = unit === \"s\" ? 1000 : unit === \"h\" ? 3_600_000 : unit === \"d\" ? 86_400_000 : 60_000;\n return n * mult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms % 86_400_000 === 0) return `${ms / 86_400_000}d`;\n if (ms % 3_600_000 === 0) return `${ms / 3_600_000}h`;\n if (ms % 60_000 === 0) return `${ms / 60_000}m`;\n return `${Math.round(ms / 1000)}s`;\n}\n\nfunction cmdSecret(useJson: boolean): void {\n const secret = generateDispatchSecret();\n if (useJson) return json({ dispatchSecret: secret });\n out(secret);\n}\n\n// ─── Config-module loading (sync / dev) ──────────────────────────────────────\n\nconst DEFAULT_CONFIG_PATHS = [\n \"cronvello.config.ts\", \"cronvello.config.js\", \"cronvello.config.mjs\",\n \"cronvello.ts\", \"cronvello.js\", \"src/cronvello.ts\", \"src/cronvello.js\",\n];\n\nfunction looksLikeApp(v: unknown): v is CronvelloApp {\n return !!v && typeof v === \"object\" && typeof (v as CronvelloApp).sync === \"function\" && typeof (v as CronvelloApp).trigger === \"function\";\n}\n\nasync function loadApp(pathArg: string | undefined): Promise<CronvelloApp> {\n const candidate = pathArg ?? DEFAULT_CONFIG_PATHS.find((p) => existsSync(resolve(process.cwd(), p)));\n if (!candidate) {\n throw new CronvelloConfigError(\n `No config module found. Pass a path (cronvello sync ./cronvello.config.js) or add one of: ${DEFAULT_CONFIG_PATHS.join(\", \")}.`,\n );\n }\n const abs = resolve(process.cwd(), candidate);\n if (!existsSync(abs)) throw new CronvelloConfigError(`Config module not found: ${abs}`);\n\n let mod: Record<string, unknown>;\n try {\n mod = (await import(pathToFileURL(abs).href)) as Record<string, unknown>;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (/Unknown file extension|\\.ts|ERR_UNKNOWN/.test(msg) && abs.endsWith(\".ts\")) {\n throw new CronvelloConfigError(\n `Could not import a TypeScript config directly. Run the CLI under a TS loader, e.g.\\n node --import tsx node_modules/@cronvello/sdk/dist/cli.js sync ${candidate}\\nor point at a compiled .js file.`,\n );\n }\n throw new CronvelloConfigError(`Failed to import ${candidate}: ${msg}`);\n }\n\n const found = looksLikeApp(mod[\"default\"]) ? mod[\"default\"]\n : looksLikeApp(mod[\"cronvello\"]) ? mod[\"cronvello\"]\n : looksLikeApp(mod[\"app\"]) ? mod[\"app\"]\n : Object.values(mod).find(looksLikeApp);\n if (!found) {\n throw new CronvelloConfigError(`${candidate} does not export a Cronvello app (export default defineCronvello({…}) or a named \\`cronvello\\`).`);\n }\n return found as CronvelloApp;\n}\n\n// ─── Help / dispatch ─────────────────────────────────────────────────────────\n\nfunction printHelp(): void {\n out(`${ICON} ${brand(\"Cronvello\")} ${c.gray(\"· code-first cron\")} ${c.dim(\"v\" + VERSION)}`);\n out();\n out(c.bold(\"USAGE\"));\n out(` ${c.cyan(\"cronvello\")} <command> [options]`);\n out();\n out(c.bold(\"COMMANDS\"));\n const cmds: [string, string][] = [\n [\"whoami\", \"account, plan, limits & usage\"],\n [\"list [jobName]\", \"job containers, or tasks inside one\"],\n [\"tasks [--job <name>]\", \"account-wide task table\"],\n [\"runs [--limit n] [--status s]\", \"recent execution feed\"],\n [\"run <taskId>\", \"trigger a task now (or: run <jobName> <taskName>)\"],\n [\"status\", \"health overview + recent failures\"],\n [\"sync [path] [--dry]\", \"reconcile a code registry (loads your module)\"],\n [\"dev [path] [--dry-run]\", \"start the local engine — run jobs locally, no account\"],\n [\"dev --dashboard [--port n]\", \"…plus a local web dashboard (127.0.0.1, live runs + run-now)\"],\n [\"preview \\\"<cron>\\\" [-n 5]\", \"print the next N fire times (--tz <IANA>)\"],\n [\"trigger [path] <jobKey>\", \"run a single job handler once, locally\"],\n [\"secret\", \"generate a strong dispatch secret\"],\n ];\n for (const [name, desc] of cmds) out(` ${c.cyan(name.padEnd(30))} ${c.gray(desc)}`);\n out();\n out(c.bold(\"GLOBAL\"));\n out(` ${c.cyan(\"--json\".padEnd(30))} ${c.gray(\"machine-readable output\")}`);\n out(` ${c.cyan(\"--no-color\".padEnd(30))} ${c.gray(\"disable colour\")}`);\n out(` ${c.cyan(\"-h, --help\".padEnd(30))} ${c.gray(\"show this help\")}`);\n out(` ${c.cyan(\"-v, --version\".padEnd(30))} ${c.gray(\"print version\")}`);\n out();\n out(c.gray(\"Auth: export CRONVELLO_API_KEY (crn_live_…). Optional: CRONVELLO_API_URL.\"));\n}\n\nfunction clampLimit(v: string | boolean | undefined): number {\n const n = typeof v === \"string\" ? Number(v) : NaN;\n if (!Number.isFinite(n)) return 20;\n return Math.min(Math.max(Math.trunc(n), 1), 100);\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length > n ? s.slice(0, n - 1) + \"…\" : s;\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const args = parseArgs(argv);\n if (args.flags[\"no-color\"]) setColor(false);\n const useJson = !!args.flags[\"json\"];\n\n if (args.flags[\"version\"] || args.flags[\"v\"]) {\n out(VERSION);\n return 0;\n }\n if (!args.command || args.flags[\"help\"] || args.flags[\"h\"] || args.command === \"help\") {\n printHelp();\n return 0;\n }\n\n try {\n switch (args.command) {\n case \"whoami\": await cmdWhoami(useJson); break;\n case \"list\": await cmdList(args.positionals[0], useJson); break;\n case \"tasks\": await cmdTasks(args.flags, useJson); break;\n case \"runs\": await cmdRuns(args.flags, useJson); break;\n case \"run\": await cmdRun(args.positionals, useJson); break;\n case \"status\": await cmdStatus(useJson); break;\n case \"sync\": await cmdSync(args.positionals, args.flags, useJson); break;\n case \"dev\": await cmdDevEngine(args.positionals, args.flags, useJson); break;\n case \"preview\": cmdPreview(args.positionals, args.flags, useJson); break;\n case \"trigger\": await cmdTrigger(args.positionals, useJson); break;\n case \"secret\": cmdSecret(useJson); break;\n default:\n out(`${sym.fail} Unknown command \"${args.command}\". Run ${c.cyan(\"cronvello --help\")}.`);\n return 1;\n }\n return 0;\n } catch (err) {\n if (err instanceof CronvelloApiError) {\n out(`${sym.fail} ${c.red(`API ${err.status}`)} ${err.message}${err.isRateLimited && err.retryAfterSeconds ? c.gray(` (retry in ${err.retryAfterSeconds}s)`) : \"\"}`);\n } else if (err instanceof CronvelloConfigError) {\n out(`${sym.fail} ${err.message}`);\n } else {\n out(`${sym.fail} ${err instanceof Error ? err.message : String(err)}`);\n }\n return 1;\n }\n}\n\n/**\n * True when this module is the process entry point — including when launched through the `bin`\n * symlink (`node_modules/.bin/cronvello`), where `process.argv[1]` is the symlink path. Resolving\n * both sides through `realpathSync` makes the comparison symlink-proof; under a test runner the\n * entry is the runner, so this is false and importing the module never auto-runs.\n */\nfunction isMainModule(): boolean {\n try {\n const argv1 = process.argv?.[1];\n if (!argv1) return false;\n return realpathSync(argv1) === realpathSync(fileURLToPath(import.meta.url));\n } catch {\n return false;\n }\n}\n\nif (isMainModule()) {\n // Exit quietly when the reader closes the pipe early (e.g. `cronvello list | head`).\n process.stdout.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") process.exit(0);\n throw err;\n });\n run(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n });\n}\n","/**\n * Zero-dependency terminal UI helpers for the `cronvello` CLI: colour, symbols, tables, boxes,\n * relative times. Colour auto-disables when stdout is not a TTY, when NO_COLOR is set, or when\n * `--no-color` was passed (see `setColor`).\n */\n\nconst E = String.fromCharCode(27);\nconst ENV = typeof process !== \"undefined\" && process.env ? process.env : {};\nlet COLOR =\n !ENV[\"NO_COLOR\"] &&\n (!!ENV[\"FORCE_COLOR\"] || !!(typeof process !== \"undefined\" && process.stdout && process.stdout.isTTY));\n\nexport function setColor(on: boolean): void {\n COLOR = on;\n}\n\nfunction wrap(code: number, close: number, s: string): string {\n return COLOR ? `${E}[${code}m${s}${E}[${close}m` : s;\n}\n\nexport const c = {\n bold: (s: string) => wrap(1, 22, s),\n dim: (s: string) => wrap(2, 22, s),\n red: (s: string) => wrap(31, 39, s),\n green: (s: string) => wrap(32, 39, s),\n yellow: (s: string) => wrap(33, 39, s),\n blue: (s: string) => wrap(34, 39, s),\n magenta: (s: string) => wrap(35, 39, s),\n cyan: (s: string) => wrap(36, 39, s),\n gray: (s: string) => wrap(90, 39, s),\n};\n\n/** Cronvello brand: indigo-ish on supported terminals (256-colour), falling back to cyan. */\nexport function brand(s: string): string {\n return COLOR ? `${E}[38;5;63m${s}${E}[39m` : s;\n}\n\nexport const sym = {\n ok: c.green(\"✔\"),\n fail: c.red(\"✗\"),\n warn: c.yellow(\"▲\"),\n info: c.cyan(\"ℹ\"),\n dot: c.gray(\"·\"),\n arrow: c.gray(\"→\"),\n};\n\n/** Visible length of a string, ignoring ANSI escape codes — for column alignment. */\nexport function visibleLength(s: string): number {\n // eslint-disable-next-line no-control-regex\n return s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n}\n\nfunction padEndVisible(s: string, width: number): string {\n const pad = width - visibleLength(s);\n return pad > 0 ? s + \" \".repeat(pad) : s;\n}\n\nexport interface TableColumn {\n header: string;\n /** Right-align (e.g. numbers). */\n align?: \"left\" | \"right\";\n}\n\n/** Render an aligned table. Cells may already contain colour codes. */\nexport function table(columns: TableColumn[], rows: string[][]): string {\n const widths = columns.map((col, i) =>\n Math.max(visibleLength(col.header), ...rows.map((r) => visibleLength(r[i] ?? \"\"))),\n );\n const fmtRow = (cells: string[]) =>\n cells\n .map((cell, i) => {\n const w = widths[i]!;\n if (columns[i]?.align === \"right\") {\n const pad = w - visibleLength(cell);\n return (pad > 0 ? \" \".repeat(pad) : \"\") + cell;\n }\n return padEndVisible(cell, w);\n })\n .join(\" \");\n const head = fmtRow(columns.map((col) => c.dim(col.header)));\n const body = rows.map(fmtRow);\n return [head, ...body].join(\"\\n\");\n}\n\n/** A simple rounded box around a block of text (already-coloured lines are fine). */\nexport function box(title: string, lines: string[]): string {\n const inner = [title, \"\", ...lines];\n const width = Math.max(...inner.map(visibleLength));\n const top = c.gray(\"╭─ \") + brand(title) + c.gray(\" \" + \"─\".repeat(Math.max(0, width - visibleLength(title) - 1)) + \"╮\");\n const mid = lines.map((l) => c.gray(\"│ \") + padEndVisible(l, width) + c.gray(\" │\"));\n const bot = c.gray(\"╰\" + \"─\".repeat(width + 2) + \"╯\");\n return [top, ...mid, bot].join(\"\\n\");\n}\n\n/** Compact relative time like \"3m ago\" / \"in 2h\" from an ISO string. `nowMs` is injectable for tests. */\nexport function relativeTime(iso: string | null, nowMs: number): string {\n if (!iso) return c.gray(\"—\");\n const then = Date.parse(iso);\n if (Number.isNaN(then)) return c.gray(\"—\");\n const deltaSec = Math.round((then - nowMs) / 1000);\n const future = deltaSec > 0;\n const abs = Math.abs(deltaSec);\n const unit =\n abs < 60 ? `${abs}s` : abs < 3600 ? `${Math.round(abs / 60)}m` : abs < 86400 ? `${Math.round(abs / 3600)}h` : `${Math.round(abs / 86400)}d`;\n return c.gray(future ? `in ${unit}` : `${unit} ago`);\n}\n\nexport const ICON = brand(\"◷\"); // clock-ish brand mark for the header\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/cron-schedule.ts","../src/dev/dashboard-assets.ts","../src/dev/dashboard.ts","../src/internal/errors.ts","../src/internal/http.ts","../src/client/client.ts","../src/registry/format.ts","../src/index.ts","../src/cli/index.ts","../src/cli/ui.ts"],"names":["out","resolve","run","c","header","sorted","engine","startDashboard"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAA,CAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACnB9B,IAAA,iBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,iBAAA,EAAA;AAAA,EAAA,cAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AA0CO,SAAS,cAAA,CAAe,MAAA,EAAqB,OAAA,GAA4B,EAAC,EAA6B;AAC5G,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,YAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,YAAA;AAC7B,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAyB;AAEhD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,CAAC,GAAA,EAAK,GAAA,KAAQ,aAAA,CAAc,MAAA,EAAQ,UAAA,EAAY,GAAA,EAAK,GAAG,CAAC,CAAA;AAE1F,EAAA,OAAO,IAAI,OAAA,CAAyB,CAACC,QAAAA,EAAS,MAAA,KAAW;AACvD,IAAA,MAAM,OAAA,GAAU,CAAC,GAAA,KAAqC;AACpD,MAAA,MAAA,CAAO,cAAA,CAAe,SAAS,OAAO,CAAA;AACtC,MAAA,IAAI,GAAA,CAAI,SAAS,YAAA,EAAc;AAC7B,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,IAAI,CAAA,IAAA,EAAO,IAAI,oDAA+C,CAAC,CAAA;AAAA,MAC/G,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,GAAG,CAAA;AAAA,MACZ;AAAA,IACF,CAAA;AACA,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,OAAO,CAAA;AAE5B,IAAA,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,MAAM;AAC9B,MAAA,MAAA,CAAO,cAAA,CAAe,SAAS,OAAO,CAAA;AACtC,MAAA,MAAM,UAAA,GAAc,MAAA,CAAO,OAAA,EAAQ,CAAkB,IAAA;AACrD,MAAA,MAAM,KAAA,GAAQ,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,OAAO,WAAA,GAAc,IAAA;AAClE,MAAA,MAAM,GAAA,GAAM,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAEzC,MAAA,IAAI,MAAA,GAAS,KAAA;AACb,MAAA,MAAM,QAAQ,MAAqB;AACjC,QAAA,IAAI,MAAA,EAAQ,OAAO,OAAA,CAAQ,OAAA,EAAQ;AACnC,QAAA,MAAA,GAAS,IAAA;AACT,QAAA,KAAA,MAAW,MAAA,IAAU,UAAA,EAAY,MAAA,CAAO,GAAA,EAAI;AAC5C,QAAA,UAAA,CAAW,KAAA,EAAM;AACjB,QAAA,OAAO,IAAI,OAAA,CAAc,CAAC,IAAA,KAAS;AAGjC,UAAA,MAAA,CAAO,mBAAA,IAAsB;AAC7B,UAAA,MAAA,CAAO,KAAA,CAAM,MAAM,IAAA,EAAM,CAAA;AAAA,QAC3B,CAAC,CAAA;AAAA,MACH,CAAA;AAEA,MAAAA,SAAQ,EAAE,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,OAAO,CAAA;AAAA,IAC1C,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAEA,SAAS,aAAA,CACP,MAAA,EACA,UAAA,EACA,GAAA,EACA,GAAA,EACM;AACN,EAAA,MAAM,MAAM,IAAI,GAAA,CAAI,GAAA,CAAI,GAAA,IAAO,KAAK,kBAAkB,CAAA;AACtD,EAAA,MAAM,OAAO,GAAA,CAAI,QAAA;AACjB,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,IAAU,KAAA;AAG7B,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,GAAA,EAAK;AACpC,IAAA,OAAO,QAAA,CAAS,KAAK,cAAc,CAAA;AAAA,EACrC;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,aAAA,EAAe;AAC9C,IAAA,OAAO,eAAA,CAAgB,MAAA,EAAQ,UAAA,EAAY,GAAA,EAAK,GAAG,CAAA;AAAA,EACrD;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,aAAA,EAAe;AAC9C,IAAA,OAAO,QAAA,CAAS,KAAK,GAAA,EAAK;AAAA,MACxB,EAAA,EAAI,IAAA;AAAA,MACJ,IAAA,EAAM,MAAA,CAAO,IAAA,EAAK,CAAE,MAAA;AAAA,MACpB,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,WAAW,MAAA,CAAO;AAAA,KACnB,CAAA;AAAA,EACH;AAKA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,YAAA,EAAc;AAC7C,IAAA,MAAM,IAAA,GAAO,OAAO,IAAA,EAAK;AACzB,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoD;AAC1E,IAAA,KAAA,MAAWC,IAAAA,IAAO,IAAA,EAAM,IAAI,CAAC,SAAA,CAAU,GAAA,CAAIA,IAAAA,CAAI,GAAG,CAAA,EAAG,SAAA,CAAU,GAAA,CAAIA,IAAAA,CAAI,KAAKA,IAAG,CAAA;AAC/E,IAAA,MAAM,gBAAgB,UAAA,CAAW,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,UAAU,CAAC,CAAA;AACjE,IAAA,OAAO,QAAA,CAAS,KAAK,GAAA,EAAK;AAAA,MACxB,MAAA,EAAQ;AAAA,QACN,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,YAAY,MAAA,CAAO,UAAA;AAAA,QACnB,GAAA,EAAK,KAAK,GAAA;AAAI,OAChB;AAAA,MACA,MAAM,MAAA,CAAO,QAAA,EAAS,CAAE,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QAClC,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,WAAA,EAAa,EAAE,WAAA,IAAe,IAAA;AAAA,QAC9B,UAAU,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,aAAY,GAAI,IAAA;AAAA,QAClD,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,OAAA,EAAS,SAAA,CAAU,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,IAAK,IAAA;AAAA,QACjC,UAAU,QAAA,CAAS,CAAA,CAAE,QAAA,EAAU,CAAA,CAAE,UAAU,aAAa;AAAA,OAC1D,CAAE,CAAA;AAAA,MACF;AAAA,KACD,CAAA;AAAA,EACH;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,kBAAA,EAAoB;AACnD,IAAA,GAAA,CAAI,UAAU,GAAA,EAAK,EAAE,gBAAgB,qCAAA,EAAuC,eAAA,EAAiB,YAAY,CAAA;AACzG,IAAA,MAAM,IAAA,GAAO,OAAO,QAAA,EAAS;AAC7B,IAAA,OAAO,KAAK,GAAA,CAAI,GAAA,CAAI,KAAK,MAAA,GAAS,IAAA,GAAO,OAAO,EAAE,CAAA;AAAA,EACpD;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,WAAA,EAAa;AAC5C,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AACtC,IAAA,OAAO,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,GAAA,GAAM,MAAA,CAAO,QAAQ,GAAG,CAAA,GAAI,MAAA,CAAO,IAAA,EAAM,CAAA;AAAA,EACrE;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,CAAK,UAAA,CAAW,YAAY,CAAA,EAAG;AACrD,IAAA,OAAO,QAAA,CAAS,KAAK,GAAA,EAAK,MAAA,CAAO,QAAQ,SAAA,CAAU,IAAA,EAAM,YAAY,CAAC,CAAC,CAAA;AAAA,EACzE;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,CAAK,UAAA,CAAW,eAAe,CAAA,EAAG;AACxD,IAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,EAAM,eAAe,CAAA;AAC3C,IAAA,MAAM,GAAA,GAAM,OAAO,QAAA,EAAS,CAAE,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,KAAQ,GAAG,CAAA;AACvD,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,EAAE,KAAA,EAAO,CAAA,aAAA,EAAgB,GAAG,CAAA,CAAA,CAAA,EAAK,CAAA;AACrE,IAAA,MAAM,IAAI,UAAA,CAAW,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAG,CAAC,CAAA;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,GAAA,CAAI,QAAA,EAAU,EAAE,UAAU,GAAA,CAAI,QAAA,EAAU,KAAA,EAAO,CAAA,EAAG,CAAA;AAChF,MAAA,OAAO,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAC,CAAA;AAAA,IAC7D,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,EAAE,CAAA;AAAA,IAC9B;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,IAAA,KAAS,WAAA,EAAa;AAC5C,IAAA,MAAM,OAAO,MAAA,CAAO,QAAA,EAAS,CAAE,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACzC,KAAK,CAAA,CAAE,GAAA;AAAA,MACP,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,UAAU,CAAA,CAAE,QAAA;AAAA,MACZ,aAAa,CAAA,CAAE,WAAA;AAAA,MACf,UAAU,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,aAAY,GAAI,IAAA;AAAA,MAClD,SAAS,CAAA,CAAE;AAAA,KACb,CAAE,CAAA;AACF,IAAA,OAAO,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,IAAI,CAAA;AAAA,EAChC;AAGA,EAAA,IAAI,MAAA,KAAW,MAAA,IAAU,IAAA,CAAK,UAAA,CAAW,eAAe,CAAA,EAAG;AACzD,IAAA,IAAI,CAAC,YAAA,CAAa,GAAG,CAAA,EAAG,OAAO,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,EAAE,KAAA,EAAO,+BAAA,EAAiC,CAAA;AAC5F,IAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,EAAM,eAAe,CAAA;AAC3C,IAAA,OAAO,KAAK,MAAA,CACT,OAAA,CAAQ,GAAG,CAAA,CACX,KAAK,CAAC,MAAA,KAAW,QAAA,CAAS,GAAA,EAAK,KAAK,MAAM,CAAC,CAAA,CAC3C,KAAA,CAAM,CAAC,GAAA,KAAe;AACrB,MAAA,MAAM,SAAS,aAAA,CAAc,IAAA,CAAK,GAAA,CAAI,OAAO,IAAI,GAAA,GAAM,GAAA;AACvD,MAAA,QAAA,CAAS,KAAK,MAAA,EAAQ,EAAE,KAAA,EAAO,GAAA,CAAI,SAAS,CAAA;AAAA,IAC9C,CAAC,CAAA;AAAA,EACL;AAEA,EAAA,QAAA,CAAS,GAAA,EAAK,GAAA,EAAK,EAAE,KAAA,EAAO,aAAa,CAAA;AAC3C;AAGA,SAAS,eAAA,CACP,MAAA,EACA,UAAA,EACA,GAAA,EACA,GAAA,EACM;AACN,EAAA,GAAA,CAAI,UAAU,GAAA,EAAK;AAAA,IACjB,cAAA,EAAgB,kCAAA;AAAA,IAChB,eAAA,EAAiB,UAAA;AAAA,IACjB,UAAA,EAAY,YAAA;AAAA,IACZ,mBAAA,EAAqB;AAAA,GACtB,CAAA;AACD,EAAA,GAAA,CAAI,MAAM,iBAAiB,CAAA;AAC3B,EAAA,UAAA,CAAW,IAAI,GAAG,CAAA;AAElB,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,SAAA,CAAU,CAAC,KAAA,KAAU;AAC9C,IAAA,GAAA,CAAI,KAAA,CAAM,CAAA,MAAA,EAAS,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC;;AAAA,CAAM,CAAA;AAAA,EAChD,CAAC,CAAA;AAED,EAAA,MAAM,YAAY,WAAA,CAAY,MAAM,IAAI,KAAA,CAAM,YAAY,GAAG,YAAY,CAAA;AACzE,EAAA,IAAI,OAAO,SAAA,CAAU,KAAA,KAAU,UAAA,YAAsB,KAAA,EAAM;AAE3D,EAAA,MAAM,UAAU,MAAY;AAC1B,IAAA,aAAA,CAAc,SAAS,CAAA;AACvB,IAAA,WAAA,EAAY;AACZ,IAAA,UAAA,CAAW,OAAO,GAAG,CAAA;AAAA,EACvB,CAAA;AACA,EAAA,GAAA,CAAI,EAAA,CAAG,SAAS,OAAO,CAAA;AACvB,EAAA,GAAA,CAAI,EAAA,CAAG,SAAS,OAAO,CAAA;AACzB;AAIA,SAAS,QAAA,CAAS,GAAA,EAA0B,MAAA,EAAgB,IAAA,EAAqB;AAC/E,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AACnC,EAAA,GAAA,CAAI,UAAU,MAAA,EAAQ,EAAE,gBAAgB,iCAAA,EAAmC,eAAA,EAAiB,YAAY,CAAA;AACxG,EAAA,GAAA,CAAI,IAAI,OAAO,CAAA;AACjB;AAEA,SAAS,QAAA,CAAS,KAA0B,IAAA,EAAoB;AAC9D,EAAA,GAAA,CAAI,UAAU,GAAA,EAAK,EAAE,gBAAgB,0BAAA,EAA4B,eAAA,EAAiB,YAAY,CAAA;AAC9F,EAAA,GAAA,CAAI,IAAI,IAAI,CAAA;AACd;AAEA,SAAS,SAAA,CAAU,MAAc,MAAA,EAAwB;AACvD,EAAA,OAAO,kBAAA,CAAmB,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACrD;AAOA,SAAS,QAAA,CAAS,QAAA,EAAkB,QAAA,EAAkB,KAAA,EAAyB;AAC7E,EAAA,IAAI;AACF,IAAA,OAAO,eAAA,CAAgB,QAAA,EAAU,EAAE,QAAA,EAAU,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAAA,EAClF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAEA,SAAS,WAAW,GAAA,EAA4B;AAC9C,EAAA,MAAM,IAAI,GAAA,GAAM,MAAA,CAAO,QAAA,CAAS,GAAA,EAAK,EAAE,CAAA,GAAI,CAAA;AAC3C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,GAAI,GAAG,OAAO,CAAA;AACzC,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,CAAA;AAChC;AAMA,SAAS,aAAa,GAAA,EAAoC;AACxD,EAAA,MAAM,MAAA,GAAS,IAAI,OAAA,CAAQ,MAAA;AAC3B,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,MAAM,CAAA,CAAE,IAAA,KAAS,IAAI,OAAA,CAAQ,IAAA;AAAA,EAC9C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AA9RA,IAiCM,YAAA,EACA,cACA,YAAA,EACA,WAAA;AApCN,IAAA,cAAA,GAAA,KAAA,CAAA;AAAA,EAAA,sBAAA,GAAA;AAcA,IAAA,kBAAA,EAAA;AACA,IAAA,qBAAA,EAAA;AAkBA,IAAM,YAAA,GAAe,IAAA;AACrB,IAAM,YAAA,GAAe,WAAA;AACrB,IAAM,YAAA,GAAe,IAAA;AACrB,IAAM,WAAA,GAAc,EAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;AC/Bb,IAAM,cAAA,GAAN,cAA6B,KAAA,CAAM;AAAA,EACxC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AAEZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAGO,IAAM,iBAAA,GAAN,cAAgC,cAAA,CAAe;AAAA;AAAA,EAE3C,MAAA;AAAA;AAAA,EAEA,IAAA;AAAA;AAAA,EAEA,QAAA;AAAA;AAAA,EAEA,IAAA;AAAA;AAAA,EAEA,iBAAA;AAAA,EAET,YAAY,IAAA,EAOT;AACD,IAAA,KAAA,CAAM,CAAA,CAAA,EAAI,KAAK,MAAM,CAAA,EAAA,EAAK,KAAK,QAAQ,CAAA,EAAA,EAAK,IAAA,CAAK,OAAO,CAAA,CAAE,CAAA;AAC1D,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AACrB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,oBAAoB,IAAA,CAAK,iBAAA;AAC9B,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAEA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,KAAK,MAAA,KAAW,GAAA;AAAA,EACzB;AAAA,EAEA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA,KAAW,GAAA,IAAO,IAAA,CAAK,MAAA,KAAW,GAAA;AAAA,EAChD;AAAA,EAEA,IAAI,UAAA,GAAsB;AACxB,IAAA,OAAO,KAAK,MAAA,KAAW,GAAA;AAAA,EACzB;AACF,CAAA;AAGO,IAAM,qBAAA,GAAN,cAAoC,cAAA,CAAe;AAAA,EAC/C,QAAA;AAAA,EACS,KAAA;AAAA,EAClB,WAAA,CAAY,UAAkB,KAAA,EAAgB;AAC5C,IAAA,KAAA,CAAM,yBAAyB,QAAQ,CAAA,EAAA,EAAK,QAAA,CAAS,KAAK,CAAC,CAAA,CAAE,CAAA;AAC7D,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AACZ,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAGO,IAAM,oBAAA,GAAN,cAAmC,cAAA,CAAe;AAAA,EACvD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF,CAAA;AAEA,SAAS,SAAS,KAAA,EAAwB;AACxC,EAAA,IAAI,KAAA,YAAiB,KAAA,EAAO,OAAO,KAAA,CAAM,OAAA;AACzC,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;;;AC/BA,IAAM,gBAAA,uBAAuB,GAAA,CAAI,CAAC,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAEnD,IAAM,YAAN,MAAgB;AAAA,EACJ,OAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,IAAA,EAAwB;AAClC,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,IAAI,qBAAqB,oBAAoB,CAAA;AACrE,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,MAAM,IAAI,qBAAqB,qBAAqB,CAAA;AACvE,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,KAAA,IAAU,UAAA,CAAW,KAAA;AAChD,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,MAAM,IAAI,oBAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC9C,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,GAAA;AACnC,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,UAAA,IAAc,CAAA;AACrC,IAAA,IAAA,CAAK,SAAA,GAAY,aAAA;AACjB,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,cAAA,IAAkB,EAAC;AAC9C,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AAAA,EACxB;AAAA,EAEA,MAAM,QAAW,IAAA,EAAkC;AACjD,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,KAAK,KAAK,CAAA;AAC/C,IAAA,MAAM,WAAW,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,CAAA;AAC5C,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,MACpC,MAAA,EAAQ,kBAAA;AAAA,MACR,GAAG,IAAA,CAAK;AAAA,KACV;AACA,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAW;AAC3B,MAAA,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAC1B,MAAA,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,IACpC;AACA,IAAA,IAAI,IAAA,CAAK,cAAA,EAAgB,OAAA,CAAQ,iBAAiB,IAAI,IAAA,CAAK,cAAA;AAE3D,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,IAAA,CAAK,YAAY,OAAA,EAAA,EAAW;AAC3D,MAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,MAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,KAAW,IAAA,CAAK,WAAA,CAAY,KAAK,MAAM,CAAA;AACvD,MAAA,IAAI;AACF,QAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK;AAAA,UACpC,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,OAAA;AAAA,UACA,GAAI,OAAA,KAAY,KAAA,CAAA,GAAY,EAAE,IAAA,EAAM,OAAA,KAAY,EAAC;AAAA,UACjD;AAAA,SACD,CAAA;AACD,QAAA,MAAA,EAAO;AACP,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAChC,QAAA,IAAA,CAAK,SAAA,GAAY,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,OAAA,EAAS,YAAY,CAAA;AAElG,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,QAAA,MAAM,MAAA,GAAS,IAAA,GAAO,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA;AAEvC,QAAA,IAAI,GAAA,CAAI,EAAA,EAAI,OAAO,cAAA,CAAe,MAAM,CAAA;AAExC,QAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,GAAA,EAAK,MAAM,CAAA;AAC9C,QAAA,IAAI,iBAAiB,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA,IAAK,OAAA,GAAU,KAAK,UAAA,EAAY;AACjE,UAAA,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,UAAU,CAAC,CAAA;AAC7C,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAI,iBAAA,CAAkB;AAAA,UAC1B,QAAQ,GAAA,CAAI,MAAA;AAAA,UACZ,QAAA;AAAA,UACA,OAAA,EAAS,cAAA,CAAe,MAAM,CAAA,IAAK,CAAA,cAAA,CAAA;AAAA,UACnC,IAAA,EAAM,YAAY,MAAM,CAAA;AAAA,UACxB,IAAA,EAAM,MAAA;AAAA,UACN,GAAI,UAAA,KAAe,KAAA,CAAA,GAAY,EAAE,iBAAA,EAAmB,UAAA,KAAe;AAAC,SACrE,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,MAAA,EAAO;AACP,QAAA,IAAI,GAAA,YAAe,mBAAmB,MAAM,GAAA;AAE5C,QAAA,SAAA,GAAY,GAAA;AACZ,QAAA,IAAI,OAAA,GAAU,KAAK,UAAA,EAAY;AAC7B,UAAA,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAC,CAAA;AACjC,UAAA;AAAA,QACF;AACA,QAAA,MAAM,IAAI,qBAAA,CAAsB,QAAA,EAAU,GAAG,CAAA;AAAA,MAC/C;AAAA,IACF;AAEA,IAAA,MAAM,IAAI,qBAAA,CAAsB,QAAA,EAAU,SAAS,CAAA;AAAA,EACrD;AAAA,EAEQ,QAAA,CAAS,MAAc,KAAA,EAAyC;AACtE,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,EAAG,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA,CAAA;AACvE,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAChC,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAS,CAAA,CACjC,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,EAAG,kBAAA,CAAmB,CAAC,CAAC,CAAA,CAAA,EAAI,kBAAA,CAAmB,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA,CAAE,CAAA;AAC9E,IAAA,OAAO,MAAA,CAAO,SAAS,CAAA,EAAG,IAAI,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAAK,IAAA;AAAA,EACzD;AAAA,EAEQ,YAAY,QAAA,EAAqE;AACvF,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,WAAW,KAAA,EAAM,EAAG,KAAK,SAAS,CAAA;AACjE,IAAA,MAAM,eAAA,GAAkB,MAAM,UAAA,CAAW,KAAA,EAAM;AAC/C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAI,QAAA,CAAS,OAAA,EAAS,UAAA,CAAW,KAAA,EAAM;AAAA,oBACzB,gBAAA,CAAiB,OAAA,EAAS,iBAAiB,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,IACzE;AACA,IAAA,OAAO;AAAA,MACL,QAAQ,UAAA,CAAW,MAAA;AAAA,MACnB,QAAQ,MAAM;AACZ,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,QAAA,EAAU,mBAAA,CAAoB,SAAS,eAAe,CAAA;AAAA,MACxD;AAAA,KACF;AAAA,EACF;AAAA,EAEQ,OAAA,CAAQ,SAAiB,iBAAA,EAAoC;AACnE,IAAA,IAAI,sBAAsB,MAAA,EAAW,OAAO,KAAK,GAAA,CAAI,iBAAA,GAAoB,KAAM,GAAM,CAAA;AAErF,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,GAAM,CAAA,IAAK,SAAS,GAAK,CAAA;AAC/C,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,IAAI,CAAA;AAAA,EACxC;AACF,CAAA;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAACD,aAAY,UAAA,CAAWA,QAAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,SAAS,SAAS,IAAA,EAAuB;AACvC,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AASA,SAAS,eAAe,IAAA,EAAwB;AAC9C,EAAA,IACE,IAAA,KAAS,IAAA,IACT,OAAO,IAAA,KAAS,QAAA,IAChB,SAAA,IAAa,IAAA,IACb,OAAQ,IAAA,CAA8B,OAAA,KAAY,SAAA,IAClD,MAAA,IAAU,IAAA,EACV;AACA,IAAA,OAAQ,IAAA,CAA2B,IAAA;AAAA,EACrC;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,eAAe,IAAA,EAAmC;AACzD,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,aAAa,IAAA,EAAM;AACzD,IAAA,MAAM,IAAK,IAAA,CAA+B,OAAA;AAC1C,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,YAAY,IAAA,EAAmC;AACtD,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,UAAU,IAAA,EAAM;AACtD,IAAA,MAAME,KAAK,IAAA,CAA4B,IAAA;AACvC,IAAA,IAAI,OAAOA,EAAAA,KAAM,QAAA,EAAU,OAAOA,EAAAA;AAAA,EACpC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,eAAA,CACP,KACA,IAAA,EACoB;AACpB,EAAA,MAAMC,OAAAA,GAAS,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAC5C,EAAA,IAAIA,OAAAA,EAAQ;AACV,IAAA,MAAM,CAAA,GAAI,OAAOA,OAAM,CAAA;AACvB,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,EAAG,OAAO,CAAA;AAAA,EACjC;AACA,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,UAAU,IAAA,EAAM;AACtD,IAAA,MAAM,OAAQ,IAAA,CAAoD,IAAA;AAClE,IAAA,IAAI,QAAQ,OAAO,IAAA,CAAK,iBAAA,KAAsB,QAAA,SAAiB,IAAA,CAAK,iBAAA;AAAA,EACtE;AACA,EAAA,OAAO,MAAA;AACT;;;AClNO,IAAM,0BAAA,GAA6B,2BAAA;AAiBnC,IAAM,kBAAN,MAAsB;AAAA,EACV,SAAA;AAAA;AAAA,EAER,OAAA;AAAA;AAAA,EAGA,IAAA;AAAA;AAAA,EAEA,KAAA;AAAA;AAAA,EAEA,IAAA;AAAA;AAAA,EAEA,OAAA;AAAA,EAET,YAAY,OAAA,EAAiC;AAC3C,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,CAAQ,MAAA,EAAQ;AAC/B,MAAA,MAAM,IAAI,qBAAqB,yDAAoD,CAAA;AAAA,IACrF;AACA,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,OAAA,IAAW,0BAAA,EAA4B,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACjF,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,SAAA,CAAU;AAAA,MAC7B,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,GAAI,QAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,OAAA,CAAQ,SAAA,EAAU,GAAI,EAAC;AAAA,MAC1E,GAAI,QAAQ,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,EAAY,OAAA,CAAQ,UAAA,EAAW,GAAI,EAAC;AAAA,MAC7E,GAAI,QAAQ,KAAA,GAAQ,EAAE,OAAO,OAAA,CAAQ,KAAA,KAAU,EAAC;AAAA,MAChD,GAAI,QAAQ,SAAA,GAAY,EAAE,WAAW,OAAA,CAAQ,SAAA,KAAc,EAAC;AAAA,MAC5D,cAAA,EAAgB,EAAE,YAAA,EAAc,eAAA;AAAgB,KACjD,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA;AAC3C,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,aAAA,CAAc,IAAA,CAAK,SAAS,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAA,CAAkB,MAAgC,IAAA,EAAwE;AACxH,IAAA,OAAO,IAAA,CAAK,UAAU,OAAA,CAAQ;AAAA,MAC5B,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,cAAA;AAAA,MACN,IAAA;AAAA,MACA,GAAI,MAAM,cAAA,GAAiB,EAAE,gBAAgB,IAAA,CAAK,cAAA,KAAmB;AAAC,KACvE,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAA,CAAW,MAAA,EAAgB,IAAA,EAAc,IAAA,EAA+H;AACtK,IAAA,OAAO,IAAA,CAAK,UAAU,OAAA,CAAW;AAAA,MAC/B,MAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAI,MAAM,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU,EAAC;AAAA,MAC3C,GAAI,MAAM,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK,GAAI,EAAC;AAAA,MACtD,GAAI,MAAM,cAAA,GAAiB,EAAE,gBAAgB,IAAA,CAAK,cAAA,KAAmB;AAAC,KACvE,CAAA;AAAA,EACH;AACF,CAAA;AAEA,IAAM,eAAN,MAAmB;AAAA,EACjB,YAA6B,CAAA,EAAc;AAAd,IAAA,IAAA,CAAA,CAAA,GAAA,CAAA;AAAA,EAAe;AAAA,EAAf,CAAA;AAAA,EAE7B,IAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,EAAE,OAAA,CAAQ,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,YAAY,CAAA;AAAA,EAC3D;AAAA,EACA,IAAI,KAAA,EAAmC;AACrC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,CAAA,EAAI,CAAA;AAAA,EACzE;AAAA,EACA,MAAA,CAAO,MAAqB,IAAA,EAAwD;AAClF,IAAA,OAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,MAAM,UAAA,EAAY,IAAA,EAAM,GAAI,IAAA,EAAM,cAAA,GAAiB,EAAE,cAAA,EAAgB,IAAA,CAAK,gBAAe,GAAI,IAAK,CAAA;AAAA,EAC5I;AAAA,EACA,MAAA,CAAO,OAAe,IAAA,EAAyC;AAC7D,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA;AAAA,EACjF;AAAA,EACA,OAAO,KAAA,EAA8B;AACnC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,CAAA,EAAI,CAAA;AAAA,EAC5E;AAAA,EACA,MAAM,KAAA,EAAmC;AACvC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,MAAA,CAAA,EAAU,CAAA;AAAA,EAChF;AAAA,EACA,KAAK,KAAA,EAAmC;AACtC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,KAAA,CAAA,EAAS,CAAA;AAAA,EAC/E;AAAA,EACA,UAAU,KAAA,EAAsC;AAC9C,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,MAAA,CAAA,EAAU,CAAA;AAAA,EAC/E;AAAA,EACA,UAAA,CAAW,KAAA,EAAe,IAAA,EAAsB,IAAA,EAAyD;AACvG,IAAA,OAAO,IAAA,CAAK,EAAE,OAAA,CAAQ,EAAE,QAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,UAAU,IAAA,EAAM,GAAI,IAAA,EAAM,cAAA,GAAiB,EAAE,cAAA,EAAgB,KAAK,cAAA,EAAe,GAAI,EAAC,EAAI,CAAA;AAAA,EAChK;AACF,CAAA;AAEA,IAAM,gBAAN,MAAoB;AAAA,EAClB,YAA6B,CAAA,EAAc;AAAd,IAAA,IAAA,CAAA,CAAA,GAAA,CAAA;AAAA,EAAe;AAAA,EAAf,CAAA;AAAA;AAAA,EAG7B,KAAK,KAAA,EAA+C;AAClD,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,WAAA,EAAa,GAAI,QAAQ,EAAE,KAAA,EAAsE,GAAI,IAAK,CAAA;AAAA,EACzJ;AAAA,EACA,IAAI,MAAA,EAAqC;AACvC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,CAAA;AAAA,EAC3E;AAAA,EACA,MAAA,CAAO,QAAgB,IAAA,EAA2C;AAChE,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA;AAAA,EACnF;AAAA,EACA,OAAO,MAAA,EAA+B;AACpC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,IAAA,EAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,CAAA,EAAI,CAAA;AAAA,EAC9E;AAAA,EACA,MAAM,MAAA,EAAqC;AACzC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,MAAA,CAAA,EAAU,CAAA;AAAA,EAClF;AAAA,EACA,KAAK,MAAA,EAAqC;AACxC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,KAAA,CAAA,EAAS,CAAA;AAAA,EACjF;AAAA;AAAA,EAEA,OAAO,MAAA,EAAuC;AAC5C,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,IAAA,CAAA,EAAQ,CAAA;AAAA,EAChF;AAAA,EACA,QAAA,CAAS,QAAgB,KAAA,EAAsC;AAC7D,IAAA,OAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAM,CAAA,UAAA,EAAa,GAAA,CAAI,MAAM,CAAC,CAAA,KAAA,CAAA,EAAS,GAAI,KAAA,GAAQ,EAAE,OAAsE,GAAI,IAAK,CAAA;AAAA,EAC7K;AACF,CAAA;AAEA,IAAM,eAAN,MAAmB;AAAA,EACjB,YAA6B,CAAA,EAAc;AAAd,IAAA,IAAA,CAAA,CAAA,GAAA,CAAA;AAAA,EAAe;AAAA,EAAf,CAAA;AAAA;AAAA,EAG7B,KAAK,KAAA,EAA6C;AAChD,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,UAAA,EAAY,GAAI,QAAQ,EAAE,KAAA,EAAsE,GAAI,IAAK,CAAA;AAAA,EACxJ;AAAA,EACA,IAAI,KAAA,EAAmC;AACrC,IAAA,OAAO,IAAA,CAAK,CAAA,CAAE,OAAA,CAAQ,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,CAAA,SAAA,EAAY,GAAA,CAAI,KAAK,CAAC,CAAA,CAAA,EAAI,CAAA;AAAA,EACzE;AACF,CAAA;AAEA,IAAM,kBAAN,MAAsB;AAAA,EACpB,YAA6B,CAAA,EAAc;AAAd,IAAA,IAAA,CAAA,CAAA,GAAA,CAAA;AAAA,EAAe;AAAA,EAAf,CAAA;AAAA,EAE7B,EAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,EAAE,OAAA,CAAQ,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,UAAU,CAAA;AAAA,EACzD;AAAA,EACA,KAAA,GAAgC;AAC9B,IAAA,OAAO,IAAA,CAAK,EAAE,OAAA,CAAQ,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,aAAa,CAAA;AAAA,EAC5D;AACF,CAAA;AAEA,SAAS,IAAI,OAAA,EAAyB;AACpC,EAAA,OAAO,mBAAmB,OAAO,CAAA;AACnC;;;AC1LA,IAAM,GAAA,GAAM,MAAA,CAAO,YAAA,CAAa,EAAE,CAAA;AAClC,IAAM,IAAA,GAAO;AAAA,EACX,KAAA,EAAO,GAAG,GAAG,CAAA,GAAA,CAAA;AAAA,EACb,GAAA,EAAK,GAAG,GAAG,CAAA,GAAA,CAAA;AAAA,EACX,IAAA,EAAM,GAAG,GAAG,CAAA,GAAA,CAAA;AAAA,EACZ,KAAA,EAAO,GAAG,GAAG,CAAA,IAAA,CAAA;AAAA,EACb,MAAA,EAAQ,GAAG,GAAG,CAAA,IAAA,CAAA;AAAA,EACd,GAAA,EAAK,GAAG,GAAG,CAAA,IAAA,CAAA;AAAA,EACX,IAAA,EAAM,GAAG,GAAG,CAAA,IAAA,CAAA;AAAA,EACZ,IAAA,EAAM,GAAG,GAAG,CAAA,IAAA;AACd,CAAA;AAIA,IAAM,KAAA,GAA+E;AAAA,EACnF,OAAA,EAAS,EAAE,IAAA,EAAM,GAAA,EAAK,OAAO,OAAA,EAAQ;AAAA,EACrC,OAAA,EAAS,EAAE,IAAA,EAAM,GAAA,EAAK,OAAO,QAAA,EAAS;AAAA,EACtC,SAAA,EAAW,EAAE,IAAA,EAAM,GAAA,EAAK,OAAO,MAAA,EAAO;AAAA,EACtC,OAAA,EAAS,EAAE,IAAA,EAAM,GAAA,EAAK,OAAO,KAAA,EAAM;AAAA,EACnC,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAK,OAAO,MAAA;AAC/B,CAAA;AAGO,SAAS,gBAAA,CAAiB,MAAA,EAAyB,OAAA,GAAyB,EAAC,EAAW;AAC7F,EAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAWD,EAAAA,KAAc,QAAQ,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAKA,EAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,GAAK,CAAA;AACxF,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,MAAA,GAAS,YAAA,GAAe,QAAA;AAC7C,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,CAAA,EAAG,MAAM,WAAA,EAAa,MAAM,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,CAAA,CAAA,EAAK,MAAM,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,MAAA,CAAO,KAAK,CAAA,CAAA,CAAA,EAAK,MAAM,CAAC,CAAA;AAAA,GACrH;AAGA,EAAA,MAAM,QAAyC,CAAC,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,WAAW,WAAW,CAAA;AACvG,EAAA,MAAME,UAAS,CAAC,GAAG,OAAO,OAAO,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,MAAM,KAAA,CAAM,OAAA,CAAQ,EAAE,MAAM,CAAA,GAAI,MAAM,OAAA,CAAQ,CAAA,CAAE,MAAM,CAAC,CAAA;AACnG,EAAA,KAAA,MAAWF,MAAKE,OAAAA,EAAQ;AACtB,IAAA,MAAM,CAAA,GAAI,KAAA,CAAMF,EAAAA,CAAE,MAAM,CAAA;AACxB,IAAA,MAAM,MAAA,GACJA,EAAAA,CAAE,aAAA,IAAiBA,EAAAA,CAAE,aAAA,CAAc,SAC/B,KAAA,CAAM,CAAA,EAAA,EAAKA,EAAAA,CAAE,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,EAAK,MAAM,CAAA,GAChDA,EAAAA,CAAE,MAAA,GACA,KAAA,CAAM,KAAKA,EAAAA,CAAE,MAAM,CAAA,CAAA,CAAA,EAAK,MAAM,CAAA,GAC9B,EAAA;AACR,IAAA,KAAA,CAAM,IAAA,CAAK,KAAK,KAAA,CAAM,CAAA,CAAE,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA,EAAI,KAAA,CAAMA,EAAAA,CAAE,OAAO,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,IAAIA,EAAAA,CAAE,GAAG,CAAA,EAAG,MAAM,CAAA,CAAE,CAAA;AAAA,EAClG;AAEA,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,MAAA,CAAO,OAAA,IAAW,CAAA,EAAG,MAAA,CAAO,OAAO,CAAA,QAAA,CAAA;AAAA,IACnC,MAAA,CAAO,OAAA,IAAW,CAAA,EAAG,MAAA,CAAO,OAAO,CAAA,QAAA,CAAA;AAAA,IACnC,MAAA,CAAO,SAAA,IAAa,CAAA,EAAG,MAAA,CAAO,SAAS,CAAA,UAAA,CAAA;AAAA,IACvC,MAAA,CAAO,OAAA,IAAW,CAAA,EAAG,MAAA,CAAO,OAAO,CAAA,QAAA,CAAA;AAAA,IACnC,MAAA,CAAO,OAAA,IAAW,CAAA,EAAG,MAAA,CAAO,OAAO,CAAA,QAAA;AAAA,GACrC,CAAE,OAAO,OAAO,CAAA;AAChB,EAAA,MAAM,UAAU,KAAA,CAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,YAAA;AAClD,EAAA,MAAM,gBAAgB,MAAA,CAAO,UAAA,GAAa,KAAA,CAAM,2BAAA,EAA0B,MAAM,CAAA,GAAI,EAAA;AACpF,EAAA,KAAA,CAAM,IAAA,CAAK,KAAK,KAAA,CAAM,OAAA,EAAS,MAAM,CAAC,CAAA,EAAG,aAAa,CAAA,CAAE,CAAA;AAExD,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;;;ACsDO,SAAS,sBAAA,CAAuB,QAAQ,EAAA,EAAY;AACzD,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,KAAK,CAAA;AAChC,EAAA,MAAA,CAAO,gBAAgB,GAAG,CAAA;AAC1B,EAAA,OAAO,MAAM,IAAA,CAAK,GAAG,CAAA,CAClB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAC1C,KAAK,EAAE,CAAA;AACZ;;;ACrGA,kBAAA,EAAA;;;ACzBA,IAAM,CAAA,GAAI,MAAA,CAAO,YAAA,CAAa,EAAE,CAAA;AAChC,IAAM,GAAA,GAAM,OAAO,OAAA,KAAY,WAAA,IAAe,QAAQ,GAAA,GAAM,OAAA,CAAQ,MAAM,EAAC;AAC3E,IAAI,QACF,CAAC,GAAA,CAAI,UAAU,CAAA,KACd,CAAC,CAAC,GAAA,CAAI,aAAa,CAAA,IAAK,CAAC,EAAE,OAAO,OAAA,KAAY,eAAe,OAAA,CAAQ,MAAA,IAAU,QAAQ,MAAA,CAAO,KAAA,CAAA,CAAA;AAE1F,SAAS,SAAS,EAAA,EAAmB;AAC1C,EAAA,KAAA,GAAQ,EAAA;AACV;AAEA,SAAS,IAAA,CAAK,IAAA,EAAc,KAAA,EAAe,CAAA,EAAmB;AAC5D,EAAA,OAAO,KAAA,GAAQ,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,CAAC,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,CAAA,GAAM,CAAA;AACrD;AAEO,IAAM,CAAA,GAAI;AAAA,EACf,MAAM,CAAC,CAAA,KAAc,IAAA,CAAK,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,EAClC,KAAK,CAAC,CAAA,KAAc,IAAA,CAAK,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,EACjC,KAAK,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EAClC,OAAO,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EACpC,QAAQ,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EACrC,MAAM,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EACnC,SAAS,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EACtC,MAAM,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAA;AAAA,EACnC,MAAM,CAAC,CAAA,KAAc,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC;AACrC,CAAA;AAGO,SAAS,MAAM,CAAA,EAAmB;AACvC,EAAA,OAAO,QAAQ,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA,EAAG,CAAC,CAAA,IAAA,CAAA,GAAS,CAAA;AAC/C;AAEO,IAAM,GAAA,GAAM;AAAA,EACjB,EAAA,EAAI,CAAA,CAAE,KAAA,CAAM,QAAG,CAAA;AAAA,EACf,IAAA,EAAM,CAAA,CAAE,GAAA,CAAI,QAAG,CAAA;AAAA,EACf,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,QAAG,CAAA;AAAA,EAClB,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,QAAG,CAAA;AAAA,EAChB,GAAA,EAAK,CAAA,CAAE,IAAA,CAAK,MAAG,CAAA;AAAA,EACf,KAAA,EAAO,CAAA,CAAE,IAAA,CAAK,QAAG;AACnB,CAAA;AAGO,SAAS,cAAc,CAAA,EAAmB;AAE/C,EAAA,OAAO,CAAA,CAAE,OAAA,CAAQ,iBAAA,EAAmB,EAAE,CAAA,CAAE,MAAA;AAC1C;AAEA,SAAS,aAAA,CAAc,GAAW,KAAA,EAAuB;AACvD,EAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,aAAA,CAAc,CAAC,CAAA;AACnC,EAAA,OAAO,MAAM,CAAA,GAAI,CAAA,GAAI,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,GAAI,CAAA;AACzC;AASO,SAAS,KAAA,CAAM,SAAwB,IAAA,EAA0B;AACtE,EAAA,MAAM,SAAS,OAAA,CAAQ,GAAA;AAAA,IAAI,CAAC,KAAK,CAAA,KAC/B,IAAA,CAAK,IAAI,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA,EAAG,GAAG,KAAK,GAAA,CAAI,CAAC,MAAM,aAAA,CAAc,CAAA,CAAE,CAAC,CAAA,IAAK,EAAE,CAAC,CAAC;AAAA,GACnF;AACA,EAAA,MAAM,SAAS,CAAC,KAAA,KACd,MACG,GAAA,CAAI,CAAC,MAAM,CAAA,KAAM;AAChB,IAAA,MAAM,CAAA,GAAI,OAAO,CAAC,CAAA;AAClB,IAAA,IAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,KAAA,KAAU,OAAA,EAAS;AACjC,MAAA,MAAM,GAAA,GAAM,CAAA,GAAI,aAAA,CAAc,IAAI,CAAA;AAClC,MAAA,OAAA,CAAQ,MAAM,CAAA,GAAI,GAAA,CAAI,MAAA,CAAO,GAAG,IAAI,EAAA,IAAM,IAAA;AAAA,IAC5C;AACA,IAAA,OAAO,aAAA,CAAc,MAAM,CAAC,CAAA;AAAA,EAC9B,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACd,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ,CAAA,CAAE,GAAA,CAAI,GAAA,CAAI,MAAM,CAAC,CAAC,CAAA;AAC3D,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAC5B,EAAA,OAAO,CAAC,IAAA,EAAM,GAAG,IAAI,CAAA,CAAE,KAAK,IAAI,CAAA;AAClC;AAGO,SAAS,GAAA,CAAI,OAAe,KAAA,EAAyB;AAC1D,EAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,EAAO,EAAA,EAAI,GAAG,KAAK,CAAA;AAClC,EAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,GAAA,CAAI,aAAa,CAAC,CAAA;AAClD,EAAA,MAAM,GAAA,GAAM,EAAE,IAAA,CAAK,eAAK,IAAI,KAAA,CAAM,KAAK,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,GAAA,GAAM,SAAI,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,aAAA,CAAc,KAAK,CAAA,GAAI,CAAC,CAAC,CAAA,GAAI,QAAG,CAAA;AACvH,EAAA,MAAM,MAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAA,CAAK,SAAI,CAAA,GAAI,aAAA,CAAc,GAAG,KAAK,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,SAAI,CAAC,CAAA;AAClF,EAAA,MAAM,GAAA,GAAM,EAAE,IAAA,CAAK,QAAA,GAAM,SAAI,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAA,GAAI,QAAG,CAAA;AACpD,EAAA,OAAO,CAAC,GAAA,EAAK,GAAG,KAAK,GAAG,CAAA,CAAE,KAAK,IAAI,CAAA;AACrC;AAGO,SAAS,YAAA,CAAa,KAAoB,KAAA,EAAuB;AACtE,EAAA,IAAI,CAAC,GAAA,EAAK,OAAO,CAAA,CAAE,KAAK,QAAG,CAAA;AAC3B,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,EAAA,IAAI,OAAO,KAAA,CAAM,IAAI,GAAG,OAAO,CAAA,CAAE,KAAK,QAAG,CAAA;AACzC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAA,CAAO,IAAA,GAAO,SAAS,GAAI,CAAA;AACjD,EAAA,MAAM,SAAS,QAAA,GAAW,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAA;AAC7B,EAAA,MAAM,IAAA,GACJ,GAAA,GAAM,EAAA,GAAK,CAAA,EAAG,GAAG,CAAA,CAAA,CAAA,GAAM,GAAA,GAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,EAAE,CAAC,CAAA,CAAA,CAAA,GAAM,GAAA,GAAM,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,KAAK,CAAC,CAAA,CAAA,CAAA;AAC1I,EAAA,OAAO,CAAA,CAAE,KAAK,MAAA,GAAS,CAAA,GAAA,EAAM,IAAI,CAAA,CAAA,GAAK,CAAA,EAAG,IAAI,CAAA,IAAA,CAAM,CAAA;AACrD;AAEO,IAAM,IAAA,GAAO,MAAM,QAAG,CAAA;;;ADxE7B,IAAM,QAAA,GAAW,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC9C,IAAM,WAAmB,MAAM;AAC7B,EAAA,IAAI;AACF,IAAA,OAAQ,QAAA,CAAS,iBAAiB,CAAA,CAA0B,OAAA;AAAA,EAC9D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAA;AAAA,EACT;AACF,CAAA,GAAG;AASH,IAAM,WAAA,GAAc,CAAC,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAW,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,GAAA,EAAK,MAAA,EAAQ,MAAM,CAAA;AAE9G,IAAM,iBAAA,GAAoB,CAAC,GAAA,EAAK,GAAG,CAAA;AAEnC,SAAS,UAAU,IAAA,EAAsB;AACvC,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,QAA0C,EAAC;AACjD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,IAAA,IAAI,CAAA,CAAE,UAAA,CAAW,IAAI,CAAA,EAAG;AACtB,MAAA,MAAM,GAAA,GAAM,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AACrB,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,CAAA,GAAI,CAAC,CAAA;AACvB,MAAA,IAAI,IAAA,KAAS,MAAA,IAAa,CAAC,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,EAAG;AAC5E,QAAA,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA;AACb,QAAA,CAAA,EAAA;AAAA,MACF,CAAA,MAAO;AACL,QAAA,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA;AAAA,MACf;AAAA,IACF,WAAW,CAAA,CAAE,UAAA,CAAW,GAAG,CAAA,IAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AAC5C,MAAA,MAAM,GAAA,GAAM,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AACrB,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,CAAA,GAAI,CAAC,CAAA;AACvB,MAAA,IAAI,IAAA,KAAS,MAAA,IAAa,CAAC,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,IAAK,iBAAA,CAAkB,QAAA,CAAS,GAAG,CAAA,EAAG;AAClF,QAAA,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA;AACb,QAAA,CAAA,EAAA;AAAA,MACF,CAAA,MAAO;AACL,QAAA,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA;AAAA,MACf;AAAA,IACF,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,KAAK,CAAC,CAAA;AAAA,IACpB;AAAA,EACF;AACA,EAAA,OAAO,EAAE,OAAA,EAAS,WAAA,CAAY,CAAC,CAAA,IAAK,EAAA,EAAI,WAAA,EAAa,WAAA,CAAY,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,EAAM;AACnF;AAEA,IAAM,GAAA,GAAM,CAAC,CAAA,GAAI,EAAA,KAAa,KAAK,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,GAAI,IAAI,CAAA;AAChE,IAAM,IAAA,GAAO,CAAC,CAAA,KAAqB,GAAA,CAAI,KAAK,SAAA,CAAU,CAAA,EAAG,IAAA,EAAM,CAAC,CAAC,CAAA;AAEjE,SAAS,UAAA,GAA8B;AACrC,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAC9C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,qBAAqB,sEAAiE,CAAA;AAAA,EAClG;AACA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAC/C,EAAA,OAAO,IAAI,eAAA,CAAgB,EAAE,MAAA,EAAQ,GAAI,OAAA,GAAU,EAAE,OAAA,EAAQ,GAAI,EAAC,EAAI,CAAA;AACxE;AAEA,SAAS,YAAY,MAAA,EAAwB;AAC3C,EAAA,MAAM,CAAA,GAAI,OAAO,WAAA,EAAY;AAC7B,EAAA,IAAI,MAAM,QAAA,IAAY,CAAA,KAAM,aAAa,OAAO,CAAA,CAAE,MAAM,MAAM,CAAA;AAC9D,EAAA,IAAI,CAAA,KAAM,cAAc,CAAA,KAAM,QAAA,IAAY,MAAM,SAAA,EAAW,OAAO,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;AAC/E,EAAA,IAAI,CAAA,CAAE,WAAW,OAAO,CAAA,IAAK,MAAM,QAAA,EAAU,OAAO,CAAA,CAAE,GAAA,CAAI,MAAM,CAAA;AAChE,EAAA,OAAO,CAAA,CAAE,OAAO,MAAM,CAAA;AACxB;AAEA,SAAS,OAAO,QAAA,EAAwB;AACtC,EAAA,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,WAAW,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,QAAQ,CAAC,CAAA,CAAE,CAAA;AACvD,EAAA,GAAA,EAAI;AACN;AAIA,eAAe,UAAU,OAAA,EAAiC;AACxD,EAAA,MAAM,EAAA,GAAK,MAAM,UAAA,EAAW,CAAE,QAAQ,EAAA,EAAG;AACzC,EAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,EAAE,CAAA;AAC3B,EAAA,MAAM,IAAI,EAAA,CAAG,KAAA;AACb,EAAA,MAAM,QAAQ,CAAA,CAAE,cAAA,IAAkB,OAAO,QAAA,GAAM,MAAA,CAAO,EAAE,cAAc,CAAA;AACtE,EAAA,GAAA;AAAA,IACE,GAAA,CAAI,CAAA,EAAG,EAAA,CAAG,WAAW,CAAA,CAAA,EAAI;AAAA,MACvB,GAAG,CAAA,CAAE,GAAA,CAAI,SAAS,CAAC,OAAO,EAAA,CAAG,SAAS,CAAA,EAAA,EAAK,EAAA,CAAG,WAAW,GAAA,CAAI,EAAA,GAAK,IAAI,IAAI,CAAA,CAAA,EAAI,GAAG,KAAK,CAAA,CAAA;AAAA,MACtF,CAAA,EAAG,CAAA,CAAE,GAAA,CAAI,MAAM,CAAC,CAAA,MAAA,EAAS,KAAA,CAAM,EAAA,CAAG,IAAA,EAAM,WAAA,IAAe,QAAG,CAAC,CAAA,CAAA;AAAA,MAC3D,GAAG,CAAA,CAAE,GAAA,CAAI,QAAQ,CAAC,CAAA,IAAA,EAAO,GAAG,MAAA,CAAO,OAAA,IAAW,QAAG,CAAA,WAAA,EAAW,EAAA,CAAG,OAAO,cAAA,IAAkB,QAAG,mBAAgB,EAAA,CAAG,MAAA,CAAO,sBAAsB,QAAG,CAAA,IAAA,CAAA;AAAA,MAC9I,CAAA,EAAG,EAAE,GAAA,CAAI,OAAO,CAAC,CAAA,KAAA,EAAQ,CAAA,CAAE,IAAA,CAAK,MAAA,CAAO,CAAA,CAAE,cAAc,CAAC,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,aAAA,EAAgB,CAAA,CAAE,KAAK,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAA,MAAA,CAAQ,CAAC,CAAA,CAAA;AAAA,MAClH,GAAG,CAAA,CAAE,GAAA,CAAI,WAAW,CAAC,IAAI,EAAA,CAAG,OAAA,CAAQ,YAAY,CAAA,UAAA,EAAU,GAAG,OAAA,CAAQ,uBAAuB,CAAA,iBAAA,EAAiB,EAAA,CAAG,QAAQ,wBAAwB,CAAA,YAAA;AAAA,KACjJ;AAAA,GACH;AACF;AAEA,eAAe,OAAA,CAAQ,SAA6B,OAAA,EAAiC;AACnF,EAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,MAAA,CAAO,IAAA,CAAK,IAAA,EAAK,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA;AAC3E,IAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,oBAAA,CAAqB,CAAA,wBAAA,EAA2B,OAAO,CAAA,EAAA,CAAI,CAAA;AACrF,IAAA,MAAM,QAAQ,MAAM,MAAA,CAAO,IAAA,CAAK,SAAA,CAAU,UAAU,EAAE,CAAA;AACtD,IAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,KAAK,CAAA;AAC9B,IAAA,MAAA,CAAO,CAAA,UAAA,EAAa,SAAA,CAAU,IAAI,CAAA,CAAA,CAAG,CAAA;AACrC,IAAA,GAAA,CAAI,WAAA,CAAY,KAAK,CAAC,CAAA;AACtB,IAAA;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,IAAA,CAAK,IAAA,EAAK;AACpC,EAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,MAAA,CAAO,gBAAgB,CAAA;AACvB,EAAA,GAAA;AAAA,IACE,KAAA;AAAA,MACE,CAAC,EAAE,MAAA,EAAQ,MAAA,EAAO,EAAG,EAAE,MAAA,EAAQ,QAAA,EAAS,EAAG,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAO,OAAA,EAAQ,EAAG,EAAE,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,OAAA,EAAQ,EAAG,EAAE,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,OAAA,EAAQ,EAAG,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC5K,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAiB;AAAA,QACzB,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAAA,QACb,WAAA,CAAY,EAAE,MAAM,CAAA;AAAA,QACpB,MAAA,CAAO,EAAE,SAAS,CAAA;AAAA,QAClB,MAAA,CAAO,EAAE,eAAe,CAAA;AAAA,QACxB,CAAA,CAAE,cAAA,GAAiB,CAAA,CAAE,GAAA,CAAI,MAAA,CAAO,CAAA,CAAE,cAAc,CAAC,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,QAC/D,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,EAAE;AAAA,OACZ;AAAA;AACH,GACF;AACA,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,EAAE,IAAA,CAAK,CAAA,EAAG,IAAA,CAAK,MAAM,sBAAmB,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA,CAAE,WAAW,CAAC,CAAC,UAAU,CAAC,CAAA;AAClG;AAEA,SAAS,YAAY,KAAA,EAA6B;AAChD,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,OAAO,KAAA;AAAA,IACL,CAAC,EAAE,MAAA,EAAQ,MAAA,IAAU,EAAE,MAAA,EAAQ,UAAS,EAAG,EAAE,QAAQ,UAAA,EAAW,EAAG,EAAE,MAAA,EAAQ,UAAA,IAAc,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC7G,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM;AAAA,MACf,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAAA,MACb,WAAA,CAAY,EAAE,MAAM,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,QAAQ,CAAA;AAAA,MACjB,YAAA,CAAa,CAAA,CAAE,OAAA,EAAS,GAAG,CAAA;AAAA,MAC3B,CAAA,CAAE,gBAAgB,WAAA,CAAY,CAAA,CAAE,aAAa,CAAA,GAAI,CAAA,CAAE,KAAK,QAAG;AAAA,KAC5D;AAAA,GACH;AACF;AAEA,eAAe,QAAA,CAAS,OAAsB,OAAA,EAAiC;AAC7E,EAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,EAAA,MAAM,OAAA,GAAU,OAAO,KAAA,CAAM,KAAK,MAAM,QAAA,GAAW,KAAA,CAAM,KAAK,CAAA,GAAI,MAAA;AAClE,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,MAAA,CAAO,IAAA,CAAK,IAAA,EAAK,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA;AAC3E,IAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,oBAAA,CAAqB,CAAA,wBAAA,EAA2B,OAAO,CAAA,EAAA,CAAI,CAAA;AACrF,IAAA,KAAA,GAAQ,SAAA,CAAU,EAAA;AAAA,EACpB;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,KAAA,CAAM,KAAK,EAAE,KAAA,EAAO,GAAA,EAAK,GAAI,QAAQ,EAAE,KAAA,EAAM,GAAI,IAAK,CAAA;AAChF,EAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,MAAA,CAAO,OAAA,GAAU,CAAA,WAAA,EAAW,OAAO,CAAA,CAAA,GAAK,WAAW,CAAA;AACnD,EAAA,GAAA,CAAI,WAAA,CAAY,IAAA,CAAK,KAAK,CAAC,CAAA;AAC7B;AAEA,eAAe,OAAA,CAAQ,OAAsB,OAAA,EAAiC;AAC5E,EAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,OAAO,CAAC,CAAA;AACvC,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,CAAM,QAAQ,MAAM,QAAA,GAAY,KAAA,CAAM,QAAQ,CAAA,GAA4B,MAAA;AAChG,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,IAAA,CAAK,KAAK,EAAE,KAAA,EAAO,GAAI,MAAA,GAAS,EAAE,MAAA,EAAO,GAAI,IAAK,CAAA;AAC5E,EAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,IAAI,CAAA;AAC7B,EAAA,MAAA,CAAO,cAAc,MAAA,GAAS,CAAA,MAAA,EAAM,MAAM,CAAA,CAAA,GAAK,EAAE,CAAA,CAAE,CAAA;AACnD,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,GAAA;AAAA,IACE,KAAA;AAAA,MACE,CAAC,EAAE,MAAA,EAAQ,MAAA,EAAO,EAAG,EAAE,MAAA,EAAQ,MAAA,EAAO,EAAG,EAAE,MAAA,EAAQ,KAAA,EAAM,EAAG,EAAE,MAAA,EAAQ,QAAA,EAAS,EAAG,EAAE,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAQ,EAAG,EAAE,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,MACxJ,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAiB;AAAA,QAC9B,YAAA,CAAa,CAAA,CAAE,SAAA,EAAW,GAAG,CAAA;AAAA,QAC7B,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,QAAQ,CAAA;AAAA,QACjB,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA;AAAA,QAChB,WAAA,CAAY,EAAE,MAAM,CAAA;AAAA,QACpB,CAAA,CAAE,kBAAkB,IAAA,GAAO,CAAA,CAAE,KAAK,QAAG,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,cAAc,CAAA;AAAA,QAChE,CAAA,CAAE,cAAc,IAAA,GAAO,CAAA,CAAE,KAAK,QAAG,CAAA,GAAI,CAAA,EAAG,CAAA,CAAE,UAAU,CAAA,EAAA;AAAA,OACrD;AAAA;AACH,GACF;AACA,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,CAAA,QAAA,EAAW,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,IAAA,EAAO,IAAA,CAAK,UAAA,CAAW,KAAK,CAAA,KAAA,CAAO,CAAC,CAAA;AAC5E;AAEA,eAAe,MAAA,CAAO,aAAuB,OAAA,EAAiC;AAC5E,EAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,WAAA,CAAY,UAAU,CAAA,EAAG;AAC3B,IAAA,MAAM,CAAC,OAAA,EAAS,QAAQ,CAAA,GAAI,WAAA;AAC5B,IAAA,MAAM,SAAA,GAAA,CAAa,MAAM,MAAA,CAAO,IAAA,CAAK,IAAA,EAAK,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA;AAC3E,IAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,oBAAA,CAAqB,CAAA,wBAAA,EAA2B,OAAO,CAAA,EAAA,CAAI,CAAA;AACrF,IAAA,MAAM,IAAA,GAAA,CAAQ,MAAM,MAAA,CAAO,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,EAAE,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,QAAQ,CAAA;AACxF,IAAA,IAAI,CAAC,MAAM,MAAM,IAAI,qBAAqB,CAAA,SAAA,EAAY,QAAQ,CAAA,MAAA,EAAS,OAAO,CAAA,EAAA,CAAI,CAAA;AAClF,IAAA,MAAA,GAAS,IAAA,CAAK,EAAA;AAAA,EAChB,CAAA,MAAA,IAAW,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG;AACnC,IAAA,MAAA,GAAS,YAAY,CAAC,CAAA;AAAA,EACxB,CAAA,MAAO;AACL,IAAA,MAAM,IAAI,qBAAqB,sEAAsE,CAAA;AAAA,EACvG;AACA,EAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,KAAA,CAAM,OAAO,MAAM,CAAA;AAC5C,EAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,GAAG,CAAA;AAC5B,EAAA,IAAI,GAAA,CAAI,SAAS,GAAA,CAAI,CAAA,EAAG,IAAI,EAAE,CAAA,WAAA,EAAc,CAAA,CAAE,IAAA,CAAK,MAAM,CAAC,IAAI,GAAA,CAAI,KAAA,GAAQ,EAAE,IAAA,CAAK,CAAA,OAAA,EAAK,IAAI,KAAK,CAAA,CAAE,CAAA,GAAI,EAAE,CAAA,CAAE,CAAA;AAAA,OACpG,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,GAAA,CAAI,GAAA,CAAI,KAAA,IAAS,YAAY,CAAC,CAAA,CAAE,CAAA;AAC5D;AAEA,eAAe,UAAU,OAAA,EAAiC;AACxD,EAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,EAAA,MAAM,CAAC,EAAA,EAAI,IAAA,EAAM,QAAQ,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IAC7C,MAAA,CAAO,QAAQ,EAAA,EAAG;AAAA,IAClB,MAAA,CAAO,KAAK,IAAA,EAAK;AAAA,IACjB,MAAA,CAAO,KAAK,IAAA,CAAK,EAAE,OAAO,CAAA,EAAG,MAAA,EAAQ,UAAU;AAAA,GAChD,CAAA;AACD,EAAA,IAAI,OAAA,SAAgB,IAAA,CAAK,EAAE,IAAI,IAAA,EAAM,cAAA,EAAgB,QAAA,CAAS,IAAA,EAAM,CAAA;AACpE,EAAA,MAAM,UAAA,GAAa,KAAK,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC3D,EAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,eAAA,EAAiB,CAAC,CAAA;AAClE,EAAA,MAAM,UAAA,GAAa,KAAK,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,cAAA,EAAgB,CAAC,CAAA;AAChE,EAAA,MAAM,OAAA,GAAU,UAAA,KAAe,CAAA,IAAK,EAAA,CAAG,QAAQ,YAAA,KAAiB,CAAA;AAChE,EAAA,MAAA,CAAO,QAAQ,CAAA;AACf,EAAA,GAAA,CAAI,GAAG,OAAA,GAAU,GAAA,CAAI,EAAA,GAAK,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,OAAA,GAAU,CAAA,CAAE,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,CAAE,MAAA,CAAO,iBAAiB,CAAC,CAAA,CAAE,CAAA;AAClG,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,EAAE,GAAA,CAAI,YAAY,CAAC,CAAA,EAAA,EAAK,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AAC9C,EAAA,GAAA,CAAI,KAAK,CAAA,CAAE,GAAA,CAAI,OAAO,CAAC,CAAA,OAAA,EAAU,WAAW,CAAA,CAAA,EAAI,UAAU,CAAA,OAAA,EAAU,UAAA,GAAa,EAAE,GAAA,CAAI,CAAA,MAAA,EAAM,UAAU,CAAA,QAAA,CAAU,CAAA,GAAI,EAAE,CAAA,CAAE,CAAA;AACzH,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,EAAE,GAAA,CAAI,UAAU,CAAC,CAAA,IAAA,EAAO,EAAA,CAAG,QAAQ,YAAA,GAAe,CAAA,CAAE,IAAI,MAAA,CAAO,EAAA,CAAG,QAAQ,YAAY,CAAC,IAAI,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAE,CAAA;AACjH,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,EAAE,GAAA,CAAI,YAAY,CAAC,CAAA,EAAA,EAAK,EAAA,CAAG,KAAA,CAAM,cAAc,CAAA,YAAA,CAAc,CAAA;AACtE,EAAA,IAAI,QAAA,CAAS,KAAK,MAAA,EAAQ;AACxB,IAAA,GAAA,EAAI;AACJ,IAAA,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,oBAAoB,CAAC,CAAA;AAC/B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,KAAA,MAAW,KAAK,QAAA,CAAS,IAAA,EAAM,GAAA,CAAI,CAAA,GAAA,EAAM,IAAI,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,EAAE,QAAQ,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,KAAK,CAAA,CAAE,OAAO,CAAC,CAAA,CAAA,EAAI,aAAa,CAAA,CAAE,SAAA,EAAW,GAAG,CAAC,IAAI,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,GAAA,CAAI,SAAS,CAAA,CAAE,KAAA,EAAO,EAAE,CAAC,CAAA,GAAI,EAAE,CAAA,CAAE,CAAA;AAAA,EACjL;AACF;AAEA,eAAe,OAAA,CAAQ,WAAA,EAAuB,KAAA,EAAsB,OAAA,EAAiC;AACnG,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,WAAA,CAAY,CAAC,CAAC,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,CAAC,CAAC,KAAA,CAAM,KAAK,CAAA,IAAK,CAAC,CAAC,KAAA,CAAM,SAAS,CAAA;AAClD,EAAA,MAAM,SAAS,MAAM,GAAA,CAAI,IAAA,CAAK,EAAE,QAAQ,CAAA;AACxC,EAAA,IAAI,OAAA,EAAS,OAAO,IAAA,CAAK,MAAM,CAAA;AAC/B,EAAA,GAAA,CAAI,iBAAiB,MAAA,EAAQ,EAAE,OAAO,IAAA,EAAM,MAAA,EAAQ,CAAC,CAAA;AACvD;AAOA,eAAe,YAAA,CAAa,WAAA,EAAuB,KAAA,EAAsB,OAAA,EAAiC;AACxG,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,WAAA,CAAY,CAAC,CAAC,CAAA;AACxC,EAAA,MAAM,MAAA,GAAS,CAAC,CAAC,KAAA,CAAM,SAAS,CAAA,IAAK,CAAC,CAAC,KAAA,CAAM,KAAK,CAAA;AAElD,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAMG,OAAAA,GAAS,IAAI,GAAA,CAAI,EAAE,WAAW,KAAA,EAAO,qBAAA,EAAuB,OAAO,CAAA;AACzE,IAAA,MAAM,WAAW,iBAAA,CAAkB,KAAA,CAAM,QAAQ,CAAA,EAAG,EAAA,GAAK,KAAK,GAAI,CAAA;AAClE,IAAA,MAAM,SAAA,GAAY,EAAA;AAClB,IAAA,MAAM,KAAA,GAAQ,aAAA;AAAA,MACZA,QAAO,IAAA,EAAK,CAAE,GAAA,CAAI,CAAC,OAAO,EAAE,GAAA,EAAK,CAAA,CAAE,GAAA,EAAK,UAAU,CAAA,CAAE,QAAA,EAAU,QAAA,EAAU,CAAA,CAAE,UAAS,CAAE,CAAA;AAAA,MACrF,EAAE,QAAA,EAAU,QAAA,EAAU,SAAA;AAAU,KAClC;AAEA,IAAA,MAAM,UAAA,GAAa,CAAC,GAAG,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAC,CAAC,CAAA,CAAE,MAAA;AAAA,MACvD,CAAC,GAAA,KAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,GAAA,KAAQ,GAAG,CAAA,CAAE,MAAA,IAAU;AAAA,KACxD;AACA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAO,IAAA,CAAK;AAAA,QACV,MAAA,EAAQ,EAAE,EAAA,EAAI,QAAA,EAAS;AAAA,QACvB,MAAA,EAAQ,UAAA;AAAA,QACR,KAAA,EAAO,MAAM,GAAA,CAAI,CAAC,OAAO,EAAE,GAAA,EAAK,EAAE,GAAA,EAAK,IAAA,EAAM,EAAE,IAAA,CAAK,WAAA,IAAe,QAAA,EAAU,CAAA,CAAE,UAAU,QAAA,EAAU,CAAA,CAAE,UAAS,CAAE;AAAA,OACjH,CAAA;AAAA,IACH;AACA,IAAA,MAAA,CAAO,CAAA,2BAAA,EAAwB,cAAA,CAAe,QAAQ,CAAC,CAAA,CAAE,CAAA;AACzD,IAAA,GAAA,CAAI,cAAA,CAAe,KAAK,CAAC,CAAA;AACzB,IAAA,GAAA,EAAI;AACJ,IAAA,GAAA,CAAI,CAAA,CAAE,KAAK,KAAA,CAAM,MAAA,GAAS,GAAG,KAAA,CAAM,MAAM,CAAA,mDAAA,CAAA,GAAmD,kCAAkC,CAAC,CAAA;AAC/H,IAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,MAAA,GAAA,CAAI,CAAA,CAAE,MAAA,CAAO,CAAA,wBAAA,EAAsB,SAAS,CAAA,UAAA,EAAa,WAAW,IAAA,CAAK,IAAI,CAAC,CAAA,qDAAA,CAAkD,CAAC,CAAA;AAAA,IACnI;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,GAAA,CAAI,EAAE,WAAW,KAAA,EAAO,qBAAA,EAAuB,KAAA,EAAO,OAAA,EAAS,CAAC,CAAA,KAAM,WAAA,CAAY,CAAA,EAAG,OAAO,GAAG,CAAA;AAGlH,EAAA,MAAA,CAAO,KAAA,EAAM;AAGb,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,EAAE,cAAA,EAAAC,eAAAA,EAAe,GAAI,MAAM,OAAA,CAAA,OAAA,EAAA,CAAA,IAAA,CAAA,OAAA,cAAA,EAAA,EAAA,iBAAA,CAAA,CAAA;AACjC,IAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,MAAM,CAAA,KAAM,QAAA,GAAW,MAAA,CAAO,QAAA,CAAS,KAAA,CAAM,MAAM,CAAA,EAAG,EAAE,CAAA,GAAI,MAAA;AACtF,IAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,MAAM,MAAM,QAAA,GAAW,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AACjE,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAMA,eAAAA,CAAe,QAAQ,EAAE,IAAA,EAAM,MAAM,CAAA;AACxD,MAAA,YAAA,GAAe,IAAA,CAAK,GAAA;AACpB,MAAA,MAAA,CAAO,MAAA,CAAO,MAAM,IAAA,CAAK,KAAA,EAAO,CAAA;AAAA,IAClC,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,OAAO,IAAA,EAAK;AAClB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAA,CAAO,CAAA,sBAAA,EAAsB,CAAA,CAAE,IAAA,CAAK,2BAAwB,CAAC,CAAA,CAAE,CAAA;AAC/D,IAAA,GAAA,CAAI,cAAA,CAAe,MAAA,CAAO,QAAA,EAAU,CAAC,CAAA;AACrC,IAAA,GAAA,EAAI;AACJ,IAAA,IAAI,YAAA,EAAc,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,EAAE,qBAAgB,CAAA,CAAE,IAAA,CAAK,YAAY,CAAC,CAAA,CAAE,CAAA;AACrE,IAAA,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA,SAAA,EAAY,MAAA,CAAO,MAAK,CAAE,MAAM,qCAAgC,CAAC,CAAA;AAC5E,IAAA,GAAA,EAAI;AAAA,EACN;AAGA,EAAA,MAAM,IAAI,OAAA,CAAc,CAACN,QAAAA,KAAY;AACnC,IAAA,MAAM,WAAW,MAAY;AAC3B,MAAA,OAAA,CAAQ,cAAA,CAAe,UAAU,QAAQ,CAAA;AACzC,MAAA,OAAA,CAAQ,cAAA,CAAe,WAAW,QAAQ,CAAA;AAC1C,MAAA,KAAK,MAAA,CAAO,IAAA,EAAK,CAAE,IAAA,CAAKA,QAAO,CAAA;AAAA,IACjC,CAAA;AACA,IAAA,OAAA,CAAQ,IAAA,CAAK,UAAU,QAAQ,CAAA;AAC/B,IAAA,OAAA,CAAQ,IAAA,CAAK,WAAW,QAAQ,CAAA;AAAA,EAClC,CAAC,CAAA;AAED,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,GAAA,EAAI;AACJ,IAAA,MAAM,IAAA,GAAO,OAAO,IAAA,EAAK;AACzB,IAAA,MAAM,EAAA,GAAK,KAAK,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA,CAAE,MAAA;AACtD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,OAAA,IAAW,CAAA,CAAE,MAAA,KAAW,WAAW,CAAA,CAAE,MAAA;AACjF,IAAA,GAAA,CAAI,EAAE,IAAA,CAAK,CAAA,eAAA,EAAa,KAAK,MAAM,CAAA,sBAAA,EAAyB,EAAE,CAAA,GAAA,EAAM,GAAA,GAAM,KAAK,CAAA,CAAE,GAAA,CAAI,GAAG,GAAG,CAAA,OAAA,CAAS,CAAC,CAAA,CAAA,GAAK,EAAE,GAAG,CAAC,CAAA;AAAA,EAClH;AACF;AAGA,eAAe,UAAA,CAAW,aAAuB,OAAA,EAAiC;AAEhF,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,WAAA,CAAY,MAAA,GAAS,CAAC,CAAA;AACjD,EAAA,MAAM,aAAa,WAAA,CAAY,MAAA,IAAU,CAAA,GAAI,WAAA,CAAY,CAAC,CAAA,GAAI,MAAA;AAC9D,EAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,qBAAqB,gDAAgD,CAAA;AAC5F,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,UAAU,CAAA;AACpC,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,CAAE,QAAA,CAAS,MAAM,CAAA,EAAG;AAChC,IAAA,MAAM,IAAI,oBAAA,CAAqB,CAAA,aAAA,EAAgB,MAAM,CAAA,UAAA,EAAa,GAAA,CAAI,IAAA,EAAK,CAAE,IAAA,CAAK,IAAI,CAAA,IAAK,QAAQ,CAAA,CAAE,CAAA;AAAA,EACvG;AACA,EAAA,IAAI,CAAC,OAAA,EAAS,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,KAAK,CAAA,SAAA,EAAY,CAAA,CAAE,IAAA,CAAK,MAAM,CAAC,CAAA,cAAA,CAAW,CAAA;AACnE,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,EAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA;AACvC,EAAA,IAAI,SAAS,OAAO,IAAA,CAAK,EAAE,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAChD,EAAA,GAAA,CAAI,GAAG,GAAA,CAAI,EAAE,IAAI,CAAA,CAAE,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,WAAW,IAAA,CAAK,GAAA,KAAQ,OAAO,CAAA,EAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AAChF,EAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,IAAA,EAAM;AAC3C,IAAA,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,WAAW,CAAC,CAAA;AACtB,IAAA,GAAA,CAAI,KAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,EAAE,KAAA,CAAM,IAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,GAAO,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EACjF;AACF;AAGA,SAAS,UAAA,CAAW,WAAA,EAAuB,KAAA,EAAsB,OAAA,EAAwB;AACvF,EAAA,MAAM,IAAA,GAAO,YAAY,CAAC,CAAA;AAC1B,EAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,qBAAqB,wDAAwD,CAAA;AAClG,EAAA,MAAM,EAAA,GAAK,OAAO,KAAA,CAAM,IAAI,MAAM,QAAA,GAAW,KAAA,CAAM,IAAI,CAAA,GAAI,aAAA,EAAc;AACzE,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,GAAG,CAAA,IAAK,MAAM,OAAO,CAAA,IAAK,KAAA,CAAM,OAAO,CAAC,CAAA;AAEvE,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI;AACF,IAAA,KAAA,GAAQ,gBAAgB,IAAA,EAAM,EAAE,QAAA,EAAU,EAAA,EAAI,OAAO,CAAA;AAAA,EACvD,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,IAAI,qBAAqB,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,EACjF;AAEA,EAAA,IAAI,SAAS,OAAO,IAAA,CAAK,EAAE,QAAA,EAAU,MAAM,QAAA,EAAU,EAAA,EAAI,IAAA,EAAM,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,EAAE,WAAA,EAAa,GAAG,CAAA;AAClG,EAAA,MAAA,CAAO,CAAA,QAAA,EAAW,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,CAAA,KAAA,EAAK,EAAE,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA;AACrD,EAAA,IAAI,CAAC,MAAM,MAAA,EAAQ;AACjB,IAAA,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,2DAA2D,CAAC,CAAA;AACvE,IAAA;AAAA,EACF;AACA,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,GAAA;AAAA,IACE,KAAA;AAAA,MACE,CAAC,EAAE,MAAA,EAAQ,KAAK,KAAA,EAAO,OAAA,IAAW,EAAE,MAAA,EAAQ,YAAA,EAAa,EAAG,EAAE,MAAA,EAAQ,MAAA,IAAU,EAAE,MAAA,EAAQ,OAAO,CAAA;AAAA,MACjG,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AAAA,QAClB,CAAA,CAAE,IAAA,CAAK,MAAA,CAAO,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,QACpB,CAAA,CAAE,IAAA,CAAK,YAAA,CAAa,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,QAC1B,YAAA,CAAa,CAAA,CAAE,WAAA,EAAY,EAAG,GAAG,CAAA;AAAA,QACjC,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,WAAA,EAAa;AAAA,OACvB;AAAA;AACH,GACF;AACF;AAKA,SAAS,eAAe,QAAA,EAAiC;AACvD,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,OAAO,KAAA;AAAA,IACL,CAAC,EAAE,MAAA,EAAQ,KAAA,IAAS,EAAE,MAAA,EAAQ,YAAW,EAAG,EAAE,QAAQ,IAAA,EAAK,EAAG,EAAE,MAAA,EAAQ,UAAA,IAAc,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAAA,IACxG,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AAAA,MAClB,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,GAAG,CAAA;AAAA,MACZ,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,QAAQ,CAAA;AAAA,MACjB,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,QAAQ,CAAA;AAAA,MACjB,CAAA,CAAE,QAAA,GAAW,YAAA,CAAa,CAAA,CAAE,QAAA,EAAU,EAAE,QAAQ,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,QAAG,CAAA;AAAA,MAC9D,CAAA,CAAE,QAAA,GAAW,YAAA,CAAa,CAAA,CAAE,QAAA,CAAS,WAAA,EAAY,EAAG,GAAG,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,QAAG;AAAA,KACtE;AAAA,GACH;AACF;AAGA,SAAS,eAAe,KAAA,EAA+B;AACrD,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,OAAO,KAAA;AAAA,IACL,CAAC,EAAE,MAAA,EAAQ,MAAA,EAAO,EAAG,EAAE,MAAA,EAAQ,YAAA,EAAa,EAAG,EAAE,QAAQ,KAAA,EAAM,EAAG,EAAE,MAAA,EAAQ,YAAY,CAAA;AAAA,IACxF,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM;AAAA,MACf,YAAA,CAAa,CAAA,CAAE,IAAA,CAAK,WAAA,IAAe,GAAG,CAAA;AAAA,MACtC,EAAE,IAAA,CAAK,YAAA,CAAa,EAAE,IAAA,EAAM,CAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,MACvC,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,GAAG,CAAA;AAAA,MACZ,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,QAAQ;AAAA,KAClB;AAAA,GACH;AACF;AAGA,SAAS,WAAA,CAAY,OAAoB,OAAA,EAAwB;AAC/D,EAAA,IAAI,SAAS,OAAO,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAC7C,EAAA,MAAM,KAAK,CAAA,CAAE,IAAA,CAAK,WAAW,IAAA,CAAK,GAAA,EAAK,CAAC,CAAA;AACxC,EAAA,QAAQ,MAAM,IAAA;AAAM,IAClB,KAAK,MAAA;AACH,MAAA,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,KAAK,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,IAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,CAAA,GAAI,CAAA,SAAA,EAAY,MAAM,OAAO,CAAA,CAAA,CAAA,GAAM,OAAO,CAAC,CAAA,CAAE,CAAA;AACnH,MAAA;AAAA,IACF,KAAK,SAAA;AACH,MAAA,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,EAAE,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,CAAA,EAAG,KAAA,CAAM,UAAU,CAAA,EAAA,EAAK,KAAA,CAAM,QAAA,GAAW,CAAA,GAAI,CAAA,MAAA,EAAM,KAAA,CAAM,QAAQ,CAAA,SAAA,CAAA,GAAc,EAAE,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA;AACzI,MAAA;AAAA,IACF,KAAK,OAAA;AACH,MAAA,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,IAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,GAAA,CAAI,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,iBAAA,GAAiB,cAAW,CAAC,CAAA,CAAE,CAAA;AAC5H,MAAA;AAAA,IACF,KAAK,SAAA;AACH,MAAA,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,GAAA,CAAI,WAAW,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,CAAA,MAAA,EAAS,KAAA,CAAM,UAAU,CAAA,EAAA,EAAK,KAAA,CAAM,SAAA,GAAY,kBAAA,GAAkB,eAAY,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA;AAC9J,MAAA;AAAA,IACF,KAAK,OAAA;AACH,MAAA,GAAA,CAAI,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,IAAI,CAAA,CAAE,IAAA,CAAK,eAAe,KAAA,CAAM,OAAO,eAAe,KAAA,CAAM,OAAO,CAAA,CAAA,CAAG,CAAC,CAAA,CAAE,CAAA;AACnH,MAAA;AAAA,IACF,KAAK,SAAA;AACH,MAAA,GAAA,CAAI,GAAG,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,IAAI,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,6CAAwC,CAAC,CAAA,CAAE,CAAA;AAChG,MAAA;AAAA;AAGN;AAGA,SAAS,YAAA,CAAa,MAAY,QAAA,EAA0B;AAC1D,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS;AAAA,MAC7C,QAAA;AAAA,MACA,IAAA,EAAM,SAAA;AAAA,MAAW,KAAA,EAAO,SAAA;AAAA,MAAW,GAAA,EAAK,SAAA;AAAA,MACxC,IAAA,EAAM,SAAA;AAAA,MAAW,MAAA,EAAQ,SAAA;AAAA,MAAW,MAAA,EAAQ,SAAA;AAAA,MAAW,MAAA,EAAQ;AAAA,KAChE,CAAA,CAAE,aAAA,CAAc,IAAI,CAAA;AACrB,IAAA,MAAM,IAA4B,EAAC;AACnC,IAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,IAAI,CAAA,CAAE,IAAA,KAAS,WAAW,CAAA,CAAE,CAAA,CAAE,IAAI,CAAA,GAAI,CAAA,CAAE,KAAA;AAC/D,IAAA,MAAM,OAAO,CAAA,CAAE,MAAM,MAAM,IAAA,GAAO,IAAA,GAAO,EAAE,MAAM,CAAA;AACjD,IAAA,OAAO,CAAA,EAAG,EAAE,MAAM,CAAC,IAAI,CAAA,CAAE,OAAO,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,KAAK,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAC,CAAA,CAAA;AAAA,EACrF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAK,WAAA,EAAY;AAAA,EAC1B;AACF;AAGA,SAAS,WAAW,KAAA,EAAuB;AACzC,EAAA,OAAO,YAAA,CAAa,IAAI,IAAA,CAAK,KAAK,GAAG,aAAA,EAAe,CAAA,CAAE,KAAA,CAAM,EAAE,CAAA;AAChE;AAEA,SAAS,iBAAA,CAAkB,OAAqC,QAAA,EAA0B;AACxF,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,QAAA;AACtC,EAAA,MAAM,CAAA,GAAI,uBAAA,CAAwB,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AACnD,EAAA,IAAI,CAAC,GAAG,OAAO,QAAA;AACf,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,EAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,KAAK,WAAA,EAAY;AACvC,EAAA,MAAM,IAAA,GAAO,SAAS,GAAA,GAAM,GAAA,GAAO,SAAS,GAAA,GAAM,IAAA,GAAY,IAAA,KAAS,GAAA,GAAM,KAAA,GAAa,GAAA;AAC1F,EAAA,OAAO,CAAA,GAAI,IAAA;AACb;AAEA,SAAS,eAAe,EAAA,EAAoB;AAC1C,EAAA,IAAI,KAAK,KAAA,KAAe,CAAA,EAAG,OAAO,CAAA,EAAG,KAAK,KAAU,CAAA,CAAA,CAAA;AACpD,EAAA,IAAI,KAAK,IAAA,KAAc,CAAA,EAAG,OAAO,CAAA,EAAG,KAAK,IAAS,CAAA,CAAA,CAAA;AAClD,EAAA,IAAI,KAAK,GAAA,KAAW,CAAA,EAAG,OAAO,CAAA,EAAG,KAAK,GAAM,CAAA,CAAA,CAAA;AAC5C,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAI,CAAC,CAAA,CAAA,CAAA;AACjC;AAEA,SAAS,UAAU,OAAA,EAAwB;AACzC,EAAA,MAAM,SAAS,sBAAA,EAAuB;AACtC,EAAA,IAAI,SAAS,OAAO,IAAA,CAAK,EAAE,cAAA,EAAgB,QAAQ,CAAA;AACnD,EAAA,GAAA,CAAI,MAAM,CAAA;AACZ;AAIA,IAAM,oBAAA,GAAuB;AAAA,EAC3B,qBAAA;AAAA,EAAuB,qBAAA;AAAA,EAAuB,sBAAA;AAAA,EAC9C,cAAA;AAAA,EAAgB,cAAA;AAAA,EAAgB,kBAAA;AAAA,EAAoB;AACtD,CAAA;AAEA,SAAS,aAAa,CAAA,EAA+B;AACnD,EAAA,OAAO,CAAC,CAAC,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,IAAY,OAAQ,CAAA,CAAmB,IAAA,KAAS,UAAA,IAAc,OAAQ,CAAA,CAAmB,OAAA,KAAY,UAAA;AAClI;AAEA,eAAe,QAAQ,OAAA,EAAoD;AACzE,EAAA,MAAM,SAAA,GAAY,OAAA,IAAW,oBAAA,CAAqB,IAAA,CAAK,CAAC,CAAA,KAAM,UAAA,CAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,EAAG,CAAC,CAAC,CAAC,CAAA;AACnG,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,oBAAA;AAAA,MACR,CAAA,0FAAA,EAA6F,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,KAC9H;AAAA,EACF;AACA,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,SAAS,CAAA;AAC5C,EAAA,IAAI,CAAC,WAAW,GAAG,CAAA,QAAS,IAAI,oBAAA,CAAqB,CAAA,yBAAA,EAA4B,GAAG,CAAA,CAAE,CAAA;AAEtF,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAO,MAAM,OAAO,aAAA,CAAc,GAAG,CAAA,CAAE,IAAA,CAAA;AAAA,EACzC,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,IAAA,IAAI,0CAA0C,IAAA,CAAK,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,KAAK,CAAA,EAAG;AAC9E,MAAA,MAAM,IAAI,oBAAA;AAAA,QACR,CAAA;AAAA,iEAAA,EAAwJ,SAAS;AAAA,gCAAA;AAAA,OACnK;AAAA,IACF;AACA,IAAA,MAAM,IAAI,oBAAA,CAAqB,CAAA,iBAAA,EAAoB,SAAS,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAA;AAAA,EACxE;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,GAAA,CAAI,SAAS,CAAC,CAAA,GAAI,GAAA,CAAI,SAAS,CAAA,GACtD,YAAA,CAAa,GAAA,CAAI,WAAW,CAAC,CAAA,GAAI,GAAA,CAAI,WAAW,CAAA,GAChD,YAAA,CAAa,GAAA,CAAI,KAAK,CAAC,CAAA,GAAI,GAAA,CAAI,KAAK,CAAA,GACpC,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,YAAY,CAAA;AACxC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,oBAAA,CAAqB,CAAA,EAAG,SAAS,CAAA,qGAAA,CAAkG,CAAA;AAAA,EAC/I;AACA,EAAA,OAAO,KAAA;AACT;AAIA,SAAS,SAAA,GAAkB;AACzB,EAAA,GAAA,CAAI,GAAG,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,WAAW,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,sBAAmB,CAAC,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,GAAA,GAAM,OAAO,CAAC,CAAA,CAAE,CAAA;AAC3F,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,OAAO,CAAC,CAAA;AACnB,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,CAAK,WAAW,CAAC,CAAA,oBAAA,CAAsB,CAAA;AAClD,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,UAAU,CAAC,CAAA;AACtB,EAAA,MAAM,IAAA,GAA2B;AAAA,IAC/B,CAAC,UAAU,+BAA+B,CAAA;AAAA,IAC1C,CAAC,kBAAkB,qCAAqC,CAAA;AAAA,IACxD,CAAC,wBAAwB,yBAAyB,CAAA;AAAA,IAClD,CAAC,iCAAiC,uBAAuB,CAAA;AAAA,IACzD,CAAC,gBAAgB,mDAAmD,CAAA;AAAA,IACpE,CAAC,UAAU,mCAAmC,CAAA;AAAA,IAC9C,CAAC,uBAAuB,+CAA+C,CAAA;AAAA,IACvE,CAAC,0BAA0B,4DAAuD,CAAA;AAAA,IAClF,CAAC,8BAA8B,mEAA8D,CAAA;AAAA,IAC7F,CAAC,2BAA6B,2CAA2C,CAAA;AAAA,IACzE,CAAC,2BAA2B,wCAAwC,CAAA;AAAA,IACpE,CAAC,UAAU,mCAAmC;AAAA,GAChD;AACA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,KAAK,IAAA,EAAM,GAAA,CAAI,KAAK,CAAA,CAAE,IAAA,CAAK,KAAK,MAAA,CAAO,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AACnF,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,QAAQ,CAAC,CAAA;AACpB,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,yBAAyB,CAAC,CAAA,CAAE,CAAA;AAC3E,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,gBAAgB,CAAC,CAAA,CAAE,CAAA;AACtE,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,gBAAgB,CAAC,CAAA,CAAE,CAAA;AACtE,EAAA,GAAA,CAAI,CAAA,EAAA,EAAK,CAAA,CAAE,IAAA,CAAK,eAAA,CAAgB,MAAA,CAAO,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,CAAK,eAAe,CAAC,CAAA,CAAE,CAAA;AACxE,EAAA,GAAA,EAAI;AACJ,EAAA,GAAA,CAAI,CAAA,CAAE,IAAA,CAAK,gFAA2E,CAAC,CAAA;AACzF;AAEA,SAAS,WAAW,CAAA,EAAyC;AAC3D,EAAA,MAAM,IAAI,OAAO,CAAA,KAAM,QAAA,GAAW,MAAA,CAAO,CAAC,CAAA,GAAI,GAAA;AAC9C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,GAAG,OAAO,EAAA;AAChC,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,GAAG,CAAA;AACjD;AAEA,SAAS,QAAA,CAAS,GAAW,CAAA,EAAmB;AAC9C,EAAA,OAAO,CAAA,CAAE,SAAS,CAAA,GAAI,CAAA,CAAE,MAAM,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,GAAI,QAAA,GAAM,CAAA;AAClD;AAEA,eAAsB,IAAI,IAAA,EAAiC;AACzD,EAAA,MAAM,IAAA,GAAO,UAAU,IAAI,CAAA;AAC3B,EAAA,IAAI,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA,WAAY,KAAK,CAAA;AAC1C,EAAA,MAAM,OAAA,GAAU,CAAC,CAAC,IAAA,CAAK,MAAM,MAAM,CAAA;AAEnC,EAAA,IAAI,KAAK,KAAA,CAAM,SAAS,KAAK,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,EAAG;AAC5C,IAAA,GAAA,CAAI,OAAO,CAAA;AACX,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,IAAK,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,IAAK,IAAA,CAAK,YAAY,MAAA,EAAQ;AACrF,IAAA,SAAA,EAAU;AACV,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,QAAQ,KAAK,OAAA;AAAS,MACpB,KAAK,QAAA;AAAU,QAAA,MAAM,UAAU,OAAO,CAAA;AAAG,QAAA;AAAA,MACzC,KAAK,MAAA;AAAQ,QAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,CAAC,GAAG,OAAO,CAAA;AAAG,QAAA;AAAA,MAC1D,KAAK,OAAA;AAAS,QAAA,MAAM,QAAA,CAAS,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA;AAAG,QAAA;AAAA,MACnD,KAAK,MAAA;AAAQ,QAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA;AAAG,QAAA;AAAA,MACjD,KAAK,KAAA;AAAO,QAAA,MAAM,MAAA,CAAO,IAAA,CAAK,WAAA,EAAa,OAAO,CAAA;AAAG,QAAA;AAAA,MACrD,KAAK,QAAA;AAAU,QAAA,MAAM,UAAU,OAAO,CAAA;AAAG,QAAA;AAAA,MACzC,KAAK,MAAA;AAAQ,QAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,OAAO,OAAO,CAAA;AAAG,QAAA;AAAA,MACnE,KAAK,KAAA;AAAO,QAAA,MAAM,YAAA,CAAa,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,OAAO,OAAO,CAAA;AAAG,QAAA;AAAA,MACvE,KAAK,SAAA;AAAW,QAAA,UAAA,CAAW,IAAA,CAAK,WAAA,EAAa,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA;AAAG,QAAA;AAAA,MACnE,KAAK,SAAA;AAAW,QAAA,MAAM,UAAA,CAAW,IAAA,CAAK,WAAA,EAAa,OAAO,CAAA;AAAG,QAAA;AAAA,MAC7D,KAAK,QAAA;AAAU,QAAA,SAAA,CAAU,OAAO,CAAA;AAAG,QAAA;AAAA,MACnC;AACE,QAAA,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,IAAA,CAAK,OAAO,CAAA,OAAA,EAAU,CAAA,CAAE,IAAA,CAAK,kBAAkB,CAAC,CAAA,CAAA,CAAG,CAAA;AACvF,QAAA,OAAO,CAAA;AAAA;AAEX,IAAA,OAAO,CAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,IAAI,eAAe,iBAAA,EAAmB;AACpC,MAAA,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,GAAA,CAAI,CAAA,IAAA,EAAO,GAAA,CAAI,MAAM,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,OAAO,CAAA,EAAG,GAAA,CAAI,aAAA,IAAiB,GAAA,CAAI,iBAAA,GAAoB,CAAA,CAAE,IAAA,CAAK,CAAA,WAAA,EAAc,GAAA,CAAI,iBAAiB,CAAA,EAAA,CAAI,CAAA,GAAI,EAAE,CAAA,CAAE,CAAA;AAAA,IACpK,CAAA,MAAA,IAAW,eAAe,oBAAA,EAAsB;AAC9C,MAAA,GAAA,CAAI,GAAG,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,IACvE;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AAQA,SAAS,YAAA,GAAwB;AAC/B,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,IAAA,GAAO,CAAC,CAAA;AAC9B,IAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,IAAA,OAAO,aAAa,KAAK,CAAA,KAAM,aAAa,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAAA,EAC5E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,IAAI,cAAa,EAAG;AAElB,EAAA,OAAA,CAAQ,MAAA,CAAO,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAA+B;AACzD,IAAA,IAAI,GAAA,CAAI,IAAA,KAAS,OAAA,EAAS,OAAA,CAAQ,KAAK,CAAC,CAAA;AACxC,IAAA,MAAM,GAAA;AAAA,EACR,CAAC,CAAA;AACD,EAAA,GAAA,CAAI,OAAA,CAAQ,KAAK,KAAA,CAAM,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,IAAA,KAAS;AACxC,IAAA,OAAA,CAAQ,QAAA,GAAW,IAAA;AAAA,EACrB,CAAC,CAAA;AACH","file":"cli.js","sourcesContent":["/**\n * Cron schedule arithmetic for the local engine — next-occurrence, preview, and an upcoming-window\n * planner, all timezone-aware (IANA / DST) and **zero-dependency**.\n *\n * The cloud SDK only needs to *validate* a cron string (see `cron.ts`), because the server owns the\n * scheduler. The local engine has to actually *fire* jobs, so it needs the next time an expression\n * matches. This module is that calculator.\n *\n * How the timezone math works without a date library:\n * • A cron expression matches against **wall-clock** fields (the time a person reads off a clock in\n * the job's timezone), so the search is done on naive calendar fields and only converted to a\n * real epoch once a full match is found.\n * • To convert a wall-clock time in a zone to an absolute epoch we use the runtime's own IANA\n * database via `Intl.DateTimeFormat`: format a guess into the zone, measure the offset it\n * implies, and correct once. This is the standard offset-probe technique and it handles DST\n * transitions (a daily job at 04:00 stays at 04:00 local; the gap to the previous fire is 23h or\n * 25h across the spring/autumn switch).\n *\n * Supported syntax mirrors `validateCron`: 5-field crontab, an optional leading seconds field\n * (6 fields), the `@macros`, month/weekday names, and `*` / ranges / lists / steps. Day-of-month and\n * day-of-week combine with Vixie cron's OR semantics when both are restricted.\n */\n\nconst MACRO_EXPANSIONS: Record<string, string> = {\n \"@yearly\": \"0 0 1 1 *\",\n \"@annually\": \"0 0 1 1 *\",\n \"@monthly\": \"0 0 1 * *\",\n \"@weekly\": \"0 0 * * 0\",\n \"@daily\": \"0 0 * * *\",\n \"@midnight\": \"0 0 * * *\",\n \"@hourly\": \"0 * * * *\",\n};\n\nconst MONTH_NAMES = [\"jan\", \"feb\", \"mar\", \"apr\", \"may\", \"jun\", \"jul\", \"aug\", \"sep\", \"oct\", \"nov\", \"dec\"];\nconst DOW_NAMES = [\"sun\", \"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\"];\n\ninterface FieldSpec {\n min: number;\n max: number;\n names?: string[];\n /** Offset added to a resolved name index (months are 1-based, weekdays 0-based). */\n nameOffset: number;\n /** Map an expanded value into its canonical form (used to fold weekday 7 → 0). */\n fold?: (v: number) => number;\n label: string;\n}\n\nconst SECOND_SPEC: FieldSpec = { min: 0, max: 59, nameOffset: 0, label: \"second\" };\nconst MINUTE_SPEC: FieldSpec = { min: 0, max: 59, nameOffset: 0, label: \"minute\" };\nconst HOUR_SPEC: FieldSpec = { min: 0, max: 23, nameOffset: 0, label: \"hour\" };\nconst DOM_SPEC: FieldSpec = { min: 1, max: 31, nameOffset: 0, label: \"day-of-month\" };\nconst MONTH_SPEC: FieldSpec = { min: 1, max: 12, names: MONTH_NAMES, nameOffset: 1, label: \"month\" };\nconst DOW_SPEC: FieldSpec = { min: 0, max: 7, names: DOW_NAMES, nameOffset: 0, fold: (v) => v % 7, label: \"day-of-week\" };\n\n/** A cron expression compiled into the set of values each field matches. */\nexport interface ParsedCron {\n /** Allowed seconds. For a 5-field expression this is `{0}`. */\n seconds: Set<number>;\n minutes: Set<number>;\n hours: Set<number>;\n daysOfMonth: Set<number>;\n months: Set<number>;\n /** Allowed weekdays, 0 = Sunday … 6 = Saturday (7 is folded to 0). */\n daysOfWeek: Set<number>;\n /** True when the day-of-month field was anything other than `*`/`?`. */\n domRestricted: boolean;\n /** True when the day-of-week field was anything other than `*`/`?`. */\n dowRestricted: boolean;\n /** True for `@reboot`, which has no scheduled next time (the engine fires it once at start). */\n reboot: boolean;\n}\n\n/** Parse a cron expression into matchable value-sets. Throws on a malformed expression. */\nexport function parseCron(expr: string): ParsedCron {\n if (typeof expr !== \"string\" || !expr.trim()) throw new Error(\"cron expression is empty\");\n let trimmed = expr.trim();\n\n if (trimmed.startsWith(\"@\")) {\n const macro = trimmed.toLowerCase();\n if (macro === \"@reboot\") {\n return {\n seconds: new Set([0]), minutes: new Set(), hours: new Set(), daysOfMonth: new Set(),\n months: new Set(), daysOfWeek: new Set(), domRestricted: false, dowRestricted: false, reboot: true,\n };\n }\n const expanded = MACRO_EXPANSIONS[macro];\n if (!expanded) throw new Error(`unknown cron macro \"${trimmed}\" (try @daily, @hourly, …)`);\n trimmed = expanded;\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5 && parts.length !== 6) {\n throw new Error(`expected 5 fields (min hour dom month dow) or 6 with seconds, got ${parts.length}: \"${trimmed}\"`);\n }\n\n const hasSeconds = parts.length === 6;\n const [secRaw, minRaw, hourRaw, domRaw, monthRaw, dowRaw] = hasSeconds\n ? parts\n : [\"0\", ...parts];\n\n return {\n seconds: expandField(secRaw!, SECOND_SPEC),\n minutes: expandField(minRaw!, MINUTE_SPEC),\n hours: expandField(hourRaw!, HOUR_SPEC),\n daysOfMonth: expandField(domRaw!, DOM_SPEC),\n months: expandField(monthRaw!, MONTH_SPEC),\n daysOfWeek: expandField(dowRaw!, DOW_SPEC),\n domRestricted: isRestricted(domRaw!),\n dowRestricted: isRestricted(dowRaw!),\n reboot: false,\n };\n}\n\nfunction isRestricted(field: string): boolean {\n const f = field.trim();\n return f !== \"*\" && f !== \"?\";\n}\n\n/** Expand one comma-separated field (`*`, ranges, lists, steps, names) into its value set. */\nfunction expandField(raw: string, spec: FieldSpec): Set<number> {\n const set = new Set<number>();\n for (const term of raw.split(\",\")) {\n if (term === \"\") throw new Error(`empty term in ${spec.label} field \"${raw}\"`);\n\n let base = term;\n let step = 1;\n const slash = term.indexOf(\"/\");\n if (slash >= 0) {\n base = term.slice(0, slash);\n const stepStr = term.slice(slash + 1);\n if (!/^\\d+$/.test(stepStr) || Number(stepStr) === 0) {\n throw new Error(`invalid step \"${stepStr}\" in ${spec.label} field \"${raw}\"`);\n }\n step = Number(stepStr);\n }\n\n let lo: number | null;\n let hi: number | null;\n if (base === \"*\" || base === \"?\") {\n lo = spec.min;\n hi = spec.max;\n } else {\n const dash = base.indexOf(\"-\");\n if (dash > 0) {\n lo = resolveValue(base.slice(0, dash), spec);\n hi = resolveValue(base.slice(dash + 1), spec);\n } else {\n lo = resolveValue(base, spec);\n // A bare value with a step (e.g. \"5/15\") runs from the value up to the field max.\n hi = step > 1 ? spec.max : lo;\n }\n }\n\n if (lo === null || hi === null) {\n throw new Error(`value out of range in ${spec.label} field \"${raw}\" (${spec.min}-${spec.max})`);\n }\n if (lo > hi) throw new Error(`range start ${lo} is greater than end ${hi} in ${spec.label} field \"${raw}\"`);\n\n for (let v = lo; v <= hi; v += step) set.add(spec.fold ? spec.fold(v) : v);\n }\n return set;\n}\n\n/** Resolve a numeric or named token to its number, or null when out of range / unknown. */\nfunction resolveValue(token: string, spec: FieldSpec): number | null {\n const t = token.trim();\n if (/^\\d+$/.test(t)) {\n const n = Number(t);\n return n >= spec.min && n <= spec.max ? n : null;\n }\n if (spec.names) {\n const idx = spec.names.indexOf(t.toLowerCase());\n if (idx >= 0) return idx + spec.nameOffset;\n }\n return null;\n}\n\n// ─── Next-occurrence search ──────────────────────────────────────────────────\n\nexport interface NextOccurrenceOptions {\n /** Search strictly after this instant (epoch ms or Date). Defaults to now. */\n from?: Date | number;\n /** IANA timezone the expression is read in. Defaults to \"UTC\". */\n timeZone?: string;\n}\n\n/** How many years ahead the search gives up after — a guard against impossible expressions. */\nconst SEARCH_HORIZON_YEARS = 5;\n\n/**\n * The next instant the expression fires, strictly after `from`, in the given timezone — or `null`\n * when nothing matches within {@link SEARCH_HORIZON_YEARS} (e.g. Feb-30). Throws for `@reboot`.\n */\nexport function nextOccurrence(expr: string | ParsedCron, opts: NextOccurrenceOptions = {}): Date | null {\n const parsed = typeof expr === \"string\" ? parseCron(expr) : expr;\n if (parsed.reboot) throw new Error(\"@reboot has no scheduled next occurrence (the engine fires it once at start)\");\n\n const tz = opts.timeZone ?? \"UTC\";\n const fromMs = opts.from === undefined ? Date.now() : typeof opts.from === \"number\" ? opts.from : opts.from.getTime();\n\n // Move strictly forward by at least one whole second, then search on wall-clock fields.\n const cursor = Math.floor(fromMs / 1000) * 1000 + 1000;\n const p = getZonedParts(cursor, tz);\n const startYear = p.y;\n\n const hourArr = sorted(parsed.hours);\n const minuteArr = sorted(parsed.minutes);\n const secondArr = sorted(parsed.seconds);\n\n let guard = 0;\n while (guard++ < 1_000_000) {\n if (p.y > startYear + SEARCH_HORIZON_YEARS) return null;\n\n if (!parsed.months.has(p.mo)) {\n bumpMonth(p);\n continue;\n }\n if (p.d > daysInMonth(p.y, p.mo)) {\n bumpMonth(p);\n continue;\n }\n if (!dayMatches(parsed, p.y, p.mo, p.d)) {\n bumpDay(p);\n continue;\n }\n const nh = firstAtLeast(hourArr, p.h);\n if (nh === null) {\n bumpDay(p);\n continue;\n }\n if (nh !== p.h) {\n p.h = nh;\n p.mi = 0;\n p.s = 0;\n }\n const nmi = firstAtLeast(minuteArr, p.mi);\n if (nmi === null) {\n p.h += 1;\n p.mi = 0;\n p.s = 0;\n continue;\n }\n if (nmi !== p.mi) {\n p.mi = nmi;\n p.s = 0;\n }\n const ns = firstAtLeast(secondArr, p.s);\n if (ns === null) {\n p.mi += 1;\n p.s = 0;\n continue;\n }\n p.s = ns;\n\n // Full wall-clock match — convert to a real epoch in the zone.\n const epoch = zonedWallToEpoch(p, tz);\n // Guard against a DST fold mapping the candidate back to or before `from`.\n if (epoch <= fromMs) {\n p.s += 1;\n continue;\n }\n return new Date(epoch);\n }\n throw new Error(`nextOccurrence: search exceeded its iteration bound for \"${typeof expr === \"string\" ? expr : \"(parsed)\"}\"`);\n}\n\n/** Whether a day satisfies the day-of-month / day-of-week fields, with Vixie OR semantics. */\nfunction dayMatches(parsed: ParsedCron, y: number, mo: number, d: number): boolean {\n const domOk = parsed.daysOfMonth.has(d);\n const dowOk = parsed.daysOfWeek.has(weekdayOf(y, mo, d));\n if (parsed.domRestricted && parsed.dowRestricted) return domOk || dowOk;\n if (parsed.domRestricted) return domOk;\n if (parsed.dowRestricted) return dowOk;\n return true;\n}\n\ninterface WallParts {\n y: number;\n mo: number;\n d: number;\n h: number;\n mi: number;\n s: number;\n}\n\nfunction bumpMonth(p: WallParts): void {\n p.mo += 1;\n if (p.mo > 12) {\n p.mo = 1;\n p.y += 1;\n }\n p.d = 1;\n p.h = 0;\n p.mi = 0;\n p.s = 0;\n}\n\nfunction bumpDay(p: WallParts): void {\n p.d += 1;\n p.h = 0;\n p.mi = 0;\n p.s = 0;\n}\n\nfunction sorted(set: Set<number>): number[] {\n return [...set].sort((a, b) => a - b);\n}\n\n/** Smallest array element ≥ `v` (array is sorted ascending), or null. */\nfunction firstAtLeast(arr: number[], v: number): number | null {\n for (const x of arr) if (x >= v) return x;\n return null;\n}\n\nfunction daysInMonth(year: number, month: number): number {\n return new Date(Date.UTC(year, month, 0)).getUTCDate();\n}\n\nfunction weekdayOf(year: number, month: number, day: number): number {\n return new Date(Date.UTC(year, month - 1, day)).getUTCDay();\n}\n\n// ─── Timezone conversion (Intl-based, zero-dependency) ───────────────────────\n\nconst FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nfunction formatterFor(timeZone: string): Intl.DateTimeFormat {\n let fmt = FORMATTER_CACHE.get(timeZone);\n if (!fmt) {\n fmt = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n FORMATTER_CACHE.set(timeZone, fmt);\n }\n return fmt;\n}\n\n/** The wall-clock calendar fields a clock in `timeZone` shows at the given epoch. */\nfunction getZonedParts(epochMs: number, timeZone: string): WallParts {\n const parts = formatterFor(timeZone).formatToParts(new Date(epochMs));\n const m: Record<string, string> = {};\n for (const part of parts) if (part.type !== \"literal\") m[part.type] = part.value;\n let h = Number(m[\"hour\"]);\n if (h === 24) h = 0; // some runtimes render midnight as \"24\" under hour12:false\n return { y: Number(m[\"year\"]), mo: Number(m[\"month\"]), d: Number(m[\"day\"]), h, mi: Number(m[\"minute\"]), s: Number(m[\"second\"]) };\n}\n\n/** Offset (ms) the zone is ahead of UTC at the given instant. */\nfunction offsetAt(epochMs: number, timeZone: string): number {\n const p = getZonedParts(epochMs, timeZone);\n const asNaive = Date.UTC(p.y, p.mo - 1, p.d, p.h, p.mi, p.s);\n return asNaive - epochMs;\n}\n\n/** Convert wall-clock fields in `timeZone` to an absolute epoch, correcting for the zone's offset. */\nfunction zonedWallToEpoch(p: WallParts, timeZone: string): number {\n const asUTC = Date.UTC(p.y, p.mo - 1, p.d, p.h, p.mi, p.s);\n const o1 = offsetAt(asUTC, timeZone);\n let epoch = asUTC - o1;\n const o2 = offsetAt(epoch, timeZone);\n if (o2 !== o1) epoch = asUTC - o2;\n return epoch;\n}\n\n// ─── Preview & upcoming-window planning ──────────────────────────────────────\n\nexport interface PreviewOptions {\n /** Start the preview after this instant. Defaults to now. */\n from?: Date | number;\n /** IANA timezone. Defaults to the runtime's local zone. */\n timeZone?: string;\n /** How many fire times to return (default 5, capped at 100). */\n count?: number;\n}\n\n/** The next N times an expression fires — the engine of `cronvello preview`. */\nexport function previewSchedule(expr: string, opts: PreviewOptions = {}): Date[] {\n const parsed = parseCron(expr);\n const timeZone = opts.timeZone ?? localTimeZone();\n const count = Math.min(Math.max(Math.trunc(opts.count ?? 5), 1), 100);\n const out: Date[] = [];\n let from = opts.from === undefined ? Date.now() : typeof opts.from === \"number\" ? opts.from : opts.from.getTime();\n for (let i = 0; i < count; i++) {\n const next = nextOccurrence(parsed, { from, timeZone });\n if (!next) break;\n out.push(next);\n from = next.getTime();\n }\n return out;\n}\n\nexport interface UpcomingJob {\n key: string;\n schedule: string;\n timeZone: string;\n}\n\nexport interface UpcomingFire {\n key: string;\n time: Date;\n schedule: string;\n timeZone: string;\n}\n\nexport interface UpcomingOptions {\n /** Window start (defaults to now). */\n from?: Date | number;\n /** Window length in ms (defaults to 1 hour). */\n withinMs?: number;\n /** Cap per job so a per-second schedule can't flood the plan (default 50). */\n maxPerJob?: number;\n}\n\n/**\n * Every fire across a set of jobs within the next window, merged and sorted by time — what powers\n * `cronvello dev --dry-run`. Jobs whose schedule can't be parsed are skipped (a dev concern surfaced\n * elsewhere); `@reboot` jobs are skipped because they have no scheduled time.\n */\nexport function upcomingFires(jobs: UpcomingJob[], opts: UpcomingOptions = {}): UpcomingFire[] {\n const from = opts.from === undefined ? Date.now() : typeof opts.from === \"number\" ? opts.from : opts.from.getTime();\n const withinMs = opts.withinMs ?? 60 * 60 * 1000;\n const maxPerJob = Math.max(1, opts.maxPerJob ?? 50);\n const horizon = from + withinMs;\n\n const fires: UpcomingFire[] = [];\n for (const job of jobs) {\n let parsed: ParsedCron;\n try {\n parsed = parseCron(job.schedule);\n } catch {\n continue;\n }\n if (parsed.reboot) continue;\n let cursor = from;\n for (let i = 0; i < maxPerJob; i++) {\n const next = nextOccurrence(parsed, { from: cursor, timeZone: job.timeZone });\n if (!next || next.getTime() > horizon) break;\n fires.push({ key: job.key, time: next, schedule: job.schedule, timeZone: job.timeZone });\n cursor = next.getTime();\n }\n }\n fires.sort((a, b) => a.time.getTime() - b.time.getTime());\n return fires;\n}\n\n/** The runtime's local IANA zone, falling back to UTC if it can't be resolved. */\nexport function localTimeZone(): string {\n try {\n return new Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\";\n } catch {\n return \"UTC\";\n }\n}\n","/**\n * The local dashboard's single-page UI — one self-contained HTML document with inline CSS and\n * vanilla JavaScript, no framework and no build step. It is served verbatim by\n * {@link ./dashboard.ts}, talks only to that server's same-origin JSON + SSE API, and never reaches\n * the network. Kept as a string constant (not a file read) so it works regardless of the bundled\n * `dist/` layout, and so it only loads when the dashboard is actually started.\n *\n * Two things shape the implementation:\n *\n * - **One read model.** Everything on screen comes from a single `/api/state` snapshot. The live\n * event stream appends to the feed and marks the snapshot stale; a debounced refetch reconciles.\n * Nothing re-renders per event.\n * - **The timeline is a fixed track that slides.** Run and fire positions are absolute in time, so\n * they are written once per snapshot; the passing second is a single `translateX` on the track\n * rather than a repositioning pass over every mark.\n *\n * Branding follows BRAND.md: indigo primary, teal/green for healthy runs, amber for retries, red for\n * failures, slate neutrals, light + dark, monospace for cron expressions.\n */\nexport const DASHBOARD_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<meta name=\"robots\" content=\"noindex\" />\n<title>Cronvello — local engine</title>\n<style>\n :root {\n --indigo: #4F46E5;\n --indigo-soft: #6366F1;\n --teal: #14B8A6;\n --green: #10B981;\n --amber: #F59E0B;\n --red: #EF4444;\n --bg: #f7f8fa;\n --panel: #ffffff;\n --panel-2: #f1f5f9;\n --panel-3: #e9edf3;\n --border: #e3e8ef;\n --border-strong: #cbd5e1;\n --text: #0f172a;\n --muted: #64748b;\n --faint: #94a3b8;\n --shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.06);\n --focus: rgba(79, 70, 229, 0.35);\n }\n [data-theme=\"dark\"] {\n --bg: #0a0f1c;\n --panel: #111827;\n --panel-2: #161f2f;\n --panel-3: #1c2740;\n --border: #1f2937;\n --border-strong: #334155;\n --text: #e6e9ef;\n --muted: #94a3b8;\n --faint: #64748b;\n --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.35);\n --focus: rgba(99, 102, 241, 0.45);\n }\n /* Dark-mode-first: follow the OS preference unless the user has explicitly chosen light. */\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n --bg: #0a0f1c;\n --panel: #111827;\n --panel-2: #161f2f;\n --panel-3: #1c2740;\n --border: #1f2937;\n --border-strong: #334155;\n --text: #e6e9ef;\n --muted: #94a3b8;\n --faint: #64748b;\n --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.35);\n --focus: rgba(99, 102, 241, 0.45);\n }\n }\n\n * { box-sizing: border-box; }\n html, body { margin: 0; padding: 0; }\n body {\n background: var(--bg);\n color: var(--text);\n font-family: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Inter, Roboto, sans-serif;\n font-size: 13.5px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n }\n code, .mono, .num {\n font-family: ui-monospace, \"SF Mono\", \"JetBrains Mono\", Menlo, Consolas, monospace;\n font-variant-numeric: tabular-nums;\n }\n .num { font-variant-numeric: tabular-nums; }\n :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }\n\n /* ── Header ─────────────────────────────────────────────────────────────── */\n header.top {\n display: flex; align-items: center; gap: 12px;\n padding: 0 20px; height: 52px;\n border-bottom: 1px solid var(--border);\n background: var(--panel);\n position: sticky; top: 0; z-index: 20;\n }\n .mark {\n width: 26px; height: 26px; border-radius: 7px; flex: none;\n display: grid; place-items: center;\n background: linear-gradient(140deg, var(--indigo), var(--teal));\n color: #fff;\n }\n .mark svg { width: 15px; height: 15px; }\n .wordmark { font-weight: 650; letter-spacing: -0.012em; font-size: 14px; }\n .wordmark span { color: var(--muted); font-weight: 450; margin-left: 7px; }\n .spacer { flex: 1; }\n\n .chip {\n display: inline-flex; align-items: center; gap: 7px;\n height: 26px; padding: 0 10px; border-radius: 7px;\n font-size: 12px; font-weight: 500;\n border: 1px solid var(--border); background: var(--panel-2); color: var(--muted);\n white-space: nowrap;\n }\n .chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); flex: none; }\n .chip.live .dot { background: var(--green); animation: pulse 2.4s ease-out infinite; }\n .chip.down { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, var(--border)); }\n .chip.down .dot { background: var(--red); }\n @keyframes pulse {\n 0% { box-shadow: 0 0 0 0 rgba(16,185,129,0.45); }\n 70% { box-shadow: 0 0 0 5px rgba(16,185,129,0); }\n 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); }\n }\n\n button {\n font: inherit; cursor: pointer; color: var(--text);\n background: var(--panel-2); border: 1px solid var(--border);\n border-radius: 7px; padding: 5px 11px;\n transition: background-color .12s ease, border-color .12s ease;\n }\n button:hover:not(:disabled) { background: var(--panel-3); border-color: var(--border-strong); }\n button:disabled { opacity: .55; cursor: default; }\n button.primary { background: var(--indigo); color: #fff; border-color: var(--indigo); }\n button.primary:hover:not(:disabled) { background: var(--indigo-soft); border-color: var(--indigo-soft); }\n button.icon { padding: 5px 7px; line-height: 0; color: var(--muted); }\n button.icon svg { width: 15px; height: 15px; display: block; }\n button.ghost { background: transparent; border-color: transparent; color: var(--muted); }\n button.ghost:hover:not(:disabled) { background: var(--panel-2); border-color: var(--border); }\n button.tiny { font-size: 11.5px; padding: 3px 8px; border-radius: 6px; }\n\n main { padding: 16px 20px 8px; display: flex; flex-direction: column; gap: 14px; }\n\n /* ── Stat row ───────────────────────────────────────────────────────────── */\n .stats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; }\n @media (max-width: 900px) { .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }\n .stat {\n background: var(--panel); border: 1px solid var(--border); border-radius: 10px;\n padding: 11px 13px; box-shadow: var(--shadow); min-width: 0;\n }\n .stat .label {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--faint); font-weight: 600;\n }\n .stat .value {\n margin-top: 3px; font-size: 21px; font-weight: 600; letter-spacing: -0.02em;\n font-variant-numeric: tabular-nums; line-height: 1.2;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .stat .sub { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n .stat.ok .value { color: var(--green); }\n .stat.bad .value { color: var(--red); }\n .stat.bad.zero .value { color: var(--text); }\n\n /* ── Cards ──────────────────────────────────────────────────────────────── */\n .card {\n background: var(--panel); border: 1px solid var(--border); border-radius: 11px;\n box-shadow: var(--shadow); overflow: hidden; min-width: 0;\n }\n .card > .head {\n display: flex; align-items: center; gap: 10px;\n padding: 9px 14px; border-bottom: 1px solid var(--border);\n background: var(--panel);\n }\n .card > .head h2 {\n margin: 0; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--muted); font-weight: 650;\n }\n .card > .head .hint { font-size: 11.5px; color: var(--faint); }\n select {\n font: inherit; font-size: 11.5px; color: var(--muted); cursor: pointer;\n background: var(--panel-2); border: 1px solid var(--border); border-radius: 6px; padding: 3px 6px;\n }\n\n /* ── Timeline ───────────────────────────────────────────────────────────── */\n .tl { display: flex; align-items: stretch; }\n .tl-gutter {\n flex: none; width: 168px; border-right: 1px solid var(--border);\n background: var(--panel); padding-bottom: 8px;\n }\n @media (max-width: 700px) { .tl-gutter { width: 108px; } }\n .tl-gutter .axis-pad { height: 22px; border-bottom: 1px solid var(--border); }\n .tl-gutter .lane-label {\n height: 26px; display: flex; align-items: center; padding: 0 12px;\n font-size: 12px; font-weight: 550;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .tl-viewport { position: relative; flex: 1; overflow: hidden; padding-bottom: 8px; min-width: 0; }\n .tl-track { position: relative; width: 100%; will-change: transform; }\n .tl-axis { position: relative; height: 22px; border-bottom: 1px solid var(--border); }\n .tl-axis .gl {\n position: absolute; top: 0; bottom: -1000px; width: 1px;\n background: var(--border); opacity: .75;\n }\n .tl-axis .gt {\n position: absolute; top: 4px; font-size: 10.5px; color: var(--faint);\n transform: translateX(4px); white-space: nowrap; font-variant-numeric: tabular-nums;\n }\n .tl-lane { position: relative; height: 26px; }\n .tl-lane + .tl-lane { border-top: 1px dashed transparent; }\n .tl-lane:hover { background: color-mix(in srgb, var(--panel-2) 60%, transparent); }\n .mk { position: absolute; top: 7px; height: 12px; border-radius: 2px; }\n .mk.run { width: 4px; margin-left: -2px; }\n .mk.success { background: var(--green); }\n .mk.error, .mk.timed_out { background: var(--red); }\n .mk.skipped { background: var(--faint); }\n .mk.retried { background: var(--amber); }\n .mk.up {\n width: 0; height: 12px; margin-left: -1px;\n border-left: 1px dashed var(--border-strong); border-radius: 0; opacity: .5;\n }\n .mk.up.first { border-left-color: var(--indigo-soft); border-left-style: solid; opacity: 1; }\n .lane-note {\n position: absolute; right: 8px; top: 6px;\n font-size: 10.5px; color: var(--faint); white-space: nowrap;\n font-variant-numeric: tabular-nums; pointer-events: none;\n }\n .tl-now {\n position: absolute; left: 50%; top: 0; bottom: 0; width: 1px;\n background: var(--indigo); opacity: .75; pointer-events: none; z-index: 3;\n }\n .tl-now::before {\n content: \"\"; position: absolute; top: 0; left: -3px;\n border: 3.5px solid transparent; border-top-color: var(--indigo);\n }\n .tl-empty { padding: 22px 16px; color: var(--muted); text-align: center; font-size: 12.5px; }\n .tl-legend { display: flex; gap: 14px; align-items: center; font-size: 11px; color: var(--faint); }\n .tl-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }\n @media (max-width: 700px) { .tl-legend { display: none; } }\n\n /* ── Grid ───────────────────────────────────────────────────────────────── */\n .grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 14px; align-items: start; }\n @media (max-width: 980px) { .grid { grid-template-columns: minmax(0, 1fr); } }\n\n /* ── Jobs table ─────────────────────────────────────────────────────────── */\n table { width: 100%; border-collapse: collapse; }\n th, td { text-align: left; padding: 9px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }\n th {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.055em;\n color: var(--faint); font-weight: 650; padding-top: 8px; padding-bottom: 8px;\n }\n tbody tr:last-child td { border-bottom: none; }\n tbody tr.job { cursor: pointer; }\n tbody tr.job:hover { background: var(--panel-2); }\n tbody tr.job.is-running { background: color-mix(in srgb, var(--indigo) 6%, transparent); }\n .jobkey { font-weight: 600; }\n .jobdesc { color: var(--muted); font-size: 11.5px; margin-top: 1px; }\n td.sched code { font-size: 12px; color: var(--muted); }\n td.next { white-space: nowrap; }\n td.act { text-align: right; width: 1%; white-space: nowrap; }\n tbody tr.job .act button { opacity: 0; transition: opacity .12s ease; }\n tbody tr.job:hover .act button, tbody tr.job .act button:focus-visible { opacity: 1; }\n @media (hover: none) { tbody tr.job .act button { opacity: 1; } }\n\n .badge {\n display: inline-block; padding: 1.5px 8px; border-radius: 999px;\n font-size: 10.5px; font-weight: 650; letter-spacing: 0.01em;\n }\n .badge.success { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green); }\n .badge.error, .badge.timed_out { background: color-mix(in srgb, var(--red) 16%, transparent); color: var(--red); }\n .badge.skipped { background: color-mix(in srgb, var(--faint) 20%, transparent); color: var(--muted); }\n .badge.running { background: color-mix(in srgb, var(--indigo) 16%, transparent); color: var(--indigo-soft); }\n .badge.none { background: var(--panel-2); color: var(--faint); }\n\n /* ── Feed ───────────────────────────────────────────────────────────────── */\n .feed { max-height: 62vh; overflow-y: auto; overscroll-behavior: contain; }\n .ev {\n display: flex; gap: 9px; align-items: baseline;\n padding: 7px 14px; border-bottom: 1px solid var(--border); font-size: 12.5px;\n }\n .ev:last-child { border-bottom: none; }\n .ev .glyph { width: 13px; text-align: center; flex: none; font-size: 11px; }\n .ev .body { flex: 1; min-width: 0; overflow-wrap: anywhere; }\n .ev .when { color: var(--faint); font-size: 10.5px; font-variant-numeric: tabular-nums; flex: none; }\n .ev .k { font-weight: 600; }\n .ev.success .glyph { color: var(--green); }\n .ev.error .glyph, .ev.timeout .glyph { color: var(--red); }\n .ev.retry .glyph { color: var(--amber); }\n .ev.fire .glyph { color: var(--indigo-soft); }\n .ev.skipped .glyph, .ev.engine .glyph { color: var(--faint); }\n .ev .detail { color: var(--muted); }\n .paused-note {\n padding: 6px 14px; font-size: 11.5px; color: var(--amber);\n background: color-mix(in srgb, var(--amber) 10%, transparent);\n border-bottom: 1px solid var(--border);\n }\n\n .empty { padding: 26px 16px; color: var(--muted); text-align: center; font-size: 12.5px; }\n .empty .lead { color: var(--text); font-weight: 550; margin-bottom: 3px; }\n\n footer {\n padding: 14px 20px 30px; color: var(--faint); font-size: 11.5px;\n display: flex; gap: 8px; flex-wrap: wrap; align-items: center;\n }\n footer .sep { opacity: .5; }\n\n /* ── Drawer ─────────────────────────────────────────────────────────────── */\n .overlay {\n position: fixed; inset: 0; background: rgba(2, 6, 23, 0.5);\n display: none; justify-content: flex-end; z-index: 40;\n }\n .overlay.open { display: flex; }\n .drawer {\n width: min(560px, 94vw); background: var(--panel); border-left: 1px solid var(--border);\n height: 100%; overflow-y: auto; display: flex; flex-direction: column;\n }\n .drawer .dhead {\n display: flex; align-items: center; gap: 10px; padding: 12px 16px;\n border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--panel); z-index: 2;\n }\n .drawer .dtitle { font-weight: 650; letter-spacing: -0.01em; }\n .drawer .pad { padding: 16px; }\n .kv { display: flex; gap: 10px; padding: 5px 0; font-size: 12.5px; }\n .kv > span:first-child { color: var(--muted); min-width: 92px; flex: none; }\n .section-title {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--faint); font-weight: 650; margin: 20px 0 7px;\n }\n ul.plain { list-style: none; margin: 0; padding: 0; }\n ul.plain > li {\n padding: 7px 0; border-bottom: 1px solid var(--border);\n display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px;\n }\n ul.plain > li:last-child { border-bottom: none; }\n .runline { display: block; }\n .runline .row1 { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }\n .runline .meta { color: var(--faint); font-size: 11px; font-variant-numeric: tabular-nums; }\n .runline pre {\n margin: 6px 0 0; padding: 8px 10px; border-radius: 7px;\n background: var(--panel-2); border: 1px solid var(--border);\n font-size: 11.5px; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 180px; overflow: auto;\n }\n .runline pre.err { color: var(--red); border-color: color-mix(in srgb, var(--red) 30%, var(--border)); }\n</style>\n</head>\n<body>\n\n<header class=\"top\">\n <div class=\"mark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 7.2V12l3.4 2\"></path></svg>\n </div>\n <div class=\"wordmark\">Cronvello <span>local engine</span></div>\n <span id=\"engine-chip\" class=\"chip\"><span class=\"dot\"></span><span id=\"engine-text\">starting…</span></span>\n <div class=\"spacer\"></div>\n <span id=\"conn\" class=\"chip\"><span class=\"dot\"></span><span id=\"conn-text\">connecting…</span></span>\n <button id=\"theme-btn\" class=\"icon\" title=\"Toggle light / dark\" aria-label=\"Toggle light or dark theme\">\n <svg id=\"icon-moon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 14.5A8.5 8.5 0 0 1 9.5 4a8.5 8.5 0 1 0 10.5 10.5Z\"></path></svg>\n <svg id=\"icon-sun\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" hidden><circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M12 2.5v2M12 19.5v2M2.5 12h2M19.5 12h2M5.2 5.2l1.4 1.4M17.4 17.4l1.4 1.4M18.8 5.2l-1.4 1.4M6.6 17.4l-1.4 1.4\"></path></svg>\n </button>\n</header>\n\n<main>\n <section class=\"stats\" aria-label=\"Engine summary\">\n <div class=\"stat\"><div class=\"label\">Jobs</div><div class=\"value num\" id=\"s-jobs\">—</div><div class=\"sub\" id=\"s-jobs-sub\"> </div></div>\n <div class=\"stat\"><div class=\"label\">Runs this session</div><div class=\"value num\" id=\"s-runs\">—</div><div class=\"sub\" id=\"s-runs-sub\"> </div></div>\n <div class=\"stat ok\"><div class=\"label\">Succeeded</div><div class=\"value num\" id=\"s-ok\">—</div><div class=\"sub\" id=\"s-ok-sub\"> </div></div>\n <div class=\"stat bad zero\"><div class=\"label\">Failed</div><div class=\"value num\" id=\"s-bad\">—</div><div class=\"sub\" id=\"s-bad-sub\"> </div></div>\n <div class=\"stat\"><div class=\"label\">Next fire</div><div class=\"value num\" id=\"s-next\">—</div><div class=\"sub\" id=\"s-next-sub\"> </div></div>\n </section>\n\n <section class=\"card\">\n <div class=\"head\">\n <h2>Timeline</h2>\n <span class=\"hint\" id=\"tl-hint\"></span>\n <div class=\"spacer\"></div>\n <div class=\"tl-legend\" aria-hidden=\"true\">\n <span><i style=\"background:var(--green)\"></i>ok</span>\n <span><i style=\"background:var(--red)\"></i>failed</span>\n <span><i style=\"background:var(--faint)\"></i>skipped</span>\n <span><i style=\"border-left:2px dashed var(--border-strong);width:2px;border-radius:0\"></i>upcoming</span>\n </div>\n <label class=\"hint\" for=\"tl-span\">Window</label>\n <select id=\"tl-span\" aria-label=\"Timeline window\">\n <option value=\"120000\">2 min</option>\n <option value=\"600000\" selected>10 min</option>\n <option value=\"3600000\">1 hour</option>\n <option value=\"21600000\">6 hours</option>\n </select>\n </div>\n <div class=\"tl\" id=\"tl\">\n <div class=\"tl-gutter\" id=\"tl-gutter\"><div class=\"axis-pad\"></div></div>\n <div class=\"tl-viewport\" id=\"tl-viewport\">\n <div class=\"tl-track\" id=\"tl-track\"><div class=\"tl-axis\" id=\"tl-axis\"></div></div>\n <div class=\"tl-now\" aria-hidden=\"true\"></div>\n </div>\n </div>\n <div class=\"tl-empty\" id=\"tl-empty\" hidden>No jobs to plot.</div>\n </section>\n\n <div class=\"grid\">\n <section class=\"card\">\n <div class=\"head\"><h2>Jobs</h2><span class=\"hint\" id=\"jobs-hint\"></span></div>\n <table>\n <thead><tr><th>Job</th><th>Schedule</th><th>Zone</th><th>Next fire</th><th>Last run</th><th></th></tr></thead>\n <tbody id=\"jobs\"><tr><td colspan=\"6\" class=\"empty\">Loading…</td></tr></tbody>\n </table>\n </section>\n\n <section class=\"card\">\n <div class=\"head\">\n <h2>Live feed</h2>\n <div class=\"spacer\"></div>\n <button id=\"feed-pause\" class=\"tiny ghost\" aria-pressed=\"false\">Pause</button>\n <button id=\"feed-clear\" class=\"tiny ghost\">Clear</button>\n </div>\n <div id=\"feed-paused\" class=\"paused-note\" hidden></div>\n <div id=\"feed\" class=\"feed\" role=\"log\" aria-label=\"Live run feed\">\n <div class=\"empty\"><div class=\"lead\">Waiting for the first run.</div><div id=\"feed-hint\">Every fire shows up here as it happens.</div></div>\n </div>\n </section>\n </div>\n</main>\n\n<footer>\n <span>Local engine</span><span class=\"sep\">·</span>\n <span>no account</span><span class=\"sep\">·</span>\n <span>no cloud</span><span class=\"sep\">·</span>\n <span>no outbound network</span><span class=\"sep\">·</span>\n <span>this process is the only source of truth</span>\n</footer>\n\n<div id=\"overlay\" class=\"overlay\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"drawer-title\" hidden>\n <div class=\"drawer\">\n <div class=\"dhead\">\n <div class=\"dtitle\" id=\"drawer-title\">Job</div>\n <div class=\"spacer\"></div>\n <button id=\"drawer-run\" class=\"primary tiny\">Run now</button>\n <button id=\"drawer-close\" class=\"tiny\">Close</button>\n </div>\n <div class=\"pad\" id=\"drawer-body\"></div>\n </div>\n</div>\n\n<script>\n(function () {\n \"use strict\";\n\n var MAX_FEED = 250;\n var REFRESH_MS = 10000; // reconciliation poll behind the event stream\n var DEBOUNCE_MS = 400; // collapse a burst of events into one refetch\n var UPCOMING = 40; // fire times requested per job\n\n var state = { engine: {}, jobs: [], runs: [] };\n var jobsByKey = {};\n var rows = {}; // key -> { tr, next, last, running }\n var lanes = {}; // key -> { lane, label }\n var laneOrder = [];\n var anchorNow = Date.now();\n var spanMs = 600000;\n var openKey = null;\n var lastFocus = null;\n var paused = false;\n var pausedCount = 0;\n var refreshTimer = null;\n\n function el(id) { return document.getElementById(id); }\n function pad2(n) { return n < 10 ? \"0\" + n : \"\" + n; }\n function clockTime(ms) {\n var d = new Date(ms);\n return pad2(d.getHours()) + \":\" + pad2(d.getMinutes()) + \":\" + pad2(d.getSeconds());\n }\n function fmtDuration(ms) {\n if (ms == null) return \"\";\n if (ms < 1000) return ms + \"ms\";\n if (ms < 60000) return (ms / 1000).toFixed(ms < 10000 ? 2 : 1) + \"s\";\n var m = Math.floor(ms / 60000);\n return m + \"m \" + Math.round((ms % 60000) / 1000) + \"s\";\n }\n function fmtElapsed(ms) {\n var s = Math.max(0, Math.floor(ms / 1000));\n var d = Math.floor(s / 86400); s -= d * 86400;\n var h = Math.floor(s / 3600); s -= h * 3600;\n var m = Math.floor(s / 60); s -= m * 60;\n if (d) return d + \"d \" + h + \"h\";\n if (h) return h + \"h \" + m + \"m\";\n if (m) return m + \"m \" + s + \"s\";\n return s + \"s\";\n }\n /** A round duration, for labels rather than countdowns: \"5m\", not \"5m 0s\". */\n function fmtSpan(ms) {\n if (ms % 3600000 === 0) return (ms / 3600000) + \"h\";\n if (ms % 60000 === 0) return (ms / 60000) + \"m\";\n return Math.round(ms / 1000) + \"s\";\n }\n function countdown(iso) {\n if (!iso) return \"\\\\u2014\";\n var diff = new Date(iso).getTime() - Date.now();\n if (diff <= 0) return \"due now\";\n return \"in \" + fmtElapsed(diff);\n }\n function localTime(iso) {\n try { return new Date(iso).toLocaleString(); } catch (e) { return String(iso); }\n }\n function setText(node, text) { if (node && node.textContent !== text) node.textContent = text; }\n\n // ── Theme ──────────────────────────────────────────────────────────────────\n function applyTheme(t) {\n if (t === \"dark\" || t === \"light\") document.documentElement.setAttribute(\"data-theme\", t);\n else document.documentElement.removeAttribute(\"data-theme\");\n }\n function resolvedTheme() {\n var t = document.documentElement.getAttribute(\"data-theme\");\n if (t) return t;\n return window.matchMedia && window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n }\n // The icon offers the theme you would switch *to*, which is the only reading that stays true\n // whether the current theme came from the OS or from a previous click.\n function paintThemeIcon() {\n var dark = resolvedTheme() === \"dark\";\n el(\"icon-sun\").hidden = !dark;\n el(\"icon-moon\").hidden = dark;\n el(\"theme-btn\").title = dark ? \"Switch to light\" : \"Switch to dark\";\n }\n try { applyTheme(localStorage.getItem(\"cronvello-theme\")); } catch (e) {}\n paintThemeIcon();\n el(\"theme-btn\").addEventListener(\"click\", function () {\n var next = resolvedTheme() === \"dark\" ? \"light\" : \"dark\";\n applyTheme(next);\n paintThemeIcon();\n try { localStorage.setItem(\"cronvello-theme\", next); } catch (e) {}\n });\n\n // ── Badges ─────────────────────────────────────────────────────────────────\n function badge(status) {\n var span = document.createElement(\"span\");\n span.className = \"badge \" + (status || \"none\");\n span.textContent = status || \"\\\\u2014\";\n return span;\n }\n function replaceChild1(cell, node) {\n cell.textContent = \"\";\n cell.appendChild(node);\n }\n\n // ── Stats ──────────────────────────────────────────────────────────────────\n function renderStats() {\n var jobs = state.jobs, runs = state.runs;\n var ok = 0, bad = 0, skipped = 0, retried = 0;\n for (var i = 0; i < runs.length; i++) {\n var s = runs[i].status;\n if (s === \"success\") { ok++; if (runs[i].attempts > 1) retried++; }\n else if (s === \"skipped\") skipped++;\n else bad++;\n }\n var active = 0;\n for (var j = 0; j < jobs.length; j++) if (jobs[j].running) active++;\n\n setText(el(\"s-jobs\"), String(jobs.length));\n setText(el(\"s-jobs-sub\"), active ? active + \" running now\" : \"idle\");\n\n setText(el(\"s-runs\"), String(runs.length));\n var upSince = state.engine.startedAt ? \"up \" + fmtElapsed(Date.now() - state.engine.startedAt) : \"not started\";\n setText(el(\"s-runs-sub\"), upSince);\n\n setText(el(\"s-ok\"), String(ok));\n setText(el(\"s-ok-sub\"), retried ? retried + \" after a retry\" : (skipped ? skipped + \" skipped (overlap)\" : \"\\\\u00a0\"));\n\n setText(el(\"s-bad\"), String(bad));\n el(\"s-bad\").parentNode.className = \"stat bad\" + (bad ? \"\" : \" zero\");\n setText(el(\"s-bad-sub\"), bad ? \"check the feed\" : \"nothing failed\");\n\n // Soonest upcoming fire across all jobs.\n var soonest = null, soonestKey = \"\";\n for (var k = 0; k < jobs.length; k++) {\n if (!jobs[k].nextFire) continue;\n var t = new Date(jobs[k].nextFire).getTime();\n if (soonest === null || t < soonest) { soonest = t; soonestKey = jobs[k].key; }\n }\n if (soonest === null) {\n setText(el(\"s-next\"), \"\\\\u2014\");\n setText(el(\"s-next-sub\"), jobs.length ? \"nothing scheduled\" : \"\\\\u00a0\");\n } else {\n setText(el(\"s-next\"), countdown(new Date(soonest).toISOString()).replace(/^in /, \"\"));\n setText(el(\"s-next-sub\"), soonestKey);\n }\n }\n\n // ── Jobs table ─────────────────────────────────────────────────────────────\n // \"No jobs\" and \"not loaded yet\" both leave the row map empty, so this flag is what separates\n // them. Without it the first snapshot of an empty registry would sit on \"Loading\" forever.\n var built = false;\n\n function sameKeys(jobs) {\n if (!built) return false;\n var keys = Object.keys(rows);\n if (keys.length !== jobs.length) return false;\n for (var i = 0; i < jobs.length; i++) if (!rows[jobs[i].key]) return false;\n return true;\n }\n\n function buildRows(jobs) {\n var tbody = el(\"jobs\");\n tbody.textContent = \"\";\n rows = {};\n if (!jobs.length) {\n var tr0 = document.createElement(\"tr\");\n var td0 = document.createElement(\"td\");\n td0.colSpan = 6; td0.className = \"empty\";\n td0.innerHTML = '<div class=\"lead\">No jobs registered.</div>Add one to <code>jobs</code> in your config and restart.';\n tr0.appendChild(td0); tbody.appendChild(tr0);\n return;\n }\n for (var i = 0; i < jobs.length; i++) {\n var j = jobs[i];\n var tr = document.createElement(\"tr\");\n tr.className = \"job\";\n tr.tabIndex = 0;\n tr.setAttribute(\"role\", \"button\");\n tr.setAttribute(\"aria-label\", \"Details for \" + j.key);\n tr.dataset.key = j.key;\n\n var tdName = document.createElement(\"td\");\n var name = document.createElement(\"div\");\n name.className = \"jobkey\"; name.textContent = j.key;\n tdName.appendChild(name);\n if (j.description) {\n var desc = document.createElement(\"div\");\n desc.className = \"jobdesc\"; desc.textContent = j.description;\n tdName.appendChild(desc);\n }\n\n var tdSched = document.createElement(\"td\");\n tdSched.className = \"sched\";\n var code = document.createElement(\"code\"); code.textContent = j.schedule;\n tdSched.appendChild(code);\n\n var tdZone = document.createElement(\"td\");\n tdZone.style.color = \"var(--muted)\";\n tdZone.textContent = j.timeZone;\n\n var tdNext = document.createElement(\"td\");\n tdNext.className = \"next num\";\n\n var tdLast = document.createElement(\"td\");\n\n var tdAct = document.createElement(\"td\");\n tdAct.className = \"act\";\n var btn = document.createElement(\"button\");\n btn.className = \"tiny\"; btn.textContent = \"Run\";\n btn.setAttribute(\"aria-label\", \"Run \" + j.key + \" now\");\n btn.dataset.key = j.key;\n tdAct.appendChild(btn);\n\n tr.appendChild(tdName); tr.appendChild(tdSched); tr.appendChild(tdZone);\n tr.appendChild(tdNext); tr.appendChild(tdLast); tr.appendChild(tdAct);\n tbody.appendChild(tr);\n\n rows[j.key] = { tr: tr, next: tdNext, last: tdLast, btn: btn };\n }\n }\n\n function paintRows(jobs) {\n for (var i = 0; i < jobs.length; i++) {\n var j = jobs[i], r = rows[j.key];\n if (!r) continue;\n r.tr.classList.toggle(\"is-running\", !!j.running);\n r.next.dataset.next = j.nextFire || \"\";\n setText(r.next, j.nextFire ? countdown(j.nextFire) : \"\\\\u2014\");\n var status = j.running ? \"running\" : (j.lastRun ? j.lastRun.status : \"\");\n if (r.lastStatus !== status) {\n r.lastStatus = status;\n replaceChild1(r.last, badge(status));\n }\n }\n }\n\n function tickCountdowns() {\n for (var key in rows) {\n if (!Object.prototype.hasOwnProperty.call(rows, key)) continue;\n var cell = rows[key].next;\n var iso = cell.dataset.next;\n setText(cell, iso ? countdown(iso) : \"\\\\u2014\");\n }\n if (state.engine.startedAt) {\n setText(el(\"s-runs-sub\"), \"up \" + fmtElapsed(Date.now() - state.engine.startedAt));\n }\n var jobs = state.jobs, soonest = null, soonestKey = \"\";\n for (var i = 0; i < jobs.length; i++) {\n if (!jobs[i].nextFire) continue;\n var t = new Date(jobs[i].nextFire).getTime();\n if (soonest === null || t < soonest) { soonest = t; soonestKey = jobs[i].key; }\n }\n if (soonest !== null) {\n setText(el(\"s-next\"), countdown(new Date(soonest).toISOString()).replace(/^in /, \"\"));\n setText(el(\"s-next-sub\"), soonestKey);\n }\n }\n\n // ── Timeline ───────────────────────────────────────────────────────────────\n //\n // The track covers a fixed absolute window [anchorNow - span/2, anchorNow + span/2] and every mark\n // is positioned once, as a percentage of that window. The passing second only shifts the whole\n // track, so an idle dashboard writes one transform per frame-ish instead of touching every mark.\n function buildLanes(jobs) {\n var gutter = el(\"tl-gutter\"), track = el(\"tl-track\");\n gutter.textContent = \"\";\n var pad = document.createElement(\"div\"); pad.className = \"axis-pad\";\n gutter.appendChild(pad);\n\n // Keep the axis, drop the lanes.\n var axis = el(\"tl-axis\");\n track.textContent = \"\";\n track.appendChild(axis);\n\n lanes = {}; laneOrder = [];\n for (var i = 0; i < jobs.length; i++) {\n var key = jobs[i].key;\n var label = document.createElement(\"div\");\n label.className = \"lane-label\"; label.textContent = key; label.title = key;\n gutter.appendChild(label);\n\n var lane = document.createElement(\"div\");\n lane.className = \"tl-lane\"; lane.dataset.key = key;\n track.appendChild(lane);\n\n lanes[key] = { lane: lane, label: label };\n laneOrder.push(key);\n }\n el(\"tl\").hidden = jobs.length === 0;\n el(\"tl-empty\").hidden = jobs.length !== 0;\n }\n\n function axisStep(span) {\n var steps = [1000, 5000, 15000, 30000, 60000, 300000, 900000, 1800000, 3600000, 10800000, 21600000];\n for (var i = 0; i < steps.length; i++) if (span / steps[i] <= 10) return steps[i];\n return steps[steps.length - 1];\n }\n\n function paintTimeline() {\n var jobs = state.jobs;\n anchorNow = Date.now();\n var start = anchorNow - spanMs / 2;\n var pct = function (t) { return ((t - start) / spanMs) * 100; };\n el(\"tl-track\").style.transform = \"translateX(0%)\";\n\n // Axis gridlines.\n var axis = el(\"tl-axis\");\n axis.textContent = \"\";\n var step = axisStep(spanMs);\n var first = Math.ceil(start / step) * step;\n for (var t = first; t < start + spanMs; t += step) {\n var p = pct(t);\n var gl = document.createElement(\"div\");\n gl.className = \"gl\"; gl.style.left = p + \"%\";\n axis.appendChild(gl);\n var gt = document.createElement(\"div\");\n gt.className = \"gt\"; gt.style.left = p + \"%\"; gt.textContent = clockTime(t);\n axis.appendChild(gt);\n }\n\n // Marks per lane: past runs, then upcoming fires.\n var runsByKey = {};\n for (var i = 0; i < state.runs.length; i++) {\n var run = state.runs[i];\n (runsByKey[run.key] || (runsByKey[run.key] = [])).push(run);\n }\n\n for (var l = 0; l < laneOrder.length; l++) {\n var key = laneOrder[l];\n var lane = lanes[key].lane;\n lane.textContent = \"\";\n\n var list = runsByKey[key] || [];\n for (var r = 0; r < list.length; r++) {\n var rec = list[r];\n if (rec.startedAt < start || rec.startedAt > start + spanMs) continue;\n var mk = document.createElement(\"div\");\n mk.className = \"mk run \" + rec.status + (rec.status === \"success\" && rec.attempts > 1 ? \" retried\" : \"\");\n mk.style.left = pct(rec.startedAt) + \"%\";\n mk.title = key + \" \\\\u00b7 \" + rec.status + \" \\\\u00b7 \" + clockTime(rec.startedAt) +\n (rec.durationMs ? \" \\\\u00b7 \" + fmtDuration(rec.durationMs) : \"\") +\n (rec.attempts > 1 ? \" \\\\u00b7 \" + rec.attempts + \" attempts\" : \"\");\n lane.appendChild(mk);\n }\n\n var ups = jobsByKey[key] && jobsByKey[key].upcoming ? jobsByKey[key].upcoming : [];\n var plotted = 0;\n for (var u = 0; u < ups.length; u++) {\n var at = new Date(ups[u]).getTime();\n if (at > start + spanMs) break;\n if (at < anchorNow) continue;\n var um = document.createElement(\"div\");\n um.className = \"mk up\" + (plotted === 0 ? \" first\" : \"\");\n um.style.left = pct(at) + \"%\";\n um.title = key + \" \\\\u00b7 next fire \" + clockTime(at);\n lane.appendChild(um);\n plotted++;\n }\n\n // A lane whose whole schedule sits outside the window would otherwise read as \"nothing here\",\n // which is indistinguishable from a broken job. Say when it actually fires.\n if (!lane.childNodes.length) {\n var note = document.createElement(\"div\");\n note.className = \"lane-note\";\n var job = jobsByKey[key];\n note.textContent = job && job.nextFire ? \"next \" + countdown(job.nextFire) : \"not scheduled\";\n lane.appendChild(note);\n }\n }\n\n el(\"tl-hint\").textContent = fmtSpan(spanMs / 2) + \" back, \" + fmtSpan(spanMs / 2) + \" ahead\";\n }\n\n function slideTimeline() {\n var drift = Date.now() - anchorNow;\n // Re-anchor rather than sliding forever, so marks that left the window get dropped.\n if (Math.abs(drift) > spanMs / 4) { paintTimeline(); return; }\n el(\"tl-track\").style.transform = \"translateX(\" + (-(drift / spanMs) * 100) + \"%)\";\n }\n\n el(\"tl-span\").addEventListener(\"change\", function () {\n spanMs = Number(this.value) || 600000;\n paintTimeline();\n });\n\n // ── Live feed ──────────────────────────────────────────────────────────────\n var glyphs = {\n fire: \"\\\\u25b8\", success: \"\\\\u2713\", error: \"\\\\u2717\", timeout: \"\\\\u29d6\",\n retry: \"\\\\u21ba\", skipped: \"\\\\u2298\", scheduled: \"\\\\u00b7\",\n \"engine-start\": \"\\\\u25cf\", \"engine-stop\": \"\\\\u25a0\"\n };\n\n function describe(ev) {\n var frag = document.createDocumentFragment();\n function k(text) { var s = document.createElement(\"span\"); s.className = \"k\"; s.textContent = text; return s; }\n function plain(text) { return document.createTextNode(text); }\n function dim(text) { var s = document.createElement(\"span\"); s.className = \"detail\"; s.textContent = text; return s; }\n\n switch (ev.type) {\n case \"fire\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" fired\"));\n if (ev.attempt > 1) frag.appendChild(dim(\" (attempt \" + ev.attempt + \")\"));\n break;\n case \"success\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" succeeded \"));\n frag.appendChild(dim(\"in \" + fmtDuration(ev.durationMs) + (ev.attempts > 1 ? \", after \" + ev.attempts + \" attempts\" : \"\")));\n break;\n case \"error\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" errored: \" + ev.error));\n frag.appendChild(dim(ev.willRetry ? \" (retrying)\" : \" (gave up)\"));\n break;\n case \"timeout\":\n frag.appendChild(k(ev.key)); frag.appendChild(plain(\" timed out \"));\n frag.appendChild(dim(\"after \" + fmtDuration(ev.durationMs) + (ev.willRetry ? \", retrying\" : \", gave up\")));\n break;\n case \"retry\":\n frag.appendChild(k(ev.key));\n frag.appendChild(dim(\" retrying in \" + fmtDuration(ev.delayMs) + \" (attempt \" + ev.attempt + \")\"));\n break;\n case \"skipped\":\n frag.appendChild(k(ev.key)); frag.appendChild(dim(\" skipped, previous run still in flight\"));\n break;\n case \"scheduled\":\n // This event's timestamp is the *next fire*, not the moment it was emitted. Saying so keeps\n // the feed's right-hand clock strictly the arrival time and never looks out of order.\n frag.appendChild(k(ev.key)); frag.appendChild(dim(\" scheduled for \" + clockTime(ev.at)));\n break;\n case \"engine-start\":\n frag.appendChild(plain(\"Engine started with \" + ev.jobs + \" job\" + (ev.jobs === 1 ? \"\" : \"s\")));\n break;\n case \"engine-stop\":\n frag.appendChild(plain(\"Engine stopped\"));\n break;\n default:\n frag.appendChild(plain(ev.type));\n }\n return frag;\n }\n\n function feedClass(type) {\n if (type === \"engine-start\" || type === \"engine-stop\" || type === \"scheduled\") return \"engine\";\n return type;\n }\n\n function pushEvent(ev) {\n var feed = el(\"feed\");\n var firstChild = feed.firstChild;\n if (firstChild && firstChild.className === \"empty\") feed.textContent = \"\";\n\n var div = document.createElement(\"div\");\n div.className = \"ev \" + feedClass(ev.type);\n\n var g = document.createElement(\"div\");\n g.className = \"glyph\"; g.textContent = glyphs[ev.type] || \"\\\\u2022\";\n var b = document.createElement(\"div\");\n b.className = \"body\"; b.appendChild(describe(ev));\n var w = document.createElement(\"div\");\n w.className = \"when\";\n w.textContent = clockTime(ev.type === \"scheduled\" ? Date.now() : (ev.at || Date.now()));\n\n div.appendChild(g); div.appendChild(b); div.appendChild(w);\n feed.insertBefore(div, feed.firstChild);\n while (feed.childNodes.length > MAX_FEED) feed.removeChild(feed.lastChild);\n }\n\n el(\"feed-pause\").addEventListener(\"click\", function () {\n paused = !paused;\n this.textContent = paused ? \"Resume\" : \"Pause\";\n this.setAttribute(\"aria-pressed\", paused ? \"true\" : \"false\");\n if (!paused) { pausedCount = 0; el(\"feed-paused\").hidden = true; }\n });\n el(\"feed-clear\").addEventListener(\"click\", function () {\n el(\"feed\").textContent = \"\";\n var d = document.createElement(\"div\");\n d.className = \"empty\"; d.textContent = \"Cleared. New events appear here.\";\n el(\"feed\").appendChild(d);\n });\n\n // ── Connection ─────────────────────────────────────────────────────────────\n function setConn(stateName) {\n var chip = el(\"conn\");\n chip.className = \"chip \" + stateName;\n setText(el(\"conn-text\"), stateName === \"live\" ? \"live\" : (stateName === \"down\" ? \"reconnecting\" : \"connecting\\\\u2026\"));\n }\n function setEngineChip() {\n var chip = el(\"engine-chip\");\n var running = state.engine.running;\n chip.className = \"chip\" + (running ? \" live\" : \"\");\n var n = state.jobs.length;\n setText(el(\"engine-text\"), (running ? \"running\" : \"stopped\") + \" \\\\u00b7 \" + n + \" job\" + (n === 1 ? \"\" : \"s\"));\n }\n\n function connect() {\n setConn(\"connecting\");\n var src = new EventSource(\"/api/events\");\n src.onopen = function () { setConn(\"live\"); scheduleRefresh(0); };\n src.onmessage = function (m) {\n var ev;\n try { ev = JSON.parse(m.data); } catch (e) { return; }\n if (paused) {\n pausedCount++;\n el(\"feed-paused\").hidden = false;\n el(\"feed-paused\").textContent = \"Paused \\\\u00b7 \" + pausedCount + \" event\" + (pausedCount === 1 ? \"\" : \"s\") + \" not shown\";\n } else {\n pushEvent(ev);\n }\n // Terminal events change job status / history; reconcile on the next tick.\n if (ev.type !== \"fire\") scheduleRefresh(DEBOUNCE_MS);\n };\n src.onerror = function () { setConn(\"down\"); };\n }\n\n // ── State ──────────────────────────────────────────────────────────────────\n function scheduleRefresh(delay) {\n if (refreshTimer) return;\n refreshTimer = setTimeout(function () { refreshTimer = null; refresh(); }, delay);\n }\n\n function refresh() {\n return fetch(\"/api/state?upcoming=\" + UPCOMING)\n .then(function (r) { return r.json(); })\n .then(function (next) {\n var structureChanged = !sameKeys(next.jobs);\n state = next;\n jobsByKey = {};\n for (var i = 0; i < next.jobs.length; i++) jobsByKey[next.jobs[i].key] = next.jobs[i];\n\n if (structureChanged) { buildRows(next.jobs); buildLanes(next.jobs); built = true; }\n paintRows(next.jobs);\n paintTimeline();\n renderStats();\n setEngineChip();\n if (openKey) paintDrawer(openKey);\n })\n .catch(function () { /* the poll below retries */ });\n }\n\n // ── Drawer ─────────────────────────────────────────────────────────────────\n function openDrawer(key) {\n if (!jobsByKey[key]) return;\n openKey = key;\n lastFocus = document.activeElement;\n el(\"overlay\").hidden = false;\n el(\"overlay\").classList.add(\"open\");\n paintDrawer(key);\n el(\"drawer-close\").focus();\n }\n\n function closeDrawer() {\n openKey = null;\n el(\"overlay\").classList.remove(\"open\");\n el(\"overlay\").hidden = true;\n if (lastFocus && lastFocus.focus) lastFocus.focus();\n }\n\n function runLine(run) {\n var li = document.createElement(\"li\");\n var wrap = document.createElement(\"div\");\n wrap.className = \"runline\";\n\n var row1 = document.createElement(\"div\");\n row1.className = \"row1\";\n var left = document.createElement(\"span\");\n left.appendChild(badge(run.status));\n var when = document.createElement(\"span\");\n when.className = \"meta\";\n when.textContent = \" \" + localTime(new Date(run.startedAt).toISOString());\n left.appendChild(when);\n var right = document.createElement(\"span\");\n right.className = \"meta\";\n right.textContent = fmtDuration(run.durationMs) + (run.attempts > 1 ? \" \\\\u00b7 \" + run.attempts + \" attempts\" : \"\");\n row1.appendChild(left); row1.appendChild(right);\n wrap.appendChild(row1);\n\n if (run.error) {\n var pre = document.createElement(\"pre\");\n pre.className = \"err\"; pre.textContent = run.error;\n wrap.appendChild(pre);\n } else if (run.result !== undefined && run.result !== null) {\n var pre2 = document.createElement(\"pre\");\n try { pre2.textContent = JSON.stringify(run.result, null, 2); }\n catch (e) { pre2.textContent = String(run.result); }\n wrap.appendChild(pre2);\n }\n\n li.appendChild(wrap);\n li.style.display = \"block\";\n return li;\n }\n\n function paintDrawer(key) {\n var job = jobsByKey[key];\n if (!job) { closeDrawer(); return; }\n setText(el(\"drawer-title\"), key);\n\n var body = el(\"drawer-body\");\n body.textContent = \"\";\n\n function kv(label, valueNode) {\n var d = document.createElement(\"div\");\n d.className = \"kv\";\n var l = document.createElement(\"span\"); l.textContent = label;\n d.appendChild(l); d.appendChild(valueNode);\n body.appendChild(d);\n }\n function textNode(t) { var s = document.createElement(\"span\"); s.textContent = t; return s; }\n function codeNode(t) { var s = document.createElement(\"code\"); s.textContent = t; return s; }\n\n kv(\"Schedule\", codeNode(job.schedule));\n kv(\"Time zone\", textNode(job.timeZone));\n if (job.description) kv(\"Description\", textNode(job.description));\n kv(\"Status\", job.running ? badge(\"running\") : badge(job.lastRun ? job.lastRun.status : \"\"));\n\n var t1 = document.createElement(\"div\");\n t1.className = \"section-title\"; t1.textContent = \"Next fire times\";\n body.appendChild(t1);\n\n var ups = job.upcoming || [];\n if (ups.length) {\n var ul = document.createElement(\"ul\");\n ul.className = \"plain\";\n for (var i = 0; i < ups.length && i < 8; i++) {\n var li = document.createElement(\"li\");\n var a = document.createElement(\"span\"); a.textContent = localTime(ups[i]);\n var b = document.createElement(\"span\"); b.className = \"meta num\"; b.textContent = countdown(ups[i]);\n li.appendChild(a); li.appendChild(b);\n ul.appendChild(li);\n }\n body.appendChild(ul);\n } else {\n var e1 = document.createElement(\"div\");\n e1.className = \"empty\"; e1.textContent = \"No upcoming fires for this expression.\";\n body.appendChild(e1);\n }\n\n var t2 = document.createElement(\"div\");\n t2.className = \"section-title\"; t2.textContent = \"Recent runs\";\n body.appendChild(t2);\n\n var mine = [];\n for (var r = 0; r < state.runs.length; r++) if (state.runs[r].key === key) mine.push(state.runs[r]);\n if (mine.length) {\n var ul2 = document.createElement(\"ul\");\n ul2.className = \"plain\";\n for (var m = 0; m < mine.length && m < 25; m++) ul2.appendChild(runLine(mine[m]));\n body.appendChild(ul2);\n } else {\n var e2 = document.createElement(\"div\");\n e2.className = \"empty\"; e2.textContent = \"No runs yet in this session.\";\n body.appendChild(e2);\n }\n }\n\n function runNow(key, btn) {\n var label = btn.textContent;\n btn.disabled = true; btn.textContent = \"Running\\\\u2026\";\n fetch(\"/api/trigger/\" + encodeURIComponent(key), { method: \"POST\", headers: { \"content-type\": \"application/json\" } })\n .then(function (r) { return r.json(); })\n .then(function () { btn.textContent = \"Ran\"; scheduleRefresh(0); })\n .catch(function () { btn.textContent = \"Failed\"; })\n .then(function () {\n setTimeout(function () { btn.disabled = false; btn.textContent = label; }, 1200);\n });\n }\n\n el(\"drawer-close\").addEventListener(\"click\", closeDrawer);\n el(\"drawer-run\").addEventListener(\"click\", function () { if (openKey) runNow(openKey, this); });\n el(\"overlay\").addEventListener(\"click\", function (e) { if (e.target === el(\"overlay\")) closeDrawer(); });\n document.addEventListener(\"keydown\", function (e) {\n if (e.key === \"Escape\" && openKey) closeDrawer();\n });\n\n // Row interactions are delegated, so rebuilding the table never leaks listeners.\n el(\"jobs\").addEventListener(\"click\", function (e) {\n var btn = e.target.closest ? e.target.closest(\"button[data-key]\") : null;\n if (btn) { e.stopPropagation(); runNow(btn.dataset.key, btn); return; }\n var tr = e.target.closest ? e.target.closest(\"tr.job\") : null;\n if (tr) openDrawer(tr.dataset.key);\n });\n el(\"jobs\").addEventListener(\"keydown\", function (e) {\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n var tr = e.target.closest ? e.target.closest(\"tr.job\") : null;\n if (tr) { e.preventDefault(); openDrawer(tr.dataset.key); }\n });\n el(\"tl-gutter\").addEventListener(\"click\", function (e) {\n var label = e.target.closest ? e.target.closest(\".lane-label\") : null;\n if (label) openDrawer(label.textContent);\n });\n\n // ── Boot ───────────────────────────────────────────────────────────────────\n refresh();\n connect();\n setInterval(tickCountdowns, 1000);\n setInterval(slideTimeline, 1000);\n setInterval(function () { scheduleRefresh(0); }, REFRESH_MS);\n})();\n</script>\n</body>\n</html>`;\n","/**\n * The **local dashboard** — a tiny `node:http` server (zero runtime dependencies) that observes a\n * running {@link LocalEngine} and renders it in a branded single-page UI. The engine stays the only\n * source of truth for scheduling; the dashboard only *reads* it (snapshot / history / live events)\n * and offers exactly one write path: a manual \"run now\" trigger.\n *\n * It is a developer tool, not a public server: it binds to `127.0.0.1` by default, never `0.0.0.0`,\n * speaks only to same-origin callers for mutations, makes no outbound network calls, and sends no\n * telemetry. Start it with {@link startDashboard}, or via `app.dev({ dashboard: true })` /\n * `cronvello dev --dashboard`.\n */\nimport http from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport type { LocalEngine } from \"./engine.js\";\nimport { previewSchedule } from \"../internal/cron-schedule.js\";\nimport { DASHBOARD_HTML } from \"./dashboard-assets.js\";\n\nexport interface DashboardOptions {\n /** Port to listen on. Default `4747`. Use `0` to let the OS pick a free port (handy in tests). */\n port?: number;\n /** Host/interface to bind. Default `127.0.0.1` — keep it loopback; this is not a public server. */\n host?: string;\n}\n\nexport interface DashboardHandle {\n /** The local URL the dashboard is reachable at, e.g. `http://127.0.0.1:4747`. */\n url: string;\n /** The actual port bound (resolved even when `port: 0` was requested). */\n port: number;\n /** Stop the server and drop every live SSE connection. Idempotent. */\n close(): Promise<void>;\n}\n\nconst DEFAULT_PORT = 4747;\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst HEARTBEAT_MS = 15_000;\nconst MAX_PREVIEW = 50;\n\n/**\n * Start the dashboard server for an engine. Resolves once it is listening; rejects with a clear\n * message if the port is already in use. Bind defaults to loopback.\n */\nexport function startDashboard(engine: LocalEngine, options: DashboardOptions = {}): Promise<DashboardHandle> {\n const host = options.host ?? DEFAULT_HOST;\n const port = options.port ?? DEFAULT_PORT;\n const sseClients = new Set<http.ServerResponse>();\n\n const server = http.createServer((req, res) => handleRequest(engine, sseClients, req, res));\n\n return new Promise<DashboardHandle>((resolve, reject) => {\n const onError = (err: NodeJS.ErrnoException): void => {\n server.removeListener(\"error\", onError);\n if (err.code === \"EADDRINUSE\") {\n reject(new Error(`Cronvello dashboard: port ${port} on ${host} is already in use — pass a different --port.`));\n } else {\n reject(err);\n }\n };\n server.once(\"error\", onError);\n\n server.listen(port, host, () => {\n server.removeListener(\"error\", onError);\n const actualPort = (server.address() as AddressInfo).port;\n const shown = host === \"0.0.0.0\" || host === \"::\" ? \"127.0.0.1\" : host;\n const url = `http://${shown}:${actualPort}`;\n\n let closed = false;\n const close = (): Promise<void> => {\n if (closed) return Promise.resolve();\n closed = true;\n for (const client of sseClients) client.end();\n sseClients.clear();\n return new Promise<void>((res2) => {\n // closeAllConnections (Node ≥18.2) drops lingering keep-alive sockets so this resolves\n // promptly instead of waiting on idle connections.\n server.closeAllConnections?.();\n server.close(() => res2());\n });\n };\n\n resolve({ url, port: actualPort, close });\n });\n });\n}\n\nfunction handleRequest(\n engine: LocalEngine,\n sseClients: Set<http.ServerResponse>,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): void {\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n const path = url.pathname;\n const method = req.method ?? \"GET\";\n\n // Landing page.\n if (method === \"GET\" && path === \"/\") {\n return sendHtml(res, DASHBOARD_HTML);\n }\n\n // Live event stream (Server-Sent Events).\n if (method === \"GET\" && path === \"/api/events\") {\n return openEventStream(engine, sseClients, req, res);\n }\n\n // Health.\n if (method === \"GET\" && path === \"/api/health\") {\n return sendJson(res, 200, {\n ok: true,\n jobs: engine.jobs().length,\n activeRuns: engine.activeRuns,\n running: engine.running,\n startedAt: engine.startedAt,\n });\n }\n\n // Everything the UI needs for a full repaint, in one round-trip. The dashboard polls this as a\n // reconciliation net behind the live event stream, so a second request per refresh would double\n // the cost of the thing that runs most often.\n if (method === \"GET\" && path === \"/api/state\") {\n const runs = engine.runs();\n const lastByKey = new Map<string, ReturnType<typeof engine.runs>[number]>();\n for (const run of runs) if (!lastByKey.has(run.key)) lastByKey.set(run.key, run);\n const upcomingCount = clampCount(url.searchParams.get(\"upcoming\"));\n return sendJson(res, 200, {\n engine: {\n running: engine.running,\n startedAt: engine.startedAt,\n activeRuns: engine.activeRuns,\n now: Date.now(),\n },\n jobs: engine.snapshot().map((j) => ({\n key: j.key,\n schedule: j.schedule,\n timeZone: j.timeZone,\n description: j.description ?? null,\n nextFire: j.nextFire ? j.nextFire.toISOString() : null,\n running: j.running,\n lastRun: lastByKey.get(j.key) ?? null,\n upcoming: upcoming(j.schedule, j.timeZone, upcomingCount),\n })),\n runs,\n });\n }\n\n // Run history as NDJSON (check before the `/api/runs` prefix).\n if (method === \"GET\" && path === \"/api/runs.ndjson\") {\n res.writeHead(200, { \"content-type\": \"application/x-ndjson; charset=utf-8\", \"cache-control\": \"no-store\" });\n const body = engine.toNdjson();\n return void res.end(body.length ? body + \"\\n\" : \"\");\n }\n\n // Run history (all, or `?key=`).\n if (method === \"GET\" && path === \"/api/runs\") {\n const key = url.searchParams.get(\"key\");\n return sendJson(res, 200, key ? engine.runsFor(key) : engine.runs());\n }\n\n // Run history for one job.\n if (method === \"GET\" && path.startsWith(\"/api/runs/\")) {\n return sendJson(res, 200, engine.runsFor(decodeKey(path, \"/api/runs/\")));\n }\n\n // Upcoming fire times for one job.\n if (method === \"GET\" && path.startsWith(\"/api/preview/\")) {\n const key = decodeKey(path, \"/api/preview/\");\n const job = engine.snapshot().find((j) => j.key === key);\n if (!job) return sendJson(res, 404, { error: `unknown job '${key}'` });\n const n = clampCount(url.searchParams.get(\"n\"));\n try {\n const fires = previewSchedule(job.schedule, { timeZone: job.timeZone, count: n });\n return sendJson(res, 200, fires.map((d) => d.toISOString()));\n } catch {\n return sendJson(res, 200, []); // an unschedulable expression simply has no upcoming fires\n }\n }\n\n // Snapshot of all jobs.\n if (method === \"GET\" && path === \"/api/jobs\") {\n const jobs = engine.snapshot().map((j) => ({\n key: j.key,\n schedule: j.schedule,\n timeZone: j.timeZone,\n description: j.description,\n nextFire: j.nextFire ? j.nextFire.toISOString() : null,\n running: j.running,\n }));\n return sendJson(res, 200, jobs);\n }\n\n // Manual trigger — the one mutating path. Guard against cross-origin POSTs.\n if (method === \"POST\" && path.startsWith(\"/api/trigger/\")) {\n if (!isSameOrigin(req)) return sendJson(res, 403, { error: \"cross-origin request rejected\" });\n const key = decodeKey(path, \"/api/trigger/\");\n return void engine\n .trigger(key)\n .then((record) => sendJson(res, 200, record))\n .catch((err: Error) => {\n const status = /unknown job/.test(err.message) ? 404 : 400;\n sendJson(res, status, { error: err.message });\n });\n }\n\n sendJson(res, 404, { error: \"not found\" });\n}\n\n/** Open an SSE stream that forwards every engine event until the client disconnects. */\nfunction openEventStream(\n engine: LocalEngine,\n sseClients: Set<http.ServerResponse>,\n req: http.IncomingMessage,\n res: http.ServerResponse,\n): void {\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-store\",\n connection: \"keep-alive\",\n \"x-accel-buffering\": \"no\",\n });\n res.write(\": connected\\n\\n\");\n sseClients.add(res);\n\n const unsubscribe = engine.subscribe((event) => {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n });\n // Heartbeat comment keeps proxies from idling the connection out.\n const heartbeat = setInterval(() => res.write(\": ping\\n\\n\"), HEARTBEAT_MS);\n if (typeof heartbeat.unref === \"function\") heartbeat.unref();\n\n const cleanup = (): void => {\n clearInterval(heartbeat);\n unsubscribe();\n sseClients.delete(res);\n };\n res.on(\"close\", cleanup);\n req.on(\"close\", cleanup);\n}\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\nfunction sendJson(res: http.ServerResponse, status: number, body: unknown): void {\n const payload = JSON.stringify(body);\n res.writeHead(status, { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\" });\n res.end(payload);\n}\n\nfunction sendHtml(res: http.ServerResponse, html: string): void {\n res.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" });\n res.end(html);\n}\n\nfunction decodeKey(path: string, prefix: string): string {\n return decodeURIComponent(path.slice(prefix.length));\n}\n\n/**\n * The next `count` fire times of a schedule, as ISO strings. An expression the previewer can't\n * resolve (`@reboot`, or a typo that slipped past define-time validation) simply has no upcoming\n * fires — that is a display fact, not an error worth failing the whole state request over.\n */\nfunction upcoming(schedule: string, timeZone: string, count: number): string[] {\n try {\n return previewSchedule(schedule, { timeZone, count }).map((d) => d.toISOString());\n } catch {\n return [];\n }\n}\n\nfunction clampCount(raw: string | null): number {\n const n = raw ? Number.parseInt(raw, 10) : 5;\n if (!Number.isFinite(n) || n < 1) return 5;\n return Math.min(n, MAX_PREVIEW);\n}\n\n/**\n * Reject a mutating request whose `Origin` points at a different host than the one it was sent to.\n * Loopback binding is the primary defence; this stops a page on another local origin from POSTing.\n */\nfunction isSameOrigin(req: http.IncomingMessage): boolean {\n const origin = req.headers.origin;\n if (!origin) return true; // non-browser clients (curl, tests) send no Origin\n try {\n return new URL(origin).host === req.headers.host;\n } catch {\n return false;\n }\n}\n","/**\n * Error taxonomy for the SDK. Everything thrown by the public surface is a\n * `CronvelloError` (or subclass), so callers can `catch (e) { if (e instanceof CronvelloError) … }`.\n */\n\nexport class CronvelloError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CronvelloError\";\n // Restore prototype chain for instanceof across transpilation targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** A non-2xx response from the Cronvello API. */\nexport class CronvelloApiError extends CronvelloError {\n /** HTTP status code. */\n readonly status: number;\n /** Machine-readable error code from the API body, when present. */\n readonly code: string | undefined;\n /** The method + path that failed, e.g. `POST /v1/jobs`. */\n readonly endpoint: string;\n /** Parsed response body (best effort). */\n readonly body: unknown;\n /** Seconds to wait before retrying, parsed from `Retry-After` / rate-limit payload (429 only). */\n readonly retryAfterSeconds: number | undefined;\n\n constructor(args: {\n status: number;\n endpoint: string;\n message: string;\n code?: string;\n body?: unknown;\n retryAfterSeconds?: number;\n }) {\n super(`[${args.status}] ${args.endpoint}: ${args.message}`);\n this.name = \"CronvelloApiError\";\n this.status = args.status;\n this.code = args.code;\n this.endpoint = args.endpoint;\n this.body = args.body;\n this.retryAfterSeconds = args.retryAfterSeconds;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n get isNotFound(): boolean {\n return this.status === 404;\n }\n}\n\n/** A network/transport failure (DNS, connection reset, timeout) before any HTTP status. */\nexport class CronvelloNetworkError extends CronvelloError {\n readonly endpoint: string;\n override readonly cause: unknown;\n constructor(endpoint: string, cause: unknown) {\n super(`Network error calling ${endpoint}: ${describe(cause)}`);\n this.name = \"CronvelloNetworkError\";\n this.endpoint = endpoint;\n this.cause = cause;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** A misconfiguration caught before any network call (missing apiKey, bad URL, …). */\nexport class CronvelloConfigError extends CronvelloError {\n constructor(message: string) {\n super(message);\n this.name = \"CronvelloConfigError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nfunction describe(cause: unknown): string {\n if (cause instanceof Error) return cause.message;\n return String(cause);\n}\n","/**\n * Minimal HTTP transport over the global `fetch` (Node 20+). No axios, no node-fetch —\n * zero runtime dependencies. Adds bearer auth, JSON (de)serialization, typed error mapping,\n * bounded retries with backoff for transient failures, and optional idempotency keys.\n */\n\nimport {\n CronvelloApiError,\n CronvelloConfigError,\n CronvelloNetworkError,\n} from \"./errors.js\";\n\nexport type FetchLike = (\n input: string,\n init?: {\n method?: string;\n headers?: Record<string, string>;\n body?: string;\n signal?: AbortSignal;\n },\n) => Promise<{\n ok: boolean;\n status: number;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}>;\n\nexport interface TransportOptions {\n baseUrl: string;\n apiKey: string;\n /** Per-request timeout in ms. Default 30_000. */\n timeoutMs?: number;\n /** Max retry attempts for 429/5xx/network errors. Default 2 (=> up to 3 tries). */\n maxRetries?: number;\n /** Override the fetch implementation (testing / custom agents). */\n fetch?: FetchLike;\n /** Extra headers sent on every request (e.g. a custom User-Agent). */\n defaultHeaders?: Record<string, string>;\n /** Telemetry hook — called once per completed attempt. */\n onRequest?: (info: { method: string; path: string; status: number; attempt: number; durationMs: number }) => void;\n}\n\nexport interface RequestOptions {\n method: string;\n path: string;\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n /** Idempotency-Key header value — replays of the same key are de-duplicated server-side. */\n idempotencyKey?: string;\n signal?: AbortSignal;\n}\n\nconst RETRYABLE_STATUS = new Set([429, 500, 502, 503, 504]);\n\nexport class Transport {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeoutMs: number;\n private readonly maxRetries: number;\n private readonly fetchImpl: FetchLike;\n private readonly defaultHeaders: Record<string, string>;\n private readonly onRequest: TransportOptions[\"onRequest\"];\n\n constructor(opts: TransportOptions) {\n if (!opts.apiKey) throw new CronvelloConfigError(\"apiKey is required\");\n if (!opts.baseUrl) throw new CronvelloConfigError(\"baseUrl is required\");\n const resolvedFetch = opts.fetch ?? (globalThis.fetch as unknown as FetchLike | undefined);\n if (!resolvedFetch) {\n throw new CronvelloConfigError(\n \"No global fetch found. Use Node 20+ or pass a `fetch` implementation in the client options.\",\n );\n }\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n this.maxRetries = opts.maxRetries ?? 2;\n this.fetchImpl = resolvedFetch;\n this.defaultHeaders = opts.defaultHeaders ?? {};\n this.onRequest = opts.onRequest;\n }\n\n async request<T>(opts: RequestOptions): Promise<T> {\n const url = this.buildUrl(opts.path, opts.query);\n const endpoint = `${opts.method} ${opts.path}`;\n const headers: Record<string, string> = {\n authorization: `Bearer ${this.apiKey}`,\n accept: \"application/json\",\n ...this.defaultHeaders,\n };\n let payload: string | undefined;\n if (opts.body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n payload = JSON.stringify(opts.body);\n }\n if (opts.idempotencyKey) headers[\"idempotency-key\"] = opts.idempotencyKey;\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const startedAt = Date.now();\n const { signal, cancel } = this.withTimeout(opts.signal);\n try {\n const res = await this.fetchImpl(url, {\n method: opts.method,\n headers,\n ...(payload !== undefined ? { body: payload } : {}),\n signal,\n });\n cancel();\n const durationMs = Date.now() - startedAt;\n this.onRequest?.({ method: opts.method, path: opts.path, status: res.status, attempt, durationMs });\n\n const text = await res.text();\n const parsed = text ? safeJson(text) : null;\n\n if (res.ok) return unwrapEnvelope(parsed) as T;\n\n const retryAfter = parseRetryAfter(res, parsed);\n if (RETRYABLE_STATUS.has(res.status) && attempt < this.maxRetries) {\n await sleep(this.backoff(attempt, retryAfter));\n continue;\n }\n throw new CronvelloApiError({\n status: res.status,\n endpoint,\n message: extractMessage(parsed) ?? `Request failed`,\n code: extractCode(parsed),\n body: parsed,\n ...(retryAfter !== undefined ? { retryAfterSeconds: retryAfter } : {}),\n });\n } catch (err) {\n cancel();\n if (err instanceof CronvelloApiError) throw err;\n // Network/abort error — retry if attempts remain.\n lastError = err;\n if (attempt < this.maxRetries) {\n await sleep(this.backoff(attempt));\n continue;\n }\n throw new CronvelloNetworkError(endpoint, err);\n }\n }\n // Unreachable, but satisfies the type checker.\n throw new CronvelloNetworkError(endpoint, lastError);\n }\n\n private buildUrl(path: string, query?: RequestOptions[\"query\"]): string {\n const base = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n if (!query) return base;\n const params = Object.entries(query)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n return params.length ? `${base}?${params.join(\"&\")}` : base;\n }\n\n private withTimeout(external?: AbortSignal): { signal: AbortSignal; cancel: () => void } {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n const onExternalAbort = () => controller.abort();\n if (external) {\n if (external.aborted) controller.abort();\n else external.addEventListener(\"abort\", onExternalAbort, { once: true });\n }\n return {\n signal: controller.signal,\n cancel: () => {\n clearTimeout(timer);\n external?.removeEventListener(\"abort\", onExternalAbort);\n },\n };\n }\n\n private backoff(attempt: number, retryAfterSeconds?: number): number {\n if (retryAfterSeconds !== undefined) return Math.min(retryAfterSeconds * 1000, 30_000);\n // Exponential backoff with full jitter: base 300ms, capped at 5s.\n const base = Math.min(300 * 2 ** attempt, 5_000);\n return Math.floor(Math.random() * base);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\n/**\n * The Cronvello server wraps every successful `/v1` response in a `{ success, message, data }`\n * envelope, while the typed client methods are declared in terms of the inner payload. Unwrap\n * it here — centrally — so every resource method (and the high-level `sync()`) sees the data it\n * expects. Bodies that aren't enveloped (no boolean `success` + `data`) pass through unchanged,\n * so non-enveloped or future endpoints keep working.\n */\nfunction unwrapEnvelope(body: unknown): unknown {\n if (\n body !== null &&\n typeof body === \"object\" &&\n \"success\" in body &&\n typeof (body as { success: unknown }).success === \"boolean\" &&\n \"data\" in body\n ) {\n return (body as { data: unknown }).data;\n }\n return body;\n}\n\nfunction extractMessage(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"message\" in body) {\n const m = (body as { message?: unknown }).message;\n if (typeof m === \"string\") return m;\n }\n return undefined;\n}\n\nfunction extractCode(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"code\" in body) {\n const c = (body as { code?: unknown }).code;\n if (typeof c === \"string\") return c;\n }\n return undefined;\n}\n\nfunction parseRetryAfter(\n res: { headers: { get(name: string): string | null } },\n body: unknown,\n): number | undefined {\n const header = res.headers.get(\"retry-after\");\n if (header) {\n const n = Number(header);\n if (Number.isFinite(n)) return n;\n }\n if (body && typeof body === \"object\" && \"data\" in body) {\n const data = (body as { data?: { retryAfterSeconds?: unknown } }).data;\n if (data && typeof data.retryAfterSeconds === \"number\") return data.retryAfterSeconds;\n }\n return undefined;\n}\n","/**\n * Low-level, fully-typed client for the Cronvello public `/v1` API.\n *\n * This is the thin REST layer: one method per endpoint, request/response types straight\n * from the server contract. The high-level registry (`defineCronvello`) is built on top of\n * it. Use this directly when you need ad-hoc control beyond the registry model.\n */\n\nimport { Transport, type FetchLike } from \"../internal/http.js\";\nimport { CronvelloConfigError } from \"../internal/errors.js\";\nimport type {\n AccountRunsQuery,\n AccountTasksQuery,\n JobCreateBody,\n JobUpdateBody,\n MeResponse,\n PublicJob,\n PublicRun,\n PublicTask,\n RunNowResult,\n RegistryReconcileRequest,\n RegistryReconcileResponse,\n RunsPage,\n RunsQuery,\n TaskCreateBody,\n TasksPage,\n TaskUpdateBody,\n UsageResponse,\n} from \"../internal/wire.js\";\n\n/** The production Cronvello API. Override `baseUrl` only for self-hosting or testing. */\nexport const CRONVELLO_DEFAULT_BASE_URL = \"https://api.cronvello.com\";\n\nexport interface CronvelloClientOptions {\n /** Account API key (`crn_live_…`). Required. */\n apiKey: string;\n /** API base URL. Defaults to https://api.cronvello.com. */\n baseUrl?: string;\n /** Per-request timeout in ms (default 30_000). */\n timeoutMs?: number;\n /** Retry attempts for 429/5xx/network errors (default 2). */\n maxRetries?: number;\n /** Custom fetch implementation (default: global fetch). */\n fetch?: FetchLike;\n /** Telemetry hook for every request attempt. */\n onRequest?: (info: { method: string; path: string; status: number; attempt: number; durationMs: number }) => void;\n}\n\nexport class CronvelloClient {\n private readonly transport: Transport;\n /** The resolved base URL in use. */\n readonly baseUrl: string;\n\n /** Job container operations. */\n readonly jobs: JobsResource;\n /** Scheduled task operations. */\n readonly tasks: TasksResource;\n /** Execution-history (run) operations. */\n readonly runs: RunsResource;\n /** Account identity + usage. */\n readonly account: AccountResource;\n\n constructor(options: CronvelloClientOptions) {\n if (!options || !options.apiKey) {\n throw new CronvelloConfigError(\"CronvelloClient requires an `apiKey` (crn_live_…).\");\n }\n this.baseUrl = (options.baseUrl ?? CRONVELLO_DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.transport = new Transport({\n baseUrl: this.baseUrl,\n apiKey: options.apiKey,\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n ...(options.maxRetries !== undefined ? { maxRetries: options.maxRetries } : {}),\n ...(options.fetch ? { fetch: options.fetch } : {}),\n ...(options.onRequest ? { onRequest: options.onRequest } : {}),\n defaultHeaders: { \"user-agent\": \"cronvello-sdk\" },\n });\n this.jobs = new JobsResource(this.transport);\n this.tasks = new TasksResource(this.transport);\n this.runs = new RunsResource(this.transport);\n this.account = new AccountResource(this.transport);\n }\n\n /**\n * Atomically reconcile a whole code registry server-side (`PUT /v1/registry`): one job\n * container + its tasks, created/updated/pruned/started in a single call. This is what\n * `defineCronvello().sync()` prefers; the high-level API builds the body for you.\n */\n reconcileRegistry(body: RegistryReconcileRequest, opts?: { idempotencyKey?: string }): Promise<RegistryReconcileResponse> {\n return this.transport.request({\n method: \"PUT\",\n path: \"/v1/registry\",\n body,\n ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),\n });\n }\n\n /**\n * Escape hatch for endpoints not yet wrapped by a typed method (heartbeat monitors,\n * maintenance windows, DLQ, notification channels, audit log, API-key self-service …).\n * `T` is the response shape you expect.\n */\n request<T>(method: string, path: string, opts?: { query?: Record<string, string | number | boolean | undefined>; body?: unknown; idempotencyKey?: string }): Promise<T> {\n return this.transport.request<T>({\n method,\n path,\n ...(opts?.query ? { query: opts.query } : {}),\n ...(opts?.body !== undefined ? { body: opts.body } : {}),\n ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),\n });\n }\n}\n\nclass JobsResource {\n constructor(private readonly t: Transport) {}\n\n list(): Promise<PublicJob[]> {\n return this.t.request({ method: \"GET\", path: \"/v1/jobs\" });\n }\n get(jobId: string): Promise<PublicJob> {\n return this.t.request({ method: \"GET\", path: `/v1/jobs/${enc(jobId)}` });\n }\n create(body: JobCreateBody, opts?: { idempotencyKey?: string }): Promise<PublicJob> {\n return this.t.request({ method: \"POST\", path: \"/v1/jobs\", body, ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}) });\n }\n update(jobId: string, body: JobUpdateBody): Promise<PublicJob> {\n return this.t.request({ method: \"PATCH\", path: `/v1/jobs/${enc(jobId)}`, body });\n }\n delete(jobId: string): Promise<null> {\n return this.t.request({ method: \"DELETE\", path: `/v1/jobs/${enc(jobId)}` });\n }\n start(jobId: string): Promise<PublicJob> {\n return this.t.request({ method: \"POST\", path: `/v1/jobs/${enc(jobId)}/start` });\n }\n stop(jobId: string): Promise<PublicJob> {\n return this.t.request({ method: \"POST\", path: `/v1/jobs/${enc(jobId)}/stop` });\n }\n listTasks(jobId: string): Promise<PublicTask[]> {\n return this.t.request({ method: \"GET\", path: `/v1/jobs/${enc(jobId)}/tasks` });\n }\n createTask(jobId: string, body: TaskCreateBody, opts?: { idempotencyKey?: string }): Promise<PublicTask> {\n return this.t.request({ method: \"POST\", path: `/v1/jobs/${enc(jobId)}/tasks`, body, ...(opts?.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}) });\n }\n}\n\nclass TasksResource {\n constructor(private readonly t: Transport) {}\n\n /** Account-wide paginated task table. */\n list(query?: AccountTasksQuery): Promise<TasksPage> {\n return this.t.request({ method: \"GET\", path: \"/v1/tasks\", ...(query ? { query: query as Record<string, string | number | boolean | undefined> } : {}) });\n }\n get(taskId: string): Promise<PublicTask> {\n return this.t.request({ method: \"GET\", path: `/v1/tasks/${enc(taskId)}` });\n }\n update(taskId: string, body: TaskUpdateBody): Promise<PublicTask> {\n return this.t.request({ method: \"PATCH\", path: `/v1/tasks/${enc(taskId)}`, body });\n }\n delete(taskId: string): Promise<null> {\n return this.t.request({ method: \"DELETE\", path: `/v1/tasks/${enc(taskId)}` });\n }\n start(taskId: string): Promise<PublicTask> {\n return this.t.request({ method: \"POST\", path: `/v1/tasks/${enc(taskId)}/start` });\n }\n stop(taskId: string): Promise<PublicTask> {\n return this.t.request({ method: \"POST\", path: `/v1/tasks/${enc(taskId)}/stop` });\n }\n /** Trigger a one-off manual execution (does not change the schedule). */\n runNow(taskId: string): Promise<RunNowResult> {\n return this.t.request({ method: \"POST\", path: `/v1/tasks/${enc(taskId)}/run` });\n }\n listRuns(taskId: string, query?: RunsQuery): Promise<RunsPage> {\n return this.t.request({ method: \"GET\", path: `/v1/tasks/${enc(taskId)}/runs`, ...(query ? { query: query as Record<string, string | number | boolean | undefined> } : {}) });\n }\n}\n\nclass RunsResource {\n constructor(private readonly t: Transport) {}\n\n /** Account-wide paginated activity feed. */\n list(query?: AccountRunsQuery): Promise<RunsPage> {\n return this.t.request({ method: \"GET\", path: \"/v1/runs\", ...(query ? { query: query as Record<string, string | number | boolean | undefined> } : {}) });\n }\n get(runId: string): Promise<PublicRun> {\n return this.t.request({ method: \"GET\", path: `/v1/runs/${enc(runId)}` });\n }\n}\n\nclass AccountResource {\n constructor(private readonly t: Transport) {}\n\n me(): Promise<MeResponse> {\n return this.t.request({ method: \"GET\", path: \"/v1/me\" });\n }\n usage(): Promise<UsageResponse> {\n return this.t.request({ method: \"GET\", path: \"/v1/usage\" });\n }\n}\n\nfunction enc(segment: string): string {\n return encodeURIComponent(segment);\n}\n","/**\n * Render a `ReconcileResult` as a clean, human-readable summary — for boot logs, CI output, and\n * `npx cronvello sync`. Zero-dependency ANSI colouring, opt-in via `color: true`.\n */\n\nimport type { ReconcileResult, ReconcileTaskChange } from \"./types.js\";\n\nexport interface FormatOptions {\n /** Emit ANSI colour codes (default false — safe for log files). */\n color?: boolean;\n /** Label the summary as a preview (\"would …\") rather than an applied change. */\n dryRun?: boolean;\n}\n\nconst ESC = String.fromCharCode(27); // ANSI escape\nconst ANSI = {\n reset: `${ESC}[0m`,\n dim: `${ESC}[2m`,\n bold: `${ESC}[1m`,\n green: `${ESC}[32m`,\n yellow: `${ESC}[33m`,\n red: `${ESC}[31m`,\n cyan: `${ESC}[36m`,\n gray: `${ESC}[90m`,\n} as const;\n\ntype Color = keyof typeof ANSI;\n\nconst GLYPH: Record<ReconcileTaskChange[\"action\"], { sign: string; color: Color }> = {\n created: { sign: \"+\", color: \"green\" },\n updated: { sign: \"~\", color: \"yellow\" },\n unchanged: { sign: \"=\", color: \"gray\" },\n deleted: { sign: \"-\", color: \"red\" },\n skipped: { sign: \"·\", color: \"cyan\" },\n};\n\n/** Build the multi-line summary string. */\nexport function formatSyncResult(result: ReconcileResult, options: FormatOptions = {}): string {\n const paint = (s: string, c: Color) => (options.color ? `${ANSI[c]}${s}${ANSI.reset}` : s);\n const verb = options.dryRun ? \"would sync\" : \"synced\";\n const lines: string[] = [];\n\n lines.push(\n `${paint(\"Cronvello\", \"cyan\")} ${verb} ${paint(`\"${result.jobName}\"`, \"bold\")} ${paint(`(${result.jobId})`, \"gray\")}`,\n );\n\n // Per-task lines, in a stable, readable order.\n const order: ReconcileTaskChange[\"action\"][] = [\"created\", \"updated\", \"deleted\", \"skipped\", \"unchanged\"];\n const sorted = [...result.changes].sort((a, b) => order.indexOf(a.action) - order.indexOf(b.action));\n for (const c of sorted) {\n const g = GLYPH[c.action];\n const detail =\n c.changedFields && c.changedFields.length\n ? paint(` (${c.changedFields.join(\", \")})`, \"gray\")\n : c.reason\n ? paint(` (${c.reason})`, \"gray\")\n : \"\";\n lines.push(` ${paint(g.sign, g.color)} ${paint(c.action.padEnd(9), g.color)} ${c.key}${detail}`);\n }\n\n const tally = [\n result.created && `${result.created} created`,\n result.updated && `${result.updated} updated`,\n result.unchanged && `${result.unchanged} unchanged`,\n result.deleted && `${result.deleted} deleted`,\n result.skipped && `${result.skipped} skipped`,\n ].filter(Boolean);\n const summary = tally.length ? tally.join(\", \") : \"no changes\";\n const containerNote = result.jobCreated ? paint(\" · container created\", \"gray\") : \"\";\n lines.push(` ${paint(summary, \"bold\")}${containerNote}`);\n\n return lines.join(\"\\n\");\n}\n","/**\n * @cronvello/sdk — code-first cron jobs for Cronvello.\n *\n * Two layers, one package:\n * • High-level registry: `defineCronvello({ jobs })` → `.sync()` + `.expressHandler()` / `.nextHandler()`.\n * Define jobs in code; the SDK reconciles them to https://api.cronvello.com and runs them.\n * • Low-level client: `new CronvelloClient({ apiKey })` → typed access to the whole `/v1` API.\n *\n * Plus an operator surface, `new CronvelloAdminClient({ serviceKey })`, for the service that\n * registers apps into Cronvello. Separate class, separate credential — see its doc comment.\n */\n\n// ── High-level registry ────────────────────────────────────────────────────\nexport { defineCronvello, type CronvelloApp, type CronvelloEnvConfig } from \"./registry/define.js\";\nexport { formatSyncResult, type FormatOptions } from \"./registry/format.js\";\nexport type {\n CronvelloAppConfig,\n CronvelloJobConfig,\n CronvelloJobConfigWithKey,\n CronvelloJobsInput,\n CronvelloJobContext,\n CronvelloJobHandler,\n CronvelloLogger,\n CronvelloHooks,\n CronvelloRunSource,\n ReconcileResult,\n ReconcileTaskChange,\n SyncOptions,\n} from \"./registry/types.js\";\nexport type { DispatchRequest, DispatchResponse } from \"./registry/dispatch.js\";\n\n// ── Schedule builders ──────────────────────────────────────────────────────\nexport {\n cron,\n every,\n everyMinutes,\n everyHours,\n hourly,\n daily,\n weekly,\n monthly,\n weekdays,\n weekends,\n schedule,\n type Weekday,\n} from \"./schedule/index.js\";\nexport { validateCron, isValidTimeZone, type CronValidation } from \"./internal/cron.js\";\n\n// ── Schedule preview (pure, no account) ─────────────────────────────────────\n// The local engine itself lives under the `@cronvello/sdk/dev` subpath; these two pure helpers are\n// surfaced here too because reasoning about *when* a schedule fires is useful everywhere.\nexport {\n nextOccurrence,\n previewSchedule,\n type NextOccurrenceOptions,\n type PreviewOptions,\n} from \"./internal/cron-schedule.js\";\n\n// ── Low-level client ───────────────────────────────────────────────────────\nexport {\n CronvelloClient,\n CRONVELLO_DEFAULT_BASE_URL,\n type CronvelloClientOptions,\n} from \"./client/client.js\";\n\n// ── Operator client (backend-to-backend) ────────────────────────────\n// Not needed to *use* Cronvello — this is for the service that provisions apps into it.\n// It takes Cronvello's service key, deliberately a different option than the account `apiKey`.\nexport {\n CronvelloAdminClient,\n type CronvelloAdminClientOptions,\n} from \"./client/admin-client.js\";\nexport type {\n ExternalApp,\n ExternalAppAuthMethod,\n ExternalAppRegisterInput,\n ExternalAppRegisterResult,\n ExternalAppRotateKeyResult,\n ExternalAppStatus,\n CatalogRetiredReason,\n} from \"./internal/admin-wire.js\";\n\n// ── Errors ─────────────────────────────────────────────────────────────────\nexport {\n CronvelloError,\n CronvelloApiError,\n CronvelloNetworkError,\n CronvelloConfigError,\n} from \"./internal/errors.js\";\n\n// ── Wire types ─────────────────────────────────────────────────────────────\nexport type {\n Urgency,\n ExecutionMode,\n HttpMethod,\n JobStatus,\n RunStatus,\n RunType,\n CallbackStatus,\n SuccessCriteria,\n PublicJob,\n PublicTask,\n PublicRun,\n JobCreateBody,\n JobUpdateBody,\n TaskCreateBody,\n TaskUpdateBody,\n RunsPage,\n TasksPage,\n RunNowResult,\n RegistryTaskInput,\n RegistryReconcileRequest,\n RegistryReconcileResponse,\n RegistryReconcileChange,\n MeResponse,\n UsageResponse,\n Pagination,\n RunsQuery,\n AccountTasksQuery,\n AccountRunsQuery,\n} from \"./internal/wire.js\";\n\n/**\n * Generate a strong random dispatch secret (hex). Convenience for setup scripts:\n * node -e \"console.log(require('@cronvello/sdk').generateDispatchSecret())\"\n */\nexport function generateDispatchSecret(bytes = 32): string {\n const buf = new Uint8Array(bytes);\n crypto.getRandomValues(buf);\n return Array.from(buf)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n","#!/usr/bin/env node\n/**\n * The `cronvello` CLI — inspect and drive your Cronvello account from the terminal.\n *\n * cronvello whoami account, plan, limits, usage\n * cronvello list [jobName] job containers, or the tasks inside one\n * cronvello tasks [--job name] account-wide task table\n * cronvello runs [--limit n] [--status failed] recent activity feed\n * cronvello run <taskId> trigger one task now\n * cronvello run <jobName> <task> …resolved by name\n * cronvello status health overview (active tasks, open DLQ, recent failures)\n * cronvello sync [configPath] [--dry] reconcile a code registry (loads your module)\n * cronvello dev [configPath] [--dry-run] start the local engine (run jobs locally, no account)\n * cronvello preview \"<cron>\" [--tz <z>] [-n 5] print the next N fire times of an expression\n * cronvello trigger [configPath] <jobKey> run a single job's handler once, locally\n * cronvello secret generate a strong dispatch secret\n *\n * Auth comes from the environment: CRONVELLO_API_KEY (required), CRONVELLO_API_URL (optional base).\n * Global flags: --json (machine output), --no-color, -h/--help, -v/--version.\n */\n\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL, fileURLToPath } from \"node:url\";\nimport { resolve } from \"node:path\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { CronvelloClient } from \"../client/client.js\";\nimport { CronvelloApiError, CronvelloConfigError } from \"../internal/errors.js\";\nimport { formatSyncResult } from \"../registry/format.js\";\nimport { generateDispatchSecret } from \"../index.js\";\nimport type { CronvelloApp } from \"../registry/define.js\";\nimport type { EngineEvent, JobSnapshot } from \"../dev/engine.js\";\nimport { previewSchedule, upcomingFires, localTimeZone, type UpcomingFire } from \"../internal/cron-schedule.js\";\nimport type { PublicJob, PublicRun, PublicTask } from \"../internal/wire.js\";\nimport { box, brand, c, ICON, relativeTime, setColor, sym, table } from \"./ui.js\";\n\nconst require2 = createRequire(import.meta.url);\nconst VERSION: string = (() => {\n try {\n return (require2(\"../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n})();\n\ninterface Args {\n command: string;\n positionals: string[];\n flags: Record<string, string | boolean>;\n}\n\n/** Long flags that take a following value (e.g. `--limit 20`, `--tz Europe/Berlin`). */\nconst VALUE_FLAGS = [\"limit\", \"status\", \"job\", \"type\", \"runType\", \"tz\", \"window\", \"count\", \"n\", \"port\", \"host\"];\n/** Short flags that take a following value (e.g. `-n 5`). */\nconst SHORT_VALUE_FLAGS = [\"n\", \"c\"];\n\nfunction parseArgs(argv: string[]): Args {\n const positionals: string[] = [];\n const flags: Record<string, string | boolean> = {};\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i]!;\n if (a.startsWith(\"--\")) {\n const key = a.slice(2);\n const next = argv[i + 1];\n if (next !== undefined && !next.startsWith(\"-\") && VALUE_FLAGS.includes(key)) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = true;\n }\n } else if (a.startsWith(\"-\") && a.length > 1) {\n const key = a.slice(1);\n const next = argv[i + 1];\n if (next !== undefined && !next.startsWith(\"-\") && SHORT_VALUE_FLAGS.includes(key)) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = true;\n }\n } else {\n positionals.push(a);\n }\n }\n return { command: positionals[0] ?? \"\", positionals: positionals.slice(1), flags };\n}\n\nconst out = (s = \"\"): void => void process.stdout.write(s + \"\\n\");\nconst json = (v: unknown): void => out(JSON.stringify(v, null, 2));\n\nfunction makeClient(): CronvelloClient {\n const apiKey = process.env[\"CRONVELLO_API_KEY\"];\n if (!apiKey) {\n throw new CronvelloConfigError(\"CRONVELLO_API_KEY is not set. Export your crn_live_… key first.\");\n }\n const baseUrl = process.env[\"CRONVELLO_API_URL\"];\n return new CronvelloClient({ apiKey, ...(baseUrl ? { baseUrl } : {}) });\n}\n\nfunction statusColor(status: string): string {\n const s = status.toUpperCase();\n if (s === \"ACTIVE\" || s === \"COMPLETED\") return c.green(status);\n if (s === \"DISABLED\" || s === \"QUEUED\" || s === \"RUNNING\") return c.cyan(status);\n if (s.startsWith(\"ERROR\") || s === \"FAILED\") return c.red(status);\n return c.yellow(status);\n}\n\nfunction header(subtitle: string): void {\n out(`${ICON} ${brand(\"Cronvello\")} ${c.gray(subtitle)}`);\n out();\n}\n\n// ─── Commands ────────────────────────────────────────────────────────────────\n\nasync function cmdWhoami(useJson: boolean): Promise<void> {\n const me = await makeClient().account.me();\n if (useJson) return json(me);\n const u = me.usage;\n const quota = u.executionQuota == null ? \"∞\" : String(u.executionQuota);\n out(\n box(`${me.accountName}`, [\n `${c.dim(\"account\")} #${me.accountId} ${me.isActive ? sym.ok : sym.fail} ${me.email}`,\n `${c.dim(\"plan\")} ${brand(me.plan?.displayName ?? \"—\")}`,\n `${c.dim(\"limits\")} ${me.limits.maxJobs ?? \"∞\"} jobs · ${me.limits.maxTasksPerJob ?? \"∞\"} tasks/job · ${me.limits.rateLimitPerMinute ?? \"∞\"}/min`,\n `${c.dim(\"usage\")} ${c.bold(String(u.executionCount))} / ${quota} executions ${c.gray(`(${u.jobsUsed} jobs)`)}`,\n `${c.dim(\"attention\")} ${me.summary.openDlqCount} DLQ · ${me.summary.heartbeatNeedsAttention} heartbeats · ${me.summary.activeMaintenanceWindows} maintenance`,\n ]),\n );\n}\n\nasync function cmdList(jobName: string | undefined, useJson: boolean): Promise<void> {\n const client = makeClient();\n if (jobName) {\n const container = (await client.jobs.list()).find((j) => j.name === jobName);\n if (!container) throw new CronvelloConfigError(`No job container named \"${jobName}\".`);\n const tasks = await client.jobs.listTasks(container.id);\n if (useJson) return json(tasks);\n header(`tasks in \"${container.name}\"`);\n out(renderTasks(tasks));\n return;\n }\n const jobs = await client.jobs.list();\n if (useJson) return json(jobs);\n header(\"job containers\");\n out(\n table(\n [{ header: \"NAME\" }, { header: \"STATUS\" }, { header: \"TASKS\", align: \"right\" }, { header: \"ACTIVE\", align: \"right\" }, { header: \"ERRORS\", align: \"right\" }, { header: \"ID\" }],\n jobs.map((j: PublicJob) => [\n c.bold(j.name),\n statusColor(j.status),\n String(j.taskCount),\n String(j.activeTaskCount),\n j.errorTaskCount ? c.red(String(j.errorTaskCount)) : c.gray(\"0\"),\n c.gray(j.id),\n ]),\n ),\n );\n out();\n out(c.gray(`${jobs.length} container(s) · ${jobs.reduce((n, j) => n + j.taskCount, 0)} task(s)`));\n}\n\nfunction renderTasks(tasks: PublicTask[]): string {\n const now = Date.now();\n return table(\n [{ header: \"TASK\" }, { header: \"STATUS\" }, { header: \"SCHEDULE\" }, { header: \"NEXT RUN\" }, { header: \"LAST\" }],\n tasks.map((t) => [\n c.bold(t.name),\n statusColor(t.status),\n c.cyan(t.schedule),\n relativeTime(t.nextRun, now),\n t.lastRunStatus ? statusColor(t.lastRunStatus) : c.gray(\"—\"),\n ]),\n );\n}\n\nasync function cmdTasks(flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const client = makeClient();\n const jobName = typeof flags[\"job\"] === \"string\" ? flags[\"job\"] : undefined;\n let jobId: string | undefined;\n if (jobName) {\n const container = (await client.jobs.list()).find((j) => j.name === jobName);\n if (!container) throw new CronvelloConfigError(`No job container named \"${jobName}\".`);\n jobId = container.id;\n }\n const page = await client.tasks.list({ limit: 100, ...(jobId ? { jobId } : {}) });\n if (useJson) return json(page);\n header(jobName ? `tasks · ${jobName}` : \"all tasks\");\n out(renderTasks(page.tasks));\n}\n\nasync function cmdRuns(flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const client = makeClient();\n const limit = clampLimit(flags[\"limit\"]);\n const status = typeof flags[\"status\"] === \"string\" ? (flags[\"status\"] as PublicRun[\"status\"]) : undefined;\n const page = await client.runs.list({ limit, ...(status ? { status } : {}) });\n if (useJson) return json(page);\n header(`recent runs${status ? ` · ${status}` : \"\"}`);\n const now = Date.now();\n out(\n table(\n [{ header: \"WHEN\" }, { header: \"TASK\" }, { header: \"JOB\" }, { header: \"STATUS\" }, { header: \"HTTP\", align: \"right\" }, { header: \"TOOK\", align: \"right\" }],\n page.runs.map((r: PublicRun) => [\n relativeTime(r.startedAt, now),\n c.bold(r.taskName),\n c.gray(r.jobName),\n statusColor(r.status),\n r.httpStatusCode == null ? c.gray(\"—\") : String(r.httpStatusCode),\n r.durationMs == null ? c.gray(\"—\") : `${r.durationMs}ms`,\n ]),\n ),\n );\n out();\n out(c.gray(`showing ${page.runs.length} of ${page.pagination.total} runs`));\n}\n\nasync function cmdRun(positionals: string[], useJson: boolean): Promise<void> {\n const client = makeClient();\n let taskId: string;\n if (positionals.length >= 2) {\n const [jobName, taskName] = positionals;\n const container = (await client.jobs.list()).find((j) => j.name === jobName);\n if (!container) throw new CronvelloConfigError(`No job container named \"${jobName}\".`);\n const task = (await client.jobs.listTasks(container.id)).find((t) => t.name === taskName);\n if (!task) throw new CronvelloConfigError(`No task \"${taskName}\" in \"${jobName}\".`);\n taskId = task.id;\n } else if (positionals.length === 1) {\n taskId = positionals[0]!;\n } else {\n throw new CronvelloConfigError(\"Usage: cronvello run <taskId> | cronvello run <jobName> <taskName>\");\n }\n const res = await client.tasks.runNow(taskId);\n if (useJson) return json(res);\n if (res.success) out(`${sym.ok} triggered ${c.bold(taskId)} ${res.runId ? c.gray(`→ ${res.runId}`) : \"\"}`);\n else out(`${sym.fail} ${c.red(res.error ?? \"run failed\")}`);\n}\n\nasync function cmdStatus(useJson: boolean): Promise<void> {\n const client = makeClient();\n const [me, jobs, failures] = await Promise.all([\n client.account.me(),\n client.jobs.list(),\n client.runs.list({ limit: 5, status: \"failed\" }),\n ]);\n if (useJson) return json({ me, jobs, recentFailures: failures.runs });\n const totalTasks = jobs.reduce((n, j) => n + j.taskCount, 0);\n const activeTasks = jobs.reduce((n, j) => n + j.activeTaskCount, 0);\n const errorTasks = jobs.reduce((n, j) => n + j.errorTaskCount, 0);\n const healthy = errorTasks === 0 && me.summary.openDlqCount === 0;\n header(\"status\");\n out(`${healthy ? sym.ok : sym.warn} ${healthy ? c.green(\"healthy\") : c.yellow(\"needs attention\")}`);\n out();\n out(` ${c.dim(\"containers\")} ${jobs.length}`);\n out(` ${c.dim(\"tasks\")} ${activeTasks}/${totalTasks} active${errorTasks ? c.red(` · ${errorTasks} errored`) : \"\"}`);\n out(` ${c.dim(\"open DLQ\")} ${me.summary.openDlqCount ? c.red(String(me.summary.openDlqCount)) : c.gray(\"0\")}`);\n out(` ${c.dim(\"executions\")} ${me.usage.executionCount} this period`);\n if (failures.runs.length) {\n out();\n out(c.dim(\" recent failures:\"));\n const now = Date.now();\n for (const r of failures.runs) out(` ${sym.fail} ${c.bold(r.taskName)} ${c.gray(r.jobName)} ${relativeTime(r.startedAt, now)} ${r.error ? c.red(truncate(r.error, 50)) : \"\"}`);\n }\n}\n\nasync function cmdSync(positionals: string[], flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const app = await loadApp(positionals[0]);\n const dryRun = !!flags[\"dry\"] || !!flags[\"dry-run\"];\n const result = await app.sync({ dryRun });\n if (useJson) return json(result);\n out(formatSyncResult(result, { color: true, dryRun }));\n}\n\n/**\n * `cronvello dev [entry]` — start the **local engine**: load the config module and actually run the\n * jobs on this machine (no account, no cloud). `--dry-run` prints what would fire in the next window\n * instead of executing anything. Runs until SIGINT, then shuts down cleanly.\n */\nasync function cmdDevEngine(positionals: string[], flags: Args[\"flags\"], useJson: boolean): Promise<void> {\n const app = await loadApp(positionals[0]);\n const dryRun = !!flags[\"dry-run\"] || !!flags[\"dry\"];\n\n if (dryRun) {\n const engine = app.dev({ autoStart: false, installSignalHandlers: false });\n const windowMs = parseDurationFlag(flags[\"window\"], 60 * 60 * 1000);\n const maxPerJob = 50;\n const fires = upcomingFires(\n engine.jobs().map((j) => ({ key: j.key, schedule: j.schedule, timeZone: j.timeZone })),\n { withinMs: windowMs, maxPerJob },\n );\n // Be honest when a high-frequency schedule hit the per-job cap — the window isn't fully shown.\n const cappedJobs = [...new Set(fires.map((f) => f.key))].filter(\n (key) => fires.filter((f) => f.key === key).length >= maxPerJob,\n );\n if (useJson) {\n return json({\n window: { ms: windowMs },\n capped: cappedJobs,\n fires: fires.map((f) => ({ key: f.key, time: f.time.toISOString(), schedule: f.schedule, timeZone: f.timeZone })),\n });\n }\n header(`dev · dry-run · next ${formatDuration(windowMs)}`);\n out(renderUpcoming(fires));\n out();\n out(c.gray(fires.length ? `${fires.length} fire(s) would run — no handlers were executed` : \"nothing scheduled in this window\"));\n if (cappedJobs.length) {\n out(c.yellow(`▲ output capped at ${maxPerJob} per job (${cappedJobs.join(\", \")}) — high-frequency schedule, not the full window`));\n }\n return;\n }\n\n const engine = app.dev({ autoStart: false, installSignalHandlers: false, onEvent: (e) => renderEvent(e, useJson) });\n\n // Start first so the snapshot has each job's computed next-fire time, then print the table.\n engine.start();\n\n // Optional local dashboard. Loaded lazily so it never weighs on the non-dashboard path.\n let dashboardUrl: string | undefined;\n if (flags[\"dashboard\"]) {\n const { startDashboard } = await import(\"../dev/dashboard.js\");\n const port = typeof flags[\"port\"] === \"string\" ? Number.parseInt(flags[\"port\"], 10) : undefined;\n const host = typeof flags[\"host\"] === \"string\" ? flags[\"host\"] : undefined;\n try {\n const dash = await startDashboard(engine, { port, host });\n dashboardUrl = dash.url;\n engine.onStop(() => dash.close()); // Ctrl-C → engine.stop() tears the dashboard down too.\n } catch (err) {\n await engine.stop();\n throw err; // surfaced cleanly (e.g. \"port … already in use\") by run()'s catch\n }\n }\n\n if (!useJson) {\n header(`dev · local engine ${c.gray(\"· no account, no cloud\")}`);\n out(renderSchedule(engine.snapshot()));\n out();\n if (dashboardUrl) out(`${sym.ok} dashboard → ${c.cyan(dashboardUrl)}`);\n out(c.gray(`watching ${engine.jobs().length} job(s) — press Ctrl-C to stop`));\n out();\n }\n\n // Block until interrupted, then drain in-flight runs and print a short summary.\n await new Promise<void>((resolve) => {\n const onSignal = (): void => {\n process.removeListener(\"SIGINT\", onSignal);\n process.removeListener(\"SIGTERM\", onSignal);\n void engine.stop().then(resolve);\n };\n process.once(\"SIGINT\", onSignal);\n process.once(\"SIGTERM\", onSignal);\n });\n\n if (!useJson) {\n out();\n const runs = engine.runs();\n const ok = runs.filter((r) => r.status === \"success\").length;\n const bad = runs.filter((r) => r.status === \"error\" || r.status === \"timed_out\").length;\n out(c.gray(`stopped — ${runs.length} run(s) this session (${ok} ok${bad ? `, ${c.red(`${bad} failed`)}` : \"\"})`));\n }\n}\n\n/** `cronvello trigger [entry] <jobKey>` — run a single job's handler once, locally (no deploy). */\nasync function cmdTrigger(positionals: string[], useJson: boolean): Promise<void> {\n // Last positional is the job key; an optional earlier one is the config path.\n const jobKey = positionals[positionals.length - 1];\n const configPath = positionals.length >= 2 ? positionals[0] : undefined;\n if (!jobKey) throw new CronvelloConfigError(\"Usage: cronvello trigger [configPath] <jobKey>\");\n const app = await loadApp(configPath);\n if (!app.keys().includes(jobKey)) {\n throw new CronvelloConfigError(`Unknown job \"${jobKey}\". Known: ${app.keys().join(\", \") || \"(none)\"}`);\n }\n if (!useJson) out(`${sym.arrow} running ${c.bold(jobKey)} locally…`);\n const started = Date.now();\n const result = await app.trigger(jobKey);\n if (useJson) return json({ job: jobKey, result });\n out(`${sym.ok} ${c.bold(jobKey)} ${c.gray(`done in ${Date.now() - started}ms`)}`);\n if (result !== undefined && result !== null) {\n out(c.dim(\" result:\"));\n out(JSON.stringify(result, null, 2).split(\"\\n\").map((l) => \" \" + l).join(\"\\n\"));\n }\n}\n\n/** `cronvello preview \"<cron>\" [--tz <IANA>] [-n 5]` — print the next N fire times of an expression. */\nfunction cmdPreview(positionals: string[], flags: Args[\"flags\"], useJson: boolean): void {\n const expr = positionals[0];\n if (!expr) throw new CronvelloConfigError('Usage: cronvello preview \"<cron>\" [--tz <IANA>] [-n 5]');\n const tz = typeof flags[\"tz\"] === \"string\" ? flags[\"tz\"] : localTimeZone();\n const count = clampLimit(flags[\"n\"] ?? flags[\"count\"] ?? flags[\"limit\"]);\n\n let times: Date[];\n try {\n times = previewSchedule(expr, { timeZone: tz, count });\n } catch (err) {\n throw new CronvelloConfigError(err instanceof Error ? err.message : String(err));\n }\n\n if (useJson) return json({ schedule: expr, timeZone: tz, next: times.map((t) => t.toISOString()) });\n header(`preview ${c.cyan(expr)} ${c.gray(`· ${tz}`)}`);\n if (!times.length) {\n out(c.gray(\"no upcoming fire times (does this expression ever match?)\"));\n return;\n }\n const now = Date.now();\n out(\n table(\n [{ header: \"#\", align: \"right\" }, { header: \"LOCAL TIME\" }, { header: \"WHEN\" }, { header: \"UTC\" }],\n times.map((t, i) => [\n c.gray(String(i + 1)),\n c.bold(formatInZone(t, tz)),\n relativeTime(t.toISOString(), now),\n c.gray(t.toISOString()),\n ]),\n ),\n );\n}\n\n// ─── Dev rendering ───────────────────────────────────────────────────────────\n\n/** The schedule table shown when the engine starts. */\nfunction renderSchedule(snapshot: JobSnapshot[]): string {\n const now = Date.now();\n return table(\n [{ header: \"JOB\" }, { header: \"SCHEDULE\" }, { header: \"TZ\" }, { header: \"NEXT RUN\" }, { header: \"WHEN\" }],\n snapshot.map((s) => [\n c.bold(s.key),\n c.cyan(s.schedule),\n c.gray(s.timeZone),\n s.nextFire ? formatInZone(s.nextFire, s.timeZone) : c.gray(\"—\"),\n s.nextFire ? relativeTime(s.nextFire.toISOString(), now) : c.gray(\"—\"),\n ]),\n );\n}\n\n/** The dry-run table of upcoming fires. */\nfunction renderUpcoming(fires: UpcomingFire[]): string {\n const now = Date.now();\n return table(\n [{ header: \"WHEN\" }, { header: \"LOCAL TIME\" }, { header: \"JOB\" }, { header: \"SCHEDULE\" }],\n fires.map((f) => [\n relativeTime(f.time.toISOString(), now),\n c.bold(formatInZone(f.time, f.timeZone)),\n c.cyan(f.key),\n c.gray(f.schedule),\n ]),\n );\n}\n\n/** Render one live engine event as a timestamped line (or an NDJSON line under --json). */\nfunction renderEvent(event: EngineEvent, useJson: boolean): void {\n if (useJson) return out(JSON.stringify(event));\n const ts = c.gray(clockStamp(Date.now()));\n switch (event.type) {\n case \"fire\":\n out(`${ts} ${sym.arrow} ${c.bold(event.key)} ${c.gray(event.attempt > 1 ? `(attempt ${event.attempt})` : \"fired\")}`);\n break;\n case \"success\":\n out(`${ts} ${sym.ok} ${c.bold(event.key)} ${c.gray(`${event.durationMs}ms${event.attempts > 1 ? ` · ${event.attempts} attempts` : \"\"}`)}`);\n break;\n case \"error\":\n out(`${ts} ${sym.fail} ${c.bold(event.key)} ${c.red(event.error)} ${c.gray(event.willRetry ? \"· will retry\" : \"· gave up\")}`);\n break;\n case \"timeout\":\n out(`${ts} ${sym.fail} ${c.bold(event.key)} ${c.red(\"timed out\")} ${c.gray(`after ${event.durationMs}ms${event.willRetry ? \" · will retry\" : \" · gave up\"}`)}`);\n break;\n case \"retry\":\n out(`${ts} ${sym.warn} ${c.bold(event.key)} ${c.gray(`retrying in ${event.delayMs}ms (attempt ${event.attempt})`)}`);\n break;\n case \"skipped\":\n out(`${ts} ${sym.warn} ${c.bold(event.key)} ${c.gray(\"skipped — previous run still in flight\")}`);\n break;\n // \"scheduled\" / \"engine-start\" / \"engine-stop\" are intentionally quiet in the live feed.\n }\n}\n\n/** Format an instant in an IANA zone as \"YYYY-MM-DD HH:MM:SS\". */\nfunction formatInZone(date: Date, timeZone: string): string {\n try {\n const parts = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone,\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\",\n hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\", hour12: false,\n }).formatToParts(date);\n const m: Record<string, string> = {};\n for (const p of parts) if (p.type !== \"literal\") m[p.type] = p.value;\n const hour = m[\"hour\"] === \"24\" ? \"00\" : m[\"hour\"];\n return `${m[\"year\"]}-${m[\"month\"]}-${m[\"day\"]} ${hour}:${m[\"minute\"]}:${m[\"second\"]}`;\n } catch {\n return date.toISOString();\n }\n}\n\n/** Wall-clock HH:MM:SS in the local zone, for live-feed line stamps. */\nfunction clockStamp(nowMs: number): string {\n return formatInZone(new Date(nowMs), localTimeZone()).slice(11);\n}\n\nfunction parseDurationFlag(value: string | boolean | undefined, fallback: number): number {\n if (typeof value !== \"string\") return fallback;\n const m = /^(\\d+)\\s*(s|m|h|d)?$/i.exec(value.trim());\n if (!m) return fallback;\n const n = Number(m[1]);\n const unit = (m[2] ?? \"m\").toLowerCase();\n const mult = unit === \"s\" ? 1000 : unit === \"h\" ? 3_600_000 : unit === \"d\" ? 86_400_000 : 60_000;\n return n * mult;\n}\n\nfunction formatDuration(ms: number): string {\n if (ms % 86_400_000 === 0) return `${ms / 86_400_000}d`;\n if (ms % 3_600_000 === 0) return `${ms / 3_600_000}h`;\n if (ms % 60_000 === 0) return `${ms / 60_000}m`;\n return `${Math.round(ms / 1000)}s`;\n}\n\nfunction cmdSecret(useJson: boolean): void {\n const secret = generateDispatchSecret();\n if (useJson) return json({ dispatchSecret: secret });\n out(secret);\n}\n\n// ─── Config-module loading (sync / dev) ──────────────────────────────────────\n\nconst DEFAULT_CONFIG_PATHS = [\n \"cronvello.config.ts\", \"cronvello.config.js\", \"cronvello.config.mjs\",\n \"cronvello.ts\", \"cronvello.js\", \"src/cronvello.ts\", \"src/cronvello.js\",\n];\n\nfunction looksLikeApp(v: unknown): v is CronvelloApp {\n return !!v && typeof v === \"object\" && typeof (v as CronvelloApp).sync === \"function\" && typeof (v as CronvelloApp).trigger === \"function\";\n}\n\nasync function loadApp(pathArg: string | undefined): Promise<CronvelloApp> {\n const candidate = pathArg ?? DEFAULT_CONFIG_PATHS.find((p) => existsSync(resolve(process.cwd(), p)));\n if (!candidate) {\n throw new CronvelloConfigError(\n `No config module found. Pass a path (cronvello sync ./cronvello.config.js) or add one of: ${DEFAULT_CONFIG_PATHS.join(\", \")}.`,\n );\n }\n const abs = resolve(process.cwd(), candidate);\n if (!existsSync(abs)) throw new CronvelloConfigError(`Config module not found: ${abs}`);\n\n let mod: Record<string, unknown>;\n try {\n mod = (await import(pathToFileURL(abs).href)) as Record<string, unknown>;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (/Unknown file extension|\\.ts|ERR_UNKNOWN/.test(msg) && abs.endsWith(\".ts\")) {\n throw new CronvelloConfigError(\n `Could not import a TypeScript config directly. Run the CLI under a TS loader, e.g.\\n node --import tsx node_modules/@cronvello/sdk/dist/cli.js sync ${candidate}\\nor point at a compiled .js file.`,\n );\n }\n throw new CronvelloConfigError(`Failed to import ${candidate}: ${msg}`);\n }\n\n const found = looksLikeApp(mod[\"default\"]) ? mod[\"default\"]\n : looksLikeApp(mod[\"cronvello\"]) ? mod[\"cronvello\"]\n : looksLikeApp(mod[\"app\"]) ? mod[\"app\"]\n : Object.values(mod).find(looksLikeApp);\n if (!found) {\n throw new CronvelloConfigError(`${candidate} does not export a Cronvello app (export default defineCronvello({…}) or a named \\`cronvello\\`).`);\n }\n return found as CronvelloApp;\n}\n\n// ─── Help / dispatch ─────────────────────────────────────────────────────────\n\nfunction printHelp(): void {\n out(`${ICON} ${brand(\"Cronvello\")} ${c.gray(\"· code-first cron\")} ${c.dim(\"v\" + VERSION)}`);\n out();\n out(c.bold(\"USAGE\"));\n out(` ${c.cyan(\"cronvello\")} <command> [options]`);\n out();\n out(c.bold(\"COMMANDS\"));\n const cmds: [string, string][] = [\n [\"whoami\", \"account, plan, limits & usage\"],\n [\"list [jobName]\", \"job containers, or tasks inside one\"],\n [\"tasks [--job <name>]\", \"account-wide task table\"],\n [\"runs [--limit n] [--status s]\", \"recent execution feed\"],\n [\"run <taskId>\", \"trigger a task now (or: run <jobName> <taskName>)\"],\n [\"status\", \"health overview + recent failures\"],\n [\"sync [path] [--dry]\", \"reconcile a code registry (loads your module)\"],\n [\"dev [path] [--dry-run]\", \"start the local engine — run jobs locally, no account\"],\n [\"dev --dashboard [--port n]\", \"…plus a local web dashboard (127.0.0.1, live runs + run-now)\"],\n [\"preview \\\"<cron>\\\" [-n 5]\", \"print the next N fire times (--tz <IANA>)\"],\n [\"trigger [path] <jobKey>\", \"run a single job handler once, locally\"],\n [\"secret\", \"generate a strong dispatch secret\"],\n ];\n for (const [name, desc] of cmds) out(` ${c.cyan(name.padEnd(30))} ${c.gray(desc)}`);\n out();\n out(c.bold(\"GLOBAL\"));\n out(` ${c.cyan(\"--json\".padEnd(30))} ${c.gray(\"machine-readable output\")}`);\n out(` ${c.cyan(\"--no-color\".padEnd(30))} ${c.gray(\"disable colour\")}`);\n out(` ${c.cyan(\"-h, --help\".padEnd(30))} ${c.gray(\"show this help\")}`);\n out(` ${c.cyan(\"-v, --version\".padEnd(30))} ${c.gray(\"print version\")}`);\n out();\n out(c.gray(\"Auth: export CRONVELLO_API_KEY (crn_live_…). Optional: CRONVELLO_API_URL.\"));\n}\n\nfunction clampLimit(v: string | boolean | undefined): number {\n const n = typeof v === \"string\" ? Number(v) : NaN;\n if (!Number.isFinite(n)) return 20;\n return Math.min(Math.max(Math.trunc(n), 1), 100);\n}\n\nfunction truncate(s: string, n: number): string {\n return s.length > n ? s.slice(0, n - 1) + \"…\" : s;\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const args = parseArgs(argv);\n if (args.flags[\"no-color\"]) setColor(false);\n const useJson = !!args.flags[\"json\"];\n\n if (args.flags[\"version\"] || args.flags[\"v\"]) {\n out(VERSION);\n return 0;\n }\n if (!args.command || args.flags[\"help\"] || args.flags[\"h\"] || args.command === \"help\") {\n printHelp();\n return 0;\n }\n\n try {\n switch (args.command) {\n case \"whoami\": await cmdWhoami(useJson); break;\n case \"list\": await cmdList(args.positionals[0], useJson); break;\n case \"tasks\": await cmdTasks(args.flags, useJson); break;\n case \"runs\": await cmdRuns(args.flags, useJson); break;\n case \"run\": await cmdRun(args.positionals, useJson); break;\n case \"status\": await cmdStatus(useJson); break;\n case \"sync\": await cmdSync(args.positionals, args.flags, useJson); break;\n case \"dev\": await cmdDevEngine(args.positionals, args.flags, useJson); break;\n case \"preview\": cmdPreview(args.positionals, args.flags, useJson); break;\n case \"trigger\": await cmdTrigger(args.positionals, useJson); break;\n case \"secret\": cmdSecret(useJson); break;\n default:\n out(`${sym.fail} Unknown command \"${args.command}\". Run ${c.cyan(\"cronvello --help\")}.`);\n return 1;\n }\n return 0;\n } catch (err) {\n if (err instanceof CronvelloApiError) {\n out(`${sym.fail} ${c.red(`API ${err.status}`)} ${err.message}${err.isRateLimited && err.retryAfterSeconds ? c.gray(` (retry in ${err.retryAfterSeconds}s)`) : \"\"}`);\n } else if (err instanceof CronvelloConfigError) {\n out(`${sym.fail} ${err.message}`);\n } else {\n out(`${sym.fail} ${err instanceof Error ? err.message : String(err)}`);\n }\n return 1;\n }\n}\n\n/**\n * True when this module is the process entry point — including when launched through the `bin`\n * symlink (`node_modules/.bin/cronvello`), where `process.argv[1]` is the symlink path. Resolving\n * both sides through `realpathSync` makes the comparison symlink-proof; under a test runner the\n * entry is the runner, so this is false and importing the module never auto-runs.\n */\nfunction isMainModule(): boolean {\n try {\n const argv1 = process.argv?.[1];\n if (!argv1) return false;\n return realpathSync(argv1) === realpathSync(fileURLToPath(import.meta.url));\n } catch {\n return false;\n }\n}\n\nif (isMainModule()) {\n // Exit quietly when the reader closes the pipe early (e.g. `cronvello list | head`).\n process.stdout.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") process.exit(0);\n throw err;\n });\n run(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n });\n}\n","/**\n * Zero-dependency terminal UI helpers for the `cronvello` CLI: colour, symbols, tables, boxes,\n * relative times. Colour auto-disables when stdout is not a TTY, when NO_COLOR is set, or when\n * `--no-color` was passed (see `setColor`).\n */\n\nconst E = String.fromCharCode(27);\nconst ENV = typeof process !== \"undefined\" && process.env ? process.env : {};\nlet COLOR =\n !ENV[\"NO_COLOR\"] &&\n (!!ENV[\"FORCE_COLOR\"] || !!(typeof process !== \"undefined\" && process.stdout && process.stdout.isTTY));\n\nexport function setColor(on: boolean): void {\n COLOR = on;\n}\n\nfunction wrap(code: number, close: number, s: string): string {\n return COLOR ? `${E}[${code}m${s}${E}[${close}m` : s;\n}\n\nexport const c = {\n bold: (s: string) => wrap(1, 22, s),\n dim: (s: string) => wrap(2, 22, s),\n red: (s: string) => wrap(31, 39, s),\n green: (s: string) => wrap(32, 39, s),\n yellow: (s: string) => wrap(33, 39, s),\n blue: (s: string) => wrap(34, 39, s),\n magenta: (s: string) => wrap(35, 39, s),\n cyan: (s: string) => wrap(36, 39, s),\n gray: (s: string) => wrap(90, 39, s),\n};\n\n/** Cronvello brand: indigo-ish on supported terminals (256-colour), falling back to cyan. */\nexport function brand(s: string): string {\n return COLOR ? `${E}[38;5;63m${s}${E}[39m` : s;\n}\n\nexport const sym = {\n ok: c.green(\"✔\"),\n fail: c.red(\"✗\"),\n warn: c.yellow(\"▲\"),\n info: c.cyan(\"ℹ\"),\n dot: c.gray(\"·\"),\n arrow: c.gray(\"→\"),\n};\n\n/** Visible length of a string, ignoring ANSI escape codes — for column alignment. */\nexport function visibleLength(s: string): number {\n // eslint-disable-next-line no-control-regex\n return s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n}\n\nfunction padEndVisible(s: string, width: number): string {\n const pad = width - visibleLength(s);\n return pad > 0 ? s + \" \".repeat(pad) : s;\n}\n\nexport interface TableColumn {\n header: string;\n /** Right-align (e.g. numbers). */\n align?: \"left\" | \"right\";\n}\n\n/** Render an aligned table. Cells may already contain colour codes. */\nexport function table(columns: TableColumn[], rows: string[][]): string {\n const widths = columns.map((col, i) =>\n Math.max(visibleLength(col.header), ...rows.map((r) => visibleLength(r[i] ?? \"\"))),\n );\n const fmtRow = (cells: string[]) =>\n cells\n .map((cell, i) => {\n const w = widths[i]!;\n if (columns[i]?.align === \"right\") {\n const pad = w - visibleLength(cell);\n return (pad > 0 ? \" \".repeat(pad) : \"\") + cell;\n }\n return padEndVisible(cell, w);\n })\n .join(\" \");\n const head = fmtRow(columns.map((col) => c.dim(col.header)));\n const body = rows.map(fmtRow);\n return [head, ...body].join(\"\\n\");\n}\n\n/** A simple rounded box around a block of text (already-coloured lines are fine). */\nexport function box(title: string, lines: string[]): string {\n const inner = [title, \"\", ...lines];\n const width = Math.max(...inner.map(visibleLength));\n const top = c.gray(\"╭─ \") + brand(title) + c.gray(\" \" + \"─\".repeat(Math.max(0, width - visibleLength(title) - 1)) + \"╮\");\n const mid = lines.map((l) => c.gray(\"│ \") + padEndVisible(l, width) + c.gray(\" │\"));\n const bot = c.gray(\"╰\" + \"─\".repeat(width + 2) + \"╯\");\n return [top, ...mid, bot].join(\"\\n\");\n}\n\n/** Compact relative time like \"3m ago\" / \"in 2h\" from an ISO string. `nowMs` is injectable for tests. */\nexport function relativeTime(iso: string | null, nowMs: number): string {\n if (!iso) return c.gray(\"—\");\n const then = Date.parse(iso);\n if (Number.isNaN(then)) return c.gray(\"—\");\n const deltaSec = Math.round((then - nowMs) / 1000);\n const future = deltaSec > 0;\n const abs = Math.abs(deltaSec);\n const unit =\n abs < 60 ? `${abs}s` : abs < 3600 ? `${Math.round(abs / 60)}m` : abs < 86400 ? `${Math.round(abs / 3600)}h` : `${Math.round(abs / 86400)}d`;\n return c.gray(future ? `in ${unit}` : `${unit} ago`);\n}\n\nexport const ICON = brand(\"◷\"); // clock-ish brand mark for the header\n"]}
|