{"version":3,"file":"index.cjs","names":["collect"],"sources":["../src/cron/fields.ts","../src/errors.ts","../src/cron/parser.ts","../src/cron/values.ts","../src/cron/next.ts","../src/cron/zone.ts","../src/cron/shift.ts","../src/cron/validate.ts","../src/explain/time.ts","../src/explain/field.ts","../src/explain/compose.ts","../src/explain/index.ts","../src/parse/dictionary.ts","../src/parse/fill.ts","../src/parse/normalize.ts","../src/parse/tokenize.ts","../src/parse/index.ts"],"sourcesContent":["import type { CronField } from \"../types\";\n\nexport interface FieldSpec {\n  field: CronField;\n  /** エラーメッセージ用の日本語名 */\n  label: string;\n  /** 展開後の下限 */\n  min: number;\n  /** 展開後の上限 */\n  max: number;\n  /** 入力として許容する上限（曜日のみ 7） */\n  inputMax: number;\n  /** 名前による指定（JAN, MON など） */\n  names?: Record<string, number>;\n}\n\nexport const MONTH_NAMES: Record<string, number> = {\n  JAN: 1,\n  FEB: 2,\n  MAR: 3,\n  APR: 4,\n  MAY: 5,\n  JUN: 6,\n  JUL: 7,\n  AUG: 8,\n  SEP: 9,\n  OCT: 10,\n  NOV: 11,\n  DEC: 12,\n};\n\nexport const DOW_NAMES: Record<string, number> = {\n  SUN: 0,\n  MON: 1,\n  TUE: 2,\n  WED: 3,\n  THU: 4,\n  FRI: 5,\n  SAT: 6,\n};\n\nexport const SECOND_SPEC: FieldSpec = {\n  field: \"second\",\n  label: \"秒\",\n  min: 0,\n  max: 59,\n  inputMax: 59,\n};\nexport const MINUTE_SPEC: FieldSpec = {\n  field: \"minute\",\n  label: \"分\",\n  min: 0,\n  max: 59,\n  inputMax: 59,\n};\nexport const HOUR_SPEC: FieldSpec = { field: \"hour\", label: \"時\", min: 0, max: 23, inputMax: 23 };\nexport const DOM_SPEC: FieldSpec = {\n  field: \"dayOfMonth\",\n  label: \"日\",\n  min: 1,\n  max: 31,\n  inputMax: 31,\n};\nexport const MONTH_SPEC: FieldSpec = {\n  field: \"month\",\n  label: \"月\",\n  min: 1,\n  max: 12,\n  inputMax: 12,\n  names: MONTH_NAMES,\n};\nexport const DOW_SPEC: FieldSpec = {\n  field: \"dayOfWeek\",\n  label: \"曜日\",\n  min: 0,\n  max: 6,\n  inputMax: 7,\n  names: DOW_NAMES,\n};\n\n/** 5 フィールド式の並び */\nexport const FIELD_SPECS: FieldSpec[] = [MINUTE_SPEC, HOUR_SPEC, DOM_SPEC, MONTH_SPEC, DOW_SPEC];\n\n/** 6 フィールド（秒付き）式の並び */\nexport const FIELD_SPECS_WITH_SECONDS: FieldSpec[] = [SECOND_SPEC, ...FIELD_SPECS];\n\nexport const MACROS: 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\n/**\n * crontab では有効だが、実行タイミングが日時で決まらないため説明できない指定。\n * 値はエラーメッセージに使う理由。\n */\nexport const UNSCHEDULABLE_MACROS: Record<string, string> = {\n  \"@reboot\": \"起動時に一度だけ実行される指定で、日時を持たないため説明できません\",\n};\n\nexport const DOW_LABELS = [\"日曜日\", \"月曜日\", \"火曜日\", \"水曜日\", \"木曜日\", \"金曜日\", \"土曜日\"];\n","import type { CronField, ParseResult } from \"./types\";\n\n/**\n * cron 式の構文エラー。\n */\nexport class CronSyntaxError extends Error {\n  readonly field?: CronField;\n  readonly position?: number;\n\n  constructor(message: string, options: { field?: CronField; position?: number } = {}) {\n    super(message);\n    this.name = \"CronSyntaxError\";\n    if (options.field !== undefined) this.field = options.field;\n    if (options.position !== undefined) this.position = options.position;\n  }\n}\n\n/**\n * `parse({ strict: true })` で解釈が曖昧だったときに投げられる。\n */\nexport class ParseAmbiguityError extends Error {\n  readonly result: ParseResult;\n\n  constructor(message: string, result: ParseResult) {\n    super(message);\n    this.name = \"ParseAmbiguityError\";\n    this.result = result;\n  }\n}\n\n/**\n * タイムゾーン名を解釈できなかったときに投げられる。\n */\nexport class CronTimeZoneError extends Error {\n  /** 与えられたゾーン名 */\n  readonly timeZone: string;\n\n  constructor(message: string, timeZone: string) {\n    super(message);\n    this.name = \"CronTimeZoneError\";\n    this.timeZone = timeZone;\n  }\n}\n","import { CronSyntaxError } from \"../errors\";\nimport type { CronAST, CronExtension, CronField, FieldAST, ParserOptions } from \"../types\";\nimport {\n  FIELD_SPECS,\n  FIELD_SPECS_WITH_SECONDS,\n  type FieldSpec,\n  MACROS,\n  UNSCHEDULABLE_MACROS,\n} from \"./fields\";\n\nexport interface ParsedExpression {\n  ast: CronAST;\n  /** フィールドごとの入力文字列（正規化前） */\n  raw: {\n    seconds?: string;\n    minute: string;\n    hour: string;\n    dayOfMonth: string;\n    month: string;\n    dayOfWeek: string;\n  };\n  /** 使用されている拡張構文 */\n  extensions: CronExtension[];\n  /** マクロが展開された場合、その元の表記 */\n  macro?: string;\n}\n\ninterface Part {\n  text: string;\n  offset: number;\n}\n\n/** カンマ区切りで位置情報を保ったまま分割する */\nfunction splitParts(text: string, offset: number, separator: string): Part[] {\n  const parts: Part[] = [];\n  let start = 0;\n  for (let i = 0; i <= text.length; i++) {\n    if (i === text.length || text[i] === separator) {\n      parts.push({ text: text.slice(start, i), offset: offset + start });\n      start = i + 1;\n    }\n  }\n  return parts;\n}\n\n/** 曜日の 7 は日曜（0）と同じ値を指す */\nfunction normalizeWeekday(value: number, spec: FieldSpec): number {\n  return spec.field === \"dayOfWeek\" && value === 7 ? 0 : value;\n}\n\n/** 書かれたままの値を読む。曜日の 7 は 0 に畳まない */\nfunction parseNumber(text: string, spec: FieldSpec, position: number): number {\n  const upper = text.toUpperCase();\n  const named = spec.names?.[upper];\n  if (named !== undefined) return named;\n\n  if (!/^\\d{1,2}$/.test(text)) {\n    throw new CronSyntaxError(`${spec.label} フィールドの値 '${text}' を解釈できません`, {\n      field: spec.field,\n      position,\n    });\n  }\n  const value = Number(text);\n  if (value < spec.min || value > spec.inputMax) {\n    throw new CronSyntaxError(\n      `${spec.label} フィールドの値 ${value} は範囲外です (${spec.min}-${spec.inputMax})`,\n      { field: spec.field, position },\n    );\n  }\n  return value;\n}\n\n/** 値を読んで、曜日の 7 を 0 に正規化する */\nfunction parseValue(text: string, spec: FieldSpec, position: number): number {\n  return normalizeWeekday(parseNumber(text, spec, position), spec);\n}\n\nfunction parseAtom(text: string, spec: FieldSpec, position: number): FieldAST {\n  if (text === \"\") {\n    throw new CronSyntaxError(`${spec.label} フィールドが空です`, {\n      field: spec.field,\n      position,\n    });\n  }\n  if (text === \"*\") return { kind: \"any\" };\n\n  if (text === \"?\") {\n    if (spec.field !== \"dayOfMonth\" && spec.field !== \"dayOfWeek\") {\n      throw new CronSyntaxError(`'?' は日・曜日フィールドでのみ使用できます`, {\n        field: spec.field,\n        position,\n      });\n    }\n    return { kind: \"noSpecific\" };\n  }\n\n  if (spec.field === \"dayOfMonth\") {\n    if (text === \"L\") return { kind: \"last\" };\n    const lastOffset = /^L-(\\d{1,2})$/.exec(text);\n    if (lastOffset?.[1] !== undefined) {\n      const offset = Number(lastOffset[1]);\n      if (offset > 30) {\n        throw new CronSyntaxError(`'L-${offset}' のオフセットは 0-30 の範囲で指定してください`, {\n          field: spec.field,\n          position,\n        });\n      }\n      return { kind: \"last\", offset };\n    }\n    const nearest = /^(\\d{1,2})W$/i.exec(text);\n    if (nearest?.[1] !== undefined) {\n      return { kind: \"nearestWeekday\", day: parseValue(nearest[1], spec, position) };\n    }\n  }\n\n  if (spec.field === \"dayOfWeek\") {\n    const hash = text.indexOf(\"#\");\n    if (hash >= 0) {\n      const weekday = parseValue(text.slice(0, hash), spec, position);\n      const nthText = text.slice(hash + 1);\n      if (!/^[1-5]$/.test(nthText)) {\n        throw new CronSyntaxError(`'#' の後は 1-5 で指定してください`, {\n          field: spec.field,\n          position: position + hash + 1,\n        });\n      }\n      return { kind: \"nth\", weekday, nth: Number(nthText) };\n    }\n    if (/^.+L$/i.test(text)) {\n      const weekday = parseValue(text.slice(0, -1), spec, position);\n      return { kind: \"nth\", weekday, nth: -1 };\n    }\n    if (text.toUpperCase() === \"L\") {\n      throw new CronSyntaxError(`曜日フィールドの 'L' は '5L' のように曜日と組み合わせてください`, {\n        field: spec.field,\n        position,\n      });\n    }\n  }\n\n  const dash = text.indexOf(\"-\");\n  if (dash > 0) {\n    const from = parseNumber(text.slice(0, dash), spec, position);\n    const to = parseNumber(text.slice(dash + 1), spec, position + dash + 1);\n    // `0-7` は「日曜から日曜まで」ではなく全曜日。7 を先に 0 へ畳むと幅が消えてしまうので、\n    // ここだけは正規化前の 7 を見て全域の範囲に読み替える。\n    // `1-7` のように始まりが 0 でない場合は、`1-0` の循環範囲が同じ集合を指すので畳んでよい\n    if (spec.field === \"dayOfWeek\" && from === spec.min && to === spec.inputMax) {\n      return { kind: \"range\", from: spec.min, to: spec.max };\n    }\n    return {\n      kind: \"range\",\n      from: normalizeWeekday(from, spec),\n      to: normalizeWeekday(to, spec),\n    };\n  }\n\n  return { kind: \"value\", value: parseValue(text, spec, position) };\n}\n\nfunction parseItem(text: string, spec: FieldSpec, position: number): FieldAST {\n  const slash = text.indexOf(\"/\");\n  if (slash < 0) return parseAtom(text, spec, position);\n\n  const stepText = text.slice(slash + 1);\n  if (!/^\\d{1,2}$/.test(stepText)) {\n    throw new CronSyntaxError(`${spec.label} フィールドの刻み幅 '${stepText}' を解釈できません`, {\n      field: spec.field,\n      position: position + slash + 1,\n    });\n  }\n  const step = Number(stepText);\n  if (step < 1) {\n    throw new CronSyntaxError(`${spec.label} フィールドの刻み幅は 1 以上で指定してください`, {\n      field: spec.field,\n      position: position + slash + 1,\n    });\n  }\n\n  const baseText = text.slice(0, slash);\n  const base = parseAtom(baseText === \"\" ? \"*\" : baseText, spec, position);\n  if (base.kind === \"value\") {\n    // `5/15` は「5 から上限まで 15 刻み」の意味。`5-<上限>` と書いたのと同じなので、\n    // 範囲として読み直す。こうすると曜日の `7`（日曜）や `0-7`（全曜日）の扱いが\n    // `a-b` と揃う。`base.value` は正規化済みなのでそのままでは 7 が 0 に潰れてしまう\n    return { kind: \"step\", base: parseAtom(`${baseText}-${spec.inputMax}`, spec, position), step };\n  }\n  if (base.kind !== \"any\" && base.kind !== \"range\") {\n    throw new CronSyntaxError(`${spec.label} フィールドの刻みは '*' か範囲にのみ指定できます`, {\n      field: spec.field,\n      position,\n    });\n  }\n  return { kind: \"step\", base, step };\n}\n\nfunction parseField(text: string, spec: FieldSpec, offset: number): FieldAST {\n  const parts = splitParts(text, offset, \",\");\n  const items = parts.map((part) => parseItem(part.text, spec, part.offset));\n  const first = items[0];\n  if (first === undefined) {\n    throw new CronSyntaxError(`${spec.label} フィールドが空です`, {\n      field: spec.field,\n      position: offset,\n    });\n  }\n  if (items.length === 1) return first;\n  return { kind: \"list\", items };\n}\n\nfunction collectExtensions(ast: FieldAST, into: Set<CronExtension>): void {\n  switch (ast.kind) {\n    case \"last\":\n      into.add(\"L\");\n      break;\n    case \"nth\":\n      into.add(ast.nth === -1 ? \"L\" : \"#\");\n      break;\n    case \"nearestWeekday\":\n      into.add(\"W\");\n      break;\n    case \"noSpecific\":\n      into.add(\"?\");\n      break;\n    case \"list\":\n      for (const item of ast.items) collectExtensions(item, into);\n      break;\n    case \"step\":\n      collectExtensions(ast.base, into);\n      break;\n    default:\n      break;\n  }\n}\n\n/**\n * cron 式を構文解析する。不正な式は {@link CronSyntaxError} を投げる。\n */\nexport function parseExpression(expression: string, options: ParserOptions = {}): ParsedExpression {\n  if (typeof expression !== \"string\") {\n    throw new CronSyntaxError(\"cron 式は文字列で指定してください\");\n  }\n  const trimmed = expression.trim();\n  if (trimmed === \"\") {\n    throw new CronSyntaxError(\"cron 式が空です\");\n  }\n\n  let source = trimmed;\n  let macro: string | undefined;\n  if (source.startsWith(\"@\")) {\n    // crontab の行は「@daily <コマンド>」の形を取り、マクロは常に先頭の 1 トークン。\n    // 数値のフィールドと違って区切りが曖昧にならないので、残りはコマンドとして捨てる\n    const token = /^\\S+/.exec(source)?.[0] ?? source;\n    const lower = token.toLowerCase();\n    const expanded = MACROS[lower];\n    if (expanded === undefined) {\n      const reason = UNSCHEDULABLE_MACROS[lower];\n      if (reason !== undefined) {\n        throw new CronSyntaxError(`'${token}' は${reason}`, { position: 0 });\n      }\n      throw new CronSyntaxError(`マクロ '${token}' には対応していません`, { position: 0 });\n    }\n    macro = token;\n    source = expanded;\n  }\n\n  const specs = options.seconds === true ? FIELD_SPECS_WITH_SECONDS : FIELD_SPECS;\n  const fields: Part[] = [];\n  const re = /\\S+/g;\n  let match = re.exec(source);\n  while (match !== null) {\n    fields.push({ text: match[0], offset: match.index });\n    match = re.exec(source);\n  }\n\n  if (fields.length !== specs.length) {\n    const hint =\n      fields.length === 6 && options.seconds !== true\n        ? \"。秒付きの式は seconds オプションを有効にしてください\"\n        : \"\";\n    throw new CronSyntaxError(\n      `フィールド数が不正です（${specs.length} 個必要ですが ${fields.length} 個でした）${hint}`,\n      { position: 0 },\n    );\n  }\n\n  interface Entry {\n    spec: FieldSpec;\n    part: Part;\n    ast: FieldAST;\n  }\n  const parsed: Entry[] = specs.map((spec, index) => {\n    const part = fields[index];\n    /* c8 ignore next -- fields.length === specs.length を確認済み */\n    if (part === undefined) throw new CronSyntaxError(\"フィールド数が不正です\");\n    return { spec, part, ast: parseField(part.text, spec, part.offset) };\n  });\n\n  const byField = new Map<CronField, Entry>(parsed.map((entry) => [entry.spec.field, entry]));\n  const get = (field: CronField): Entry => {\n    const entry = byField.get(field);\n    /* c8 ignore next -- specs は必ず全フィールドを含む */\n    if (entry === undefined) throw new CronSyntaxError(\"フィールドが不足しています\");\n    return entry;\n  };\n\n  const minute = get(\"minute\");\n  const hour = get(\"hour\");\n  const dayOfMonth = get(\"dayOfMonth\");\n  const month = get(\"month\");\n  const dayOfWeek = get(\"dayOfWeek\");\n  const seconds = options.seconds === true ? get(\"second\") : undefined;\n\n  const ast: CronAST = {\n    minute: minute.ast,\n    hour: hour.ast,\n    dayOfMonth: dayOfMonth.ast,\n    month: month.ast,\n    dayOfWeek: dayOfWeek.ast,\n  };\n  if (seconds !== undefined) ast.seconds = seconds.ast;\n\n  const extensions = new Set<CronExtension>();\n  for (const entry of parsed) collectExtensions(entry.ast, extensions);\n\n  const result: ParsedExpression = {\n    ast,\n    raw: {\n      minute: minute.part.text,\n      hour: hour.part.text,\n      dayOfMonth: dayOfMonth.part.text,\n      month: month.part.text,\n      dayOfWeek: dayOfWeek.part.text,\n    },\n    extensions: [...extensions],\n  };\n  if (seconds !== undefined) result.raw.seconds = seconds.part.text;\n  if (macro !== undefined) result.macro = macro;\n  return result;\n}\n","import type { CronAST, FieldAST } from \"../types\";\nimport type { FieldSpec } from \"./fields\";\n\n/** 値に展開できない拡張構文（L / # / W）を含むか。`?` は制約なしなので含めない */\nexport function hasExtension(ast: FieldAST): boolean {\n  switch (ast.kind) {\n    case \"last\":\n    case \"nth\":\n    case \"nearestWeekday\":\n      return true;\n    case \"list\":\n      return ast.items.some(hasExtension);\n    case \"step\":\n      return hasExtension(ast.base);\n    default:\n      return false;\n  }\n}\n\n/** `*` あるいは `?`（＝制約なし）か */\nexport function isAny(ast: FieldAST): boolean {\n  if (ast.kind === \"any\" || ast.kind === \"noSpecific\") return true;\n  if (ast.kind === \"step\") return ast.step === 1 && isAny(ast.base);\n  return false;\n}\n\n/** 表記は違っても、そのフィールドの全値を含むか（`0-6` など） */\nexport function coversAll(ast: FieldAST, spec: FieldSpec): boolean {\n  if (isAny(ast)) return true;\n  if (hasExtension(ast)) return false;\n  return expandField(ast, spec).length === spec.max - spec.min + 1;\n}\n\n/**\n * フィールドの全域に対する刻みなら、その刻み幅を返す。\n * `0-59/5` のように範囲が全域を覆う場合を含み、`*` を base にしたものと同じ意味になる。\n */\nexport function fullRangeStep(ast: FieldAST, spec: FieldSpec): number | undefined {\n  if (ast.kind !== \"step\") return undefined;\n  const base = ast.base;\n  // 刻みは base の下限を起点に数えるため、全値を含んでいても起点が min でなければ\n  // `*` とは値が違う。`1-0/2` は循環して全値を含むが 1,3,5… であり `*/2` ではない\n  const fromMin =\n    isAny(base) || (base.kind === \"range\" && base.from === spec.min && base.to === spec.max);\n  if (!fromMin) return undefined;\n  // 幅を超える刻みは実際には起点で 1 回動くだけなので、「Nごと」とは説明しない\n  if (ast.step > spec.max - spec.min) return undefined;\n  return ast.step;\n}\n\n/**\n * 「AからBまでNごと」と説明できる刻みなら、その範囲と刻み幅を返す。\n * 幅を超える刻みは起点で 1 回動くだけなので、範囲としては説明しない。\n */\nexport function rangeStep(\n  ast: FieldAST,\n  spec: FieldSpec,\n): { from: number; to: number; step: number } | undefined {\n  if (ast.kind !== \"step\" || ast.base.kind !== \"range\") return undefined;\n  const { from, to } = ast.base;\n  const span = spec.max - spec.min + 1;\n  const width = from <= to ? to - from : span - from + to;\n  if (ast.step > width) return undefined;\n  return { from, to, step: ast.step };\n}\n\nfunction rangeValues(from: number, to: number, spec: FieldSpec, step: number): number[] {\n  const values: number[] = [];\n  const span = spec.max - spec.min + 1;\n  // from > to は循環範囲（例: 金-月 = 5-1）として扱う\n  const length = from <= to ? to - from + 1 : span - from + to + 1;\n  for (let i = 0; i < length; i += step) {\n    values.push(spec.min + ((from - spec.min + i) % span));\n  }\n  return values;\n}\n\n/**\n * フィールドの構文木を実際の値へ展開する。\n * 拡張構文（L / # / W）は静的に展開できないため空配列を返す。\n */\nexport function expandField(ast: FieldAST, spec: FieldSpec): number[] {\n  const values = collect(ast, spec);\n  return [...new Set(values)].sort((a, b) => a - b);\n}\n\nfunction collect(ast: FieldAST, spec: FieldSpec): number[] {\n  switch (ast.kind) {\n    case \"any\":\n    case \"noSpecific\":\n      return rangeValues(spec.min, spec.max, spec, 1);\n    case \"value\":\n      return [ast.value];\n    case \"range\":\n      return rangeValues(ast.from, ast.to, spec, 1);\n    case \"step\": {\n      const base = ast.base;\n      if (base.kind === \"range\") return rangeValues(base.from, base.to, spec, ast.step);\n      return rangeValues(spec.min, spec.max, spec, ast.step);\n    }\n    case \"list\":\n      return ast.items.flatMap((item) => collect(item, spec));\n    default:\n      return [];\n  }\n}\n\n/** 構文木を正規化された cron 表記へ戻す */\nexport function formatField(ast: FieldAST): string {\n  switch (ast.kind) {\n    case \"any\":\n      return \"*\";\n    case \"noSpecific\":\n      return \"?\";\n    case \"value\":\n      return String(ast.value);\n    case \"range\":\n      return `${ast.from}-${ast.to}`;\n    case \"step\":\n      return `${formatField(ast.base)}/${ast.step}`;\n    case \"list\":\n      return ast.items.map(formatField).join(\",\");\n    case \"last\":\n      return ast.offset === undefined ? \"L\" : `L-${ast.offset}`;\n    case \"nth\":\n      return ast.nth === -1 ? `${ast.weekday}L` : `${ast.weekday}#${ast.nth}`;\n    case \"nearestWeekday\":\n      return `${ast.day}W`;\n  }\n}\n\n/** 連続した値の並びを範囲に畳む（[1,2,3,5] → [[1,3],[5,5]]） */\nexport function toRanges(values: number[]): Array<[number, number]> {\n  const ranges: Array<[number, number]> = [];\n  for (const value of values) {\n    const last = ranges[ranges.length - 1];\n    if (last !== undefined && value === last[1] + 1) {\n      last[1] = value;\n    } else {\n      ranges.push([value, value]);\n    }\n  }\n  return ranges;\n}\n\n/** 構文木を正規化された cron 式へ戻す */\nexport function formatExpression(ast: CronAST): string {\n  const fields = [ast.minute, ast.hour, ast.dayOfMonth, ast.month, ast.dayOfWeek].map(formatField);\n  if (ast.seconds !== undefined) fields.unshift(formatField(ast.seconds));\n  return fields.join(\" \");\n}\n","import type { NextOptions } from \"../types\";\nimport { DOM_SPEC, DOW_SPEC, HOUR_SPEC, MINUTE_SPEC, MONTH_SPEC, SECOND_SPEC } from \"./fields\";\nimport { parseExpression } from \"./parser\";\nimport { expandField, isAny } from \"./values\";\n\ninterface Parts {\n  year: number;\n  month: number;\n  day: number;\n  hour: number;\n  minute: number;\n  second: number;\n  dayOfWeek: number;\n}\n\n/** 瞬間 → UTC の壁時計 */\nfunction partsOf(date: Date): Parts {\n  return {\n    year: date.getUTCFullYear(),\n    month: date.getUTCMonth() + 1,\n    day: date.getUTCDate(),\n    hour: date.getUTCHours(),\n    minute: date.getUTCMinutes(),\n    second: date.getUTCSeconds(),\n    dayOfWeek: date.getUTCDay(),\n  };\n}\n\n/** UTC の壁時計 → 瞬間。範囲外の値（13 月・32 日・24 時など）は繰り上がる */\nfunction dateOf(\n  year: number,\n  month: number,\n  day: number,\n  hour: number,\n  minute: number,\n  second: number,\n): Date {\n  return new Date(Date.UTC(year, month - 1, day, hour, minute, second, 0));\n}\n\n/** sorted の中で value 以上の最小値。無ければ null */\nfunction atLeast(sorted: number[], value: number): number | null {\n  for (const candidate of sorted) {\n    if (candidate >= value) return candidate;\n  }\n  return null;\n}\n\n/** 5 年先まで探索する */\nconst SEARCH_YEARS = 5;\n\n/** 無限ループを避けるための保険 */\nconst MAX_ITERATIONS = 2_000_000;\n\n/**\n * cron 式の次回実行日時を求める。\n *\n * cron 式は UTC のサーバーで動くものとして解釈する。返るのは絶対時刻なので、\n * どのタイムゾーンで表示するかは呼び出し側の裁量。\n *\n * `L` / `#` / `W` を含む式は v1 では計算対象外で、空配列を返す。\n */\nexport function next(expression: string, options: NextOptions = {}): Date[] {\n  const parserOptions = options.seconds === true ? { seconds: true } : {};\n  const parsed = parseExpression(expression, parserOptions);\n  if (parsed.extensions.some((extension) => extension !== \"?\")) return [];\n\n  const count = options.count ?? 3;\n  if (count <= 0) return [];\n\n  const from = options.from ?? new Date();\n  if (Number.isNaN(from.getTime())) return [];\n\n  const ast = parsed.ast;\n  const seconds = ast.seconds === undefined ? [0] : expandField(ast.seconds, SECOND_SPEC);\n  const minutes = expandField(ast.minute, MINUTE_SPEC);\n  const hours = expandField(ast.hour, HOUR_SPEC);\n  const months = expandField(ast.month, MONTH_SPEC);\n  const days = expandField(ast.dayOfMonth, DOM_SPEC);\n  const weekdays = expandField(ast.dayOfWeek, DOW_SPEC);\n  if ([seconds, minutes, hours, months].some((values) => values.length === 0)) return [];\n\n  const domRestricted = !isAny(ast.dayOfMonth);\n  const dowRestricted = !isAny(ast.dayOfWeek);\n  const daySet = new Set(days);\n  const weekdaySet = new Set(weekdays);\n  const monthSet = new Set(months);\n\n  const dayMatches = (parts: Parts): boolean => {\n    if (domRestricted && dowRestricted) {\n      return daySet.has(parts.day) || weekdaySet.has(parts.dayOfWeek);\n    }\n    if (domRestricted) return daySet.has(parts.day);\n    if (dowRestricted) return weekdaySet.has(parts.dayOfWeek);\n    return true;\n  };\n\n  const startParts = partsOf(from);\n  const limitYear = startParts.year + SEARCH_YEARS;\n\n  // 起点そのものは含めないので 1 秒進めてから秒に丸める\n  const initial = partsOf(new Date(from.getTime() + 1000));\n  let cursor = dateOf(\n    initial.year,\n    initial.month,\n    initial.day,\n    initial.hour,\n    initial.minute,\n    initial.second,\n  );\n\n  const results: Date[] = [];\n  let iterations = 0;\n  while (results.length < count && iterations < MAX_ITERATIONS) {\n    iterations += 1;\n    const parts = partsOf(cursor);\n    if (parts.year > limitYear) break;\n\n    if (!monthSet.has(parts.month)) {\n      cursor = dateOf(parts.year, parts.month + 1, 1, 0, 0, 0);\n      continue;\n    }\n    if (!dayMatches(parts)) {\n      cursor = dateOf(parts.year, parts.month, parts.day + 1, 0, 0, 0);\n      continue;\n    }\n    const hour = atLeast(hours, parts.hour);\n    if (hour === null) {\n      cursor = dateOf(parts.year, parts.month, parts.day + 1, 0, 0, 0);\n      continue;\n    }\n    if (hour !== parts.hour) {\n      cursor = dateOf(parts.year, parts.month, parts.day, hour, 0, 0);\n      continue;\n    }\n    const minute = atLeast(minutes, parts.minute);\n    if (minute === null) {\n      cursor = dateOf(parts.year, parts.month, parts.day, parts.hour + 1, 0, 0);\n      continue;\n    }\n    if (minute !== parts.minute) {\n      cursor = dateOf(parts.year, parts.month, parts.day, parts.hour, minute, 0);\n      continue;\n    }\n    const second = atLeast(seconds, parts.second);\n    if (second === null) {\n      cursor = dateOf(parts.year, parts.month, parts.day, parts.hour, parts.minute + 1, 0);\n      continue;\n    }\n    if (second !== parts.second) {\n      cursor = dateOf(parts.year, parts.month, parts.day, parts.hour, parts.minute, second);\n      continue;\n    }\n\n    results.push(new Date(cursor.getTime()));\n    cursor = new Date(cursor.getTime() + 1000);\n  }\n\n  return results;\n}\n","import { CronTimeZoneError } from \"../errors\";\n\n/**\n * 自然言語（日本語）側の既定のタイムゾーン。\n *\n * cron 式は常に UTC のサーバーで動くものとして扱い、日本語はこのゾーンの壁時計として読む。\n */\nexport const DEFAULT_TIME_ZONE = \"Asia/Tokyo\";\n\n/** 実行環境のタイムゾーンを指す特別な値 */\nexport const LOCAL_TIME_ZONE = \"local\";\n\n/** cron 式が動くサーバーのタイムゾーン。固定 */\nexport const SERVER_TIME_ZONE = \"UTC\";\n\n/**\n * ある瞬間をタイムゾーンで読んだ壁時計。\n */\nexport interface WallClock {\n  year: number;\n  month: number;\n  day: number;\n  hour: number;\n  minute: number;\n  second: number;\n  dayOfWeek: number;\n}\n\n/** Intl.DateTimeFormat の生成は重いのでゾーンごとに使い回す */\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\nfunction formatter(timeZone: string): Intl.DateTimeFormat {\n  const cached = formatters.get(timeZone);\n  if (cached !== undefined) return cached;\n  const created = new Intl.DateTimeFormat(\"en-US\", {\n    timeZone,\n    // hour12: false は環境によって 0 時を 24 と読ませるため h23 を使う\n    hourCycle: \"h23\",\n    year: \"numeric\",\n    month: \"2-digit\",\n    day: \"2-digit\",\n    hour: \"2-digit\",\n    minute: \"2-digit\",\n    second: \"2-digit\",\n  });\n  formatters.set(timeZone, created);\n  return created;\n}\n\n/**\n * `'local'` を実行環境のゾーン名に、未指定を {@link DEFAULT_TIME_ZONE} に解決し、\n * IANA の正規名に揃えて返す。\n *\n * @throws {CronTimeZoneError} 実行環境が知らないゾーン名の場合\n */\nexport function resolveTimeZone(tz?: string): string {\n  if (tz === undefined) return DEFAULT_TIME_ZONE;\n  const requested =\n    tz === LOCAL_TIME_ZONE ? new Intl.DateTimeFormat().resolvedOptions().timeZone : tz;\n  try {\n    return new Intl.DateTimeFormat(\"en-US\", { timeZone: requested }).resolvedOptions().timeZone;\n  } catch {\n    throw new CronTimeZoneError(`タイムゾーン '${tz}' を解釈できません`, tz);\n  }\n}\n\n/** 壁時計を UTC とみなしたミリ秒 */\nfunction asUtc(wall: WallClock): number {\n  return Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute, wall.second);\n}\n\n/** その瞬間の壁時計と、そのときのゾーンオフセット(分) */\nexport function wallClockWithOffset(\n  timeZone: string,\n  date: Date,\n): { wall: WallClock; offset: number } {\n  const found: Record<string, string> = {};\n  for (const part of formatter(timeZone).formatToParts(date)) {\n    if (part.type !== \"literal\") found[part.type] = part.value;\n  }\n  const year = Number(found.year);\n  const month = Number(found.month);\n  const day = Number(found.day);\n  const wall: WallClock = {\n    year,\n    month,\n    day,\n    // h23 でも 24 を返す実装が過去にあったため丸めておく\n    hour: Number(found.hour) % 24,\n    minute: Number(found.minute),\n    second: Number(found.second),\n    // 曜日は暦から求める。ICU の短縮形に依存すると、読めない綴りを黙って日曜にしてしまう\n    dayOfWeek: new Date(Date.UTC(year, month - 1, day)).getUTCDay(),\n  };\n  return { wall, offset: (asUtc(wall) - Math.floor(date.getTime() / 1000) * 1000) / 60_000 };\n}\n\n/** その瞬間のゾーンオフセット(分)。UTC より東が正 */\nfunction offsetMinutes(timeZone: string, date: Date): number {\n  return wallClockWithOffset(timeZone, date).offset;\n}\n\n/**\n * 壁時計 → 瞬間。オフセットを 2 回反復して収束させる。\n *\n * 夏時間の境界にあたる壁時計では厳密には決まらないが、探索の起点にしか使わないので\n * 近い側に寄せれば足りる。\n */\nexport function instantAt(\n  timeZone: string,\n  year: number,\n  month: number,\n  day: number,\n  hour: number,\n  minute: number,\n  second: number,\n): Date {\n  const guess = Date.UTC(year, month - 1, day, hour, minute, second);\n  const first = guess - offsetMinutes(timeZone, new Date(guess)) * 60_000;\n  return new Date(guess - offsetMinutes(timeZone, new Date(first)) * 60_000);\n}\n\nconst fixedOffsets = new Map<string, number>();\n\n/**\n * 変わらないゾーンオフセット(分)を返す。\n *\n * cron 式の書き換えは固定のオフセットでしか行えないため、オフセットが動くゾーンは\n * ここで弾く。書き換えた式は crontab に貼られたあと何年も動き続けるので、\n * 今年だけでなく**翌年まで**を 1 か月ごとにサンプルして、すべて同じであることを確かめる\n * （夏時間を来年から始める国を今年のぶんだけ見て通すと、半年ずれた式を黙って出すことになる）。\n *\n * @throws {CronTimeZoneError} 期間内でオフセットが変わる場合\n */\nexport function fixedOffsetMinutes(timeZone: string, reference: Date = new Date()): number {\n  const year = reference.getUTCFullYear();\n  const key = `${timeZone}@${year}`;\n  const cached = fixedOffsets.get(key);\n  if (cached !== undefined) return cached;\n\n  const offsets = new Set<number>();\n  for (let month = 0; month < 24; month += 1) {\n    offsets.add(offsetMinutes(timeZone, new Date(Date.UTC(year, month, 15, 12))));\n  }\n  const [offset] = [...offsets];\n  if (offsets.size > 1 || offset === undefined) {\n    throw new CronTimeZoneError(\n      `${timeZone} は ${year}-${year + 1} 年にオフセットが変わる（夏時間など）ため、` +\n        \"cron 式を固定のオフセットに書き換えられません\",\n      timeZone,\n    );\n  }\n  fixedOffsets.set(key, offset);\n  return offset;\n}\n","import { CronTimeZoneError } from \"../errors\";\nimport type { CronAST, FieldAST, ParserOptions } from \"../types\";\nimport { DOM_SPEC, DOW_SPEC, type FieldSpec, HOUR_SPEC, MINUTE_SPEC, MONTH_SPEC } from \"./fields\";\nimport { parseExpression } from \"./parser\";\nimport { coversAll, expandField, formatExpression, hasExtension, isAny, toRanges } from \"./values\";\nimport { fixedOffsetMinutes, SERVER_TIME_ZONE } from \"./zone\";\n\n/**\n * 書き換えの向き。\n * - `'toLocal'`: cron 式(UTC) → `timeZone` の壁時計（explain）\n * - `'toServer'`: `timeZone` の壁時計 → cron 式(UTC)（parse）\n */\nexport type ShiftDirection = \"toLocal\" | \"toServer\";\n\nconst MINUTES_PER_DAY = 1440;\n\n/** 日をまたぐ書き換えが月の長さに左右されないのは 1-28 日の範囲だけ */\nconst SAFE_DAY_MIN = 1;\nconst SAFE_DAY_MAX = 28;\n\nfunction mod(value: number, size: number): number {\n  return ((value % size) + size) % size;\n}\n\nfunction sorted(values: Iterable<number>): number[] {\n  return [...new Set(values)].sort((a, b) => a - b);\n}\n\nfunction sameValues(left: number[], right: number[]): boolean {\n  return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\n/** 「+9:00」「-4:30」 */\nfunction formatOffset(minutes: number): string {\n  const absolute = Math.abs(minutes);\n  const hour = Math.floor(absolute / 60);\n  const minute = absolute % 60;\n  return `${minutes < 0 ? \"-\" : \"+\"}${hour}:${String(minute).padStart(2, \"0\")}`;\n}\n\n/**\n * 値の並びから、なるべく自然な構文木を組み立てる。\n *\n * 連番は範囲に、等間隔は刻みに畳む。説明文の質がここで決まる\n * （`1,3,5,…,23` を並べ立てず `1-23/2` にする）。\n */\nfunction fromValues(values: number[], spec: FieldSpec): FieldAST {\n  const first = values[0];\n  const last = values[values.length - 1];\n  /* c8 ignore next -- 呼び出し側が空配列を渡さない */\n  if (first === undefined || last === undefined) return { kind: \"any\" };\n  if (values.length === spec.max - spec.min + 1) return { kind: \"any\" };\n  if (values.length === 1) return { kind: \"value\", value: first };\n\n  const step = (values[1] as number) - first;\n  const evenlySpaced =\n    values.length > 2 &&\n    step > 1 &&\n    values.every((value, index) => index === 0 || value - (values[index - 1] as number) === step);\n  if (evenlySpaced) {\n    // 下限から刻んで上限に届いているなら `*/N`。`0-22/2` より `*/2` の方が説明しやすい\n    const fromMin = first === spec.min && last + step > spec.max;\n    const base: FieldAST = fromMin ? { kind: \"any\" } : { kind: \"range\", from: first, to: last };\n    return { kind: \"step\", base, step };\n  }\n\n  const items = toRanges(values).map(\n    ([from, to]): FieldAST =>\n      from === to ? { kind: \"value\", value: from } : { kind: \"range\", from, to },\n  );\n  return items.length === 1 ? (items[0] as FieldAST) : { kind: \"list\", items };\n}\n\n/**\n * cron 式(UTC) と `timeZone` の壁時計の間で、フィールドをずらす。\n *\n * cron 式は「フィールドごとに独立した値の集合」しか表せないので、ずらした結果が\n * その形に収まらない場合は書き換えられない。収まらないまま近い式を返すと、\n * 半年ずれた予定を黙って出すことになるため {@link CronTimeZoneError} で失敗させる。\n *\n * @throws {CronTimeZoneError} ゾーンのオフセットが動く、または結果が cron 式で表せない場合\n */\nexport function shiftAst(ast: CronAST, timeZone: string, direction: ShiftDirection): CronAST {\n  // UTC のままなら書き換えも夏時間の検査も要らない\n  if (timeZone === SERVER_TIME_ZONE) return ast;\n\n  const zoneOffset = fixedOffsetMinutes(timeZone);\n  const deltaMinutes = direction === \"toLocal\" ? zoneOffset : -zoneOffset;\n  if (deltaMinutes === 0) return ast;\n\n  // 表示するのは常にゾーンのオフセット。向きによって符号が変わると読み手が混乱する\n  const offset = formatOffset(zoneOffset);\n  const fail = (reason: string): never => {\n    throw new CronTimeZoneError(`${timeZone}（時差 ${offset}）では${reason}`, timeZone);\n  };\n\n  const minutes = expandField(ast.minute, MINUTE_SPEC);\n  const hours = expandField(ast.hour, HOUR_SPEC);\n  if (minutes.length === 0 || hours.length === 0) {\n    return fail(\"分・時のフィールドを展開できないため、cron 式に書き換えられません\");\n  }\n\n  // 1 日の中の分（0-1439）に直してからずらす\n  const moved = new Set<number>();\n  const carries = new Set<number>();\n  for (const hour of hours) {\n    for (const minute of minutes) {\n      const value = hour * 60 + minute + deltaMinutes;\n      moved.add(mod(value, MINUTES_PER_DAY));\n      carries.add(Math.floor(value / MINUTES_PER_DAY));\n    }\n  }\n\n  const newMinutes = sorted([...moved].map((value) => value % 60));\n  const newHours = sorted([...moved].map((value) => Math.floor(value / 60)));\n  // cron の分と時は独立した集合なので、直積に戻らない組み合わせは表せない\n  if (newMinutes.length * newHours.length !== moved.size) {\n    return fail(\n      \"分と時の組み合わせが崩れるため、cron 式に書き換えられません\" +\n        \"（分の繰り上がりが時刻によって変わります）\",\n    );\n  }\n\n  // 日と曜日が「指定されているか」は書き方で決まる（`*` / `?` だけが指定なし）。\n  // `0-6` のように全域を覆っていても、標準の cron では OR 条件の一方として数える。\n  // ここで coversAll を使うと、毎日動く式を「15 日だけ」と見て日をずらしてしまう\n  const domRestricted = !isAny(ast.dayOfMonth);\n  const dowRestricted = !isAny(ast.dayOfWeek);\n  const monthRestricted = !coversAll(ast.month, MONTH_SPEC);\n  const everyDay = !domRestricted && !dowRestricted && !monthRestricted;\n\n  const [onlyCarry] = [...carries];\n  const dayShift = carries.size === 1 && onlyCarry !== undefined ? onlyCarry : null;\n  if (dayShift === null && !everyDay) {\n    return fail(\"日付をまたぐ時刻とまたがない時刻が混ざるため、cron 式に書き換えられません\");\n  }\n\n  let dayOfMonth = ast.dayOfMonth;\n  let dayOfWeek = ast.dayOfWeek;\n  if (dayShift !== null && dayShift !== 0 && !everyDay) {\n    if (hasExtension(ast.dayOfMonth) || hasExtension(ast.dayOfWeek)) {\n      return fail(\"日付が 1 日ずれるため、L / # / W を含む式は書き換えられません\");\n    }\n    // 月フィールドが絞られていると、月末の実行が翌月へこぼれる。\n    // 日で絞られていて月をまたがないと分かっている場合だけ通す\n    if (monthRestricted && (!domRestricted || dowRestricted)) {\n      return fail(\"日付が 1 日ずれて月をまたぐため、cron 式に書き換えられません\");\n    }\n    if (domRestricted) {\n      const days = expandField(ast.dayOfMonth, DOM_SPEC);\n      const shiftedDays = days.map((day) => day + dayShift);\n      // 29-31 日は月によって存在したりしなかったりするので、ずらすと意味が変わる\n      const safe = days.every(\n        (day, index) =>\n          day <= SAFE_DAY_MAX &&\n          (shiftedDays[index] as number) >= SAFE_DAY_MIN &&\n          (shiftedDays[index] as number) <= SAFE_DAY_MAX,\n      );\n      if (!safe) {\n        return fail(\n          \"日付が 1 日ずれて月をまたぐ可能性があるため、cron 式に書き換えられません\" +\n            \"（1-28 日の範囲に収まる指定であれば書き換えられます）\",\n        );\n      }\n      dayOfMonth = fromValues(shiftedDays, DOM_SPEC);\n    }\n    if (dowRestricted) {\n      const weekdays = expandField(ast.dayOfWeek, DOW_SPEC);\n      dayOfWeek = fromValues(sorted(weekdays.map((day) => mod(day + dayShift, 7))), DOW_SPEC);\n    }\n  }\n\n  return {\n    ...ast,\n    minute: sameValues(newMinutes, minutes) ? ast.minute : fromValues(newMinutes, MINUTE_SPEC),\n    hour: sameValues(newHours, hours) ? ast.hour : fromValues(newHours, HOUR_SPEC),\n    dayOfMonth,\n    dayOfWeek,\n  };\n}\n\n/**\n * cron 式の文字列を {@link shiftAst} と同じ規則でずらす。\n *\n * @throws {CronSyntaxError} 式が不正な場合\n * @throws {CronTimeZoneError} ゾーンのオフセットが動く、または結果が cron 式で表せない場合\n */\nexport function shiftExpression(\n  expression: string,\n  timeZone: string,\n  direction: ShiftDirection,\n  options: ParserOptions = {},\n): string {\n  if (timeZone === SERVER_TIME_ZONE) return expression;\n  const { ast } = parseExpression(expression, options);\n  return formatExpression(shiftAst(ast, timeZone, direction));\n}\n","import { CronSyntaxError } from \"../errors\";\nimport type { ParserOptions, ValidationError, ValidationResult } from \"../types\";\nimport { DOM_SPEC, MONTH_SPEC } from \"./fields\";\nimport { parseExpression } from \"./parser\";\nimport { expandField, hasExtension, isAny } from \"./values\";\n\nconst DAYS_IN_MONTH = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst MONTH_LABELS = [\n  \"1月\",\n  \"2月\",\n  \"3月\",\n  \"4月\",\n  \"5月\",\n  \"6月\",\n  \"7月\",\n  \"8月\",\n  \"9月\",\n  \"10月\",\n  \"11月\",\n  \"12月\",\n];\n\n/**\n * cron 式を検証する。構文エラーは throw せず {@link ValidationResult} として返す。\n */\nexport function validate(expression: string, options: ParserOptions = {}): ValidationResult {\n  const errors: ValidationError[] = [];\n  const warnings: string[] = [];\n\n  let parsed: ReturnType<typeof parseExpression>;\n  try {\n    parsed = parseExpression(expression, options);\n  } catch (error) {\n    if (error instanceof CronSyntaxError) {\n      const entry: ValidationError = {\n        field: error.field ?? \"expression\",\n        message: error.message,\n      };\n      if (error.position !== undefined) entry.position = error.position;\n      errors.push(entry);\n      return { valid: false, errors, warnings };\n    }\n    /* c8 ignore next 2 -- parseExpression は CronSyntaxError しか投げない */\n    throw error;\n  }\n\n  const { ast, extensions } = parsed;\n\n  if (extensions.includes(\"L\") || extensions.includes(\"#\") || extensions.includes(\"W\")) {\n    const used = extensions.filter((extension) => extension !== \"?\").join(\"', '\");\n    warnings.push(`'${used}' は Quartz 拡張です。標準の cron（Vixie cron）では動作しません`);\n    warnings.push(\"拡張構文を含む式では次回実行日時（next）を計算できません\");\n  }\n\n  if (!isAny(ast.dayOfMonth) && !isAny(ast.dayOfWeek)) {\n    warnings.push(\n      \"標準の cron では日と曜日を同時に指定すると OR 条件になり、どちらかに一致する日に実行されます\",\n    );\n  }\n\n  if (\n    !isAny(ast.month) &&\n    !isAny(ast.dayOfMonth) &&\n    !hasExtension(ast.dayOfMonth) &&\n    !hasExtension(ast.month)\n  ) {\n    const months = expandField(ast.month, MONTH_SPEC);\n    const days = expandField(ast.dayOfMonth, DOM_SPEC);\n    const impossible: string[] = [];\n    let anyPossible = false;\n    for (const month of months) {\n      const limit = DAYS_IN_MONTH[month - 1] ?? 31;\n      for (const day of days) {\n        if (day <= limit) {\n          anyPossible = true;\n        } else {\n          impossible.push(`${MONTH_LABELS[month - 1] ?? `${month}月`}${day}日`);\n        }\n      }\n    }\n    if (!anyPossible && impossible.length > 0) {\n      warnings.push(`${impossible.join(\"、\")}は存在しないため、このジョブは実行されません`);\n    } else if (impossible.length > 0) {\n      warnings.push(`${impossible.join(\"、\")}は存在しないため、その日は実行されません`);\n    }\n    if (months.includes(2) && days.includes(29)) {\n      warnings.push(\"2月29日はうるう年にのみ実行されます\");\n    }\n  }\n\n  return { valid: true, errors, warnings };\n}\n","export interface TimeStyle {\n  style: \"casual\" | \"formal\";\n  hour: \"12h\" | \"24h\";\n}\n\nfunction pad2(value: number): string {\n  return value < 10 ? `0${value}` : String(value);\n}\n\n/**\n * 「午前9時」「15時」のように時だけを表す。\n */\nexport function formatHour(hour: number, style: TimeStyle): string {\n  if (style.hour === \"24h\") return `${hour}時`;\n  if (hour < 12) return `午前${hour}時`;\n  return `午後${hour - 12}時`;\n}\n\n/**\n * 「午前9時」「午後6時30分」「正午」のように時刻を表す。\n */\nexport function formatTime(hour: number, minute: number, style: TimeStyle): string {\n  if (style.style === \"casual\" && style.hour === \"12h\" && hour === 12 && minute === 0) {\n    return \"正午\";\n  }\n  const base = formatHour(hour, style);\n  if (style.style === \"formal\") return `${base}${pad2(minute)}分`;\n  return minute === 0 ? base : `${base}${minute}分`;\n}\n","import {\n  DOM_SPEC,\n  DOW_LABELS,\n  DOW_SPEC,\n  HOUR_SPEC,\n  MINUTE_SPEC,\n  MONTH_SPEC,\n  SECOND_SPEC,\n} from \"../cron/fields\";\nimport {\n  coversAll,\n  expandField,\n  fullRangeStep,\n  hasExtension,\n  rangeStep,\n  toRanges,\n} from \"../cron/values\";\nimport type { FieldAST } from \"../types\";\nimport { formatHour, type TimeStyle } from \"./time\";\n\n/** 「AとB」「A、B、C」 */\nexport function joinJa(items: string[]): string {\n  if (items.length === 0) return \"\";\n  if (items.length === 1) return items[0] ?? \"\";\n  if (items.length === 2) return `${items[0]}と${items[1]}`;\n  return items.join(\"、\");\n}\n\n/**\n * 値の並びを、連続部分を範囲に畳みながら日本語にする。\n */\nexport function describeValues(\n  values: number[],\n  point: (value: number) => string,\n  range: (from: number, to: number) => string,\n): string {\n  const texts: string[] = [];\n  for (const [from, to] of toRanges(values)) {\n    // 3 個以上連続している場合のみ範囲に畳む\n    if (to - from >= 2) {\n      texts.push(range(from, to));\n    } else {\n      for (let value = from; value <= to; value++) texts.push(point(value));\n    }\n  }\n  return joinJa(texts);\n}\n\nexport function describeMinuteValues(ast: FieldAST): string {\n  const values = expandField(ast, MINUTE_SPEC);\n  return describeValues(\n    values,\n    (value) => `${value}分`,\n    (from, to) => `${from}分から${to}分まで`,\n  );\n}\n\n/** 分フィールドの、時と組み合わせるための表現 */\nexport type MinutePart =\n  | { kind: \"any\" }\n  | { kind: \"step\"; text: string }\n  | { kind: \"rangeStep\"; from: number; to: number; step: number }\n  | { kind: \"single\"; value: number }\n  | { kind: \"values\"; text: string };\n\n/**\n * 分フィールドを、文の組み立てに使える形に分解する。\n * 文単位（`compose.ts`）とフィールド単位（{@link describeMinuteField}）で\n * 同じ規則を使うため、判定はここだけに置く。\n */\nexport function minutePart(ast: FieldAST): MinutePart {\n  if (coversAll(ast, MINUTE_SPEC)) return { kind: \"any\" };\n  const step = fullRangeStep(ast, MINUTE_SPEC);\n  if (step !== undefined) return { kind: \"step\", text: `${step}分ごと` };\n  const ranged = rangeStep(ast, MINUTE_SPEC);\n  if (ranged !== undefined) return { kind: \"rangeStep\", ...ranged };\n  const values = expandField(ast, MINUTE_SPEC);\n  const first = values[0];\n  if (values.length === 1 && first !== undefined) return { kind: \"single\", value: first };\n  return { kind: \"values\", text: describeMinuteValues(ast) };\n}\n\n/** 前に何も置かずに単独で読める分の表現 */\nexport function minuteBare(part: MinutePart): string {\n  switch (part.kind) {\n    case \"any\":\n      return \"毎分\";\n    case \"step\":\n      return part.text;\n    case \"rangeStep\":\n      return `${part.from}分から${part.to}分まで${part.step}分ごと`;\n    case \"single\":\n      return `${part.value}分`;\n    case \"values\":\n      return part.text;\n  }\n}\n\n/**\n * 時の節に続けるときの、時の中での分の表現。\n * 刻みは時をまたがないので、上限が 59 分なら「59分まで」は何も足さない。\n * 時の範囲の「まで」と重なって読みにくくするだけなので落とす。\n */\nexport function minuteWithinHour(part: MinutePart): string {\n  if (part.kind !== \"rangeStep\") return minuteBare(part);\n  const { from, to, step } = part;\n  if (to === MINUTE_SPEC.max) return `${from}分から${step}分ごと`;\n  return `${from}分から${to}分まで${step}分ごと`;\n}\n\n/** 分フィールドの説明。全域は「毎分」、ステップ指定は「N分ごと」 */\nexport function describeMinuteField(ast: FieldAST): string {\n  return minuteBare(minutePart(ast));\n}\n\nexport function describeSecondField(ast: FieldAST): string {\n  if (coversAll(ast, SECOND_SPEC)) return \"毎秒\";\n  const step = fullRangeStep(ast, SECOND_SPEC);\n  if (step !== undefined) return `${step}秒ごと`;\n  const values = expandField(ast, SECOND_SPEC);\n  return describeValues(\n    values,\n    (value) => `${value}秒`,\n    (from, to) => `${from}秒から${to}秒まで`,\n  );\n}\n\nexport function describeHourValues(ast: FieldAST, style: TimeStyle): string {\n  const values = expandField(ast, HOUR_SPEC);\n  return describeValues(\n    values,\n    (value) => formatHour(value, style),\n    (from, to) => `${formatHour(from, style)}から${formatHour(to, style)}まで`,\n  );\n}\n\nexport function describeHourField(ast: FieldAST, style: TimeStyle): string {\n  if (coversAll(ast, HOUR_SPEC)) return \"毎時\";\n  const step = fullRangeStep(ast, HOUR_SPEC);\n  if (step !== undefined) return `${step}時間ごと`;\n  const ranged = rangeStep(ast, HOUR_SPEC);\n  if (ranged !== undefined) {\n    const from = formatHour(ranged.from, style);\n    const to = formatHour(ranged.to, style);\n    return `${from}から${to}まで${ranged.step}時間ごと`;\n  }\n  return describeHourValues(ast, style);\n}\n\nexport function describeMonthField(ast: FieldAST): string {\n  if (coversAll(ast, MONTH_SPEC)) return \"毎月\";\n  const step = fullRangeStep(ast, MONTH_SPEC);\n  if (step !== undefined) return `${step}か月ごと`;\n  const values = expandField(ast, MONTH_SPEC);\n  return describeValues(\n    values,\n    (value) => `${value}月`,\n    (from, to) => `${from}月から${to}月まで`,\n  );\n}\n\nexport function describeDayOfMonthField(ast: FieldAST): string {\n  if (coversAll(ast, DOM_SPEC)) return \"毎日\";\n  if (ast.kind === \"last\") {\n    return ast.offset === undefined ? \"月末\" : `月末の${ast.offset}日前`;\n  }\n  if (ast.kind === \"nearestWeekday\") return `${ast.day}日に最も近い平日`;\n  // parse 側が「1日から3日ごと」を解釈できず往復が壊れるため、起点は明示しない。\n  // 「毎月」が前置されるので、月をまたいで数え直す点は文脈から読み取れる。\n  const step = fullRangeStep(ast, DOM_SPEC);\n  if (step !== undefined) return `${step}日ごと`;\n  if (ast.kind === \"list\" && hasExtension(ast)) {\n    return joinJa(ast.items.map(describeDayOfMonthField));\n  }\n  const values = expandField(ast, DOM_SPEC);\n  return describeValues(\n    values,\n    (value) => `${value}日`,\n    (from, to) => `${from}日から${to}日まで`,\n  );\n}\n\nexport interface DowOptions {\n  /** 「毎週」を前置するか */\n  weekly: boolean;\n  /** 「平日」「週末」に畳むか */\n  collapse: boolean;\n}\n\nfunction dowLabel(value: number): string {\n  return DOW_LABELS[value] ?? `${value}`;\n}\n\nexport function describeDayOfWeekField(ast: FieldAST, options: DowOptions): string {\n  if (ast.kind === \"any\" || ast.kind === \"noSpecific\") return \"毎日\";\n  if (ast.kind === \"nth\") {\n    const label = dowLabel(ast.weekday);\n    return ast.nth === -1 ? `最終${label}` : `第${ast.nth}${label}`;\n  }\n  if (ast.kind === \"list\" && hasExtension(ast)) {\n    return joinJa(\n      ast.items.map((item) => describeDayOfWeekField(item, { ...options, weekly: false })),\n    );\n  }\n\n  const values = expandField(ast, DOW_SPEC);\n  if (values.length === 7) return \"毎日\";\n  if (options.collapse) {\n    const key = values.join(\",\");\n    if (key === \"1,2,3,4,5\") return \"平日\";\n    if (key === \"0,6\") return \"週末\";\n  }\n  const text = describeValues(\n    values,\n    dowLabel,\n    (from, to) => `${dowLabel(from)}から${dowLabel(to)}まで`,\n  );\n  return options.weekly ? `毎週${text}` : text;\n}\n","import {\n  DOM_SPEC,\n  DOW_SPEC,\n  HOUR_SPEC,\n  MINUTE_SPEC,\n  MONTH_SPEC,\n  SECOND_SPEC,\n} from \"../cron/fields\";\nimport { coversAll, expandField, fullRangeStep, isAny, rangeStep, toRanges } from \"../cron/values\";\nimport type { CronAST } from \"../types\";\nimport {\n  describeDayOfMonthField,\n  describeDayOfWeekField,\n  describeHourValues,\n  describeMonthField,\n  describeSecondField,\n  joinJa,\n  type MinutePart,\n  minuteBare,\n  minutePart,\n  minuteWithinHour,\n} from \"./field\";\nimport { formatHour, formatTime, type TimeStyle } from \"./time\";\n\nexport interface ComposeOptions extends TimeStyle {\n  collapseWeekdays: boolean;\n}\n\n/** 「毎分」「15分ごと」「毎時0分」のように、時を限定しない文での分の表現 */\nfunction minuteAlone(part: MinutePart): string {\n  switch (part.kind) {\n    case \"any\":\n    case \"step\":\n    case \"rangeStep\":\n      return minuteBare(part);\n    case \"single\":\n      return `毎時${part.value}分`;\n    case \"values\":\n      return `毎時${part.text}`;\n  }\n}\n\n/**\n * 時の節に続けるときの分の表現。\n * 「AからBまでNごと」を自己完結した形のまま置くと、時の範囲の「まで」と重なって\n * 「午前9時から午後5時まで5分から59分まで15分ごと」のように読めなくなる。\n * 「毎時」で分の節の始まりを示し、時の中での位置として組み立てる。\n */\nfunction minuteAfterHours(part: MinutePart): string {\n  if (part.kind === \"rangeStep\") return `毎時${minuteWithinHour(part)}`;\n  return minuteAlone(part);\n}\n\nexport interface TimeDescription {\n  text: string;\n  /** 「毎分」「N分ごと」のように頻度そのものを表す表現か */\n  frequency: boolean;\n}\n\n/**\n * 時刻部分を組み立てる。\n */\nexport function describeTime(ast: CronAST, options: ComposeOptions): TimeDescription {\n  const minute = minutePart(ast.minute);\n  const hour = ast.hour;\n  let result: TimeDescription;\n\n  const hourStep = fullRangeStep(hour, HOUR_SPEC);\n  const hourRange = rangeStep(hour, HOUR_SPEC);\n\n  if (coversAll(hour, HOUR_SPEC)) {\n    result = { text: minuteAlone(minute), frequency: true };\n  } else if (hourStep !== undefined) {\n    result = { text: `${hourStep}時間ごと（${minuteAfterHours(minute)}）`, frequency: true };\n  } else if (hourRange !== undefined) {\n    const from = formatHour(hourRange.from, options);\n    const to = formatHour(hourRange.to, options);\n    const step = `${hourRange.step}時間ごと（${minuteAfterHours(minute)}）`;\n    result = { text: `${from}から${to}まで${step}`, frequency: false };\n  } else {\n    const values = expandField(hour, HOUR_SPEC);\n    const ranges = toRanges(values);\n    // describeHourValues は 3 個以上連続したときだけ範囲に畳む。同じ閾値で判定しないと、\n    // 12,13 のような 2 個の連なりが「範囲になった」扱いのまま点として並び、\n    // 「午後0時と午後1時毎時0分」のように接続が抜けた文になる\n    const allPoints = ranges.every(([from, to]) => to - from < 2);\n    if (allPoints && minute.kind === \"single\") {\n      result = {\n        text: joinJa(values.map((value) => formatTime(value, minute.value, options))),\n        frequency: false,\n      };\n    } else if (allPoints) {\n      // 「台」は各時に付ける。「午後2時と午後6時台」では 2 時に掛からない\n      const hours = joinJa(values.map((value) => `${formatHour(value, options)}台`));\n      // 「台」自体が時の中を指すので、ここでは「毎時」を前置しない\n      result = { text: `${hours}の${minuteWithinHour(minute)}`, frequency: false };\n    } else {\n      result = {\n        text: `${describeHourValues(hour, options)}${minuteAfterHours(minute)}`,\n        frequency: false,\n      };\n    }\n  }\n\n  const seconds = ast.seconds;\n  if (seconds === undefined) return result;\n  // 「0 秒ちょうど」は既定の挙動なので触れない\n  if (seconds.kind === \"value\" && seconds.value === 0) return result;\n\n  if (coversAll(ast.hour, HOUR_SPEC) && coversAll(ast.minute, MINUTE_SPEC)) {\n    if (coversAll(seconds, SECOND_SPEC)) return { text: \"毎秒\", frequency: true };\n    const secondStep = fullRangeStep(seconds, SECOND_SPEC);\n    if (secondStep !== undefined) return { text: `${secondStep}秒ごと`, frequency: true };\n  }\n  return { text: `${result.text}の${describeSecondField(seconds)}`, frequency: result.frequency };\n}\n\nexport interface DateDescription {\n  text: string;\n  /** 時刻表現と「の」で繋ぐか */\n  joinWithNo: boolean;\n  /** 日付を一切限定していないか */\n  everyDay: boolean;\n}\n\n/**\n * 日付部分を組み立てる。\n */\nexport function describeDate(ast: CronAST, options: ComposeOptions): DateDescription {\n  const domAll = coversAll(ast.dayOfMonth, DOM_SPEC);\n  const monthAny = coversAll(ast.month, MONTH_SPEC);\n  const dowAll = coversAll(ast.dayOfWeek, DOW_SPEC);\n\n  // 標準の cron では、日と曜日を「両方とも」指定すると OR 条件になる（`*` / `?` は指定と\n  // 見なさない）。片方が全域を覆っていれば、もう片方が何であれ毎日一致する。\n  // `0 0 15 * 0-7` は「毎月15日」ではなく毎日動く\n  const orCoversEveryDay = !isAny(ast.dayOfMonth) && !isAny(ast.dayOfWeek) && (domAll || dowAll);\n  const domAny = domAll || orCoversEveryDay;\n  const dowAny = dowAll || orCoversEveryDay;\n\n  if (domAny && monthAny && dowAny) {\n    return { text: \"毎日\", joinWithNo: false, everyDay: true };\n  }\n\n  const monthText = describeMonthField(ast.month);\n\n  if (domAny && !dowAny) {\n    const dow = describeDayOfWeekField(ast.dayOfWeek, {\n      weekly: true,\n      collapse: options.collapseWeekdays,\n    });\n    const text = monthAny ? dow : `${monthText}の${dow}`;\n    return { text, joinWithNo: true, everyDay: false };\n  }\n\n  if (!domAny && dowAny) {\n    const dom = describeDayOfMonthField(ast.dayOfMonth);\n    if (monthAny) return { text: `毎月${dom}`, joinWithNo: true, everyDay: false };\n    if (ast.month.kind === \"value\" && ast.dayOfMonth.kind === \"value\") {\n      return { text: `毎年${monthText}${dom}`, joinWithNo: true, everyDay: false };\n    }\n    return { text: `${monthText}の${dom}`, joinWithNo: true, everyDay: false };\n  }\n\n  if (!domAny && !dowAny) {\n    const dom = describeDayOfMonthField(ast.dayOfMonth);\n    const dow = describeDayOfWeekField(ast.dayOfWeek, {\n      weekly: false,\n      collapse: options.collapseWeekdays,\n    });\n    const base = monthAny\n      ? `毎月${dom}`\n      : ast.month.kind === \"value\" && ast.dayOfMonth.kind === \"value\"\n        ? `毎年${monthText}${dom}`\n        : `${monthText}の${dom}`;\n    return { text: `${base}および${dow}`, joinWithNo: true, everyDay: false };\n  }\n\n  // 月だけが指定されている\n  return { text: `${monthText}の毎日`, joinWithNo: false, everyDay: false };\n}\n\n/**\n * 日付部分と時刻部分を 1 文に組み立てる。\n */\nexport function compose(ast: CronAST, options: ComposeOptions): string {\n  const time = describeTime(ast, options);\n  const date = describeDate(ast, options);\n  if (date.everyDay && time.frequency) return time.text;\n  return `${date.text}${date.joinWithNo ? \"の\" : \"\"}${time.text}`;\n}\n","import {\n  DOM_SPEC,\n  DOW_SPEC,\n  expandField,\n  type FieldSpec,\n  formatExpression,\n  formatField,\n  HOUR_SPEC,\n  hasExtension,\n  MINUTE_SPEC,\n  MONTH_SPEC,\n  next,\n  parseExpression,\n  resolveTimeZone,\n  SECOND_SPEC,\n  shiftAst,\n  validate,\n} from \"../cron\";\nimport type {\n  ExplainOptions,\n  Explanation,\n  FieldAST,\n  FieldExplanation,\n  ParserOptions,\n} from \"../types\";\nimport type { ComposeOptions } from \"./compose\";\nimport { compose } from \"./compose\";\nimport {\n  describeDayOfMonthField,\n  describeDayOfWeekField,\n  describeHourField,\n  describeMinuteField,\n  describeMonthField,\n  describeSecondField,\n} from \"./field\";\n\nfunction resolve(options: ExplainOptions): ComposeOptions {\n  return {\n    style: options.style ?? \"casual\",\n    hour: options.hour ?? \"12h\",\n    collapseWeekdays: options.collapseWeekdays ?? true,\n  };\n}\n\nfunction parserOptions(options: ExplainOptions): ParserOptions {\n  return options.seconds === true ? { seconds: true } : {};\n}\n\n/**\n * cron 式を 1 文の日本語に変換する。\n *\n * 式は UTC のサーバーで動くものとして読み、`options.tz`（既定 `'Asia/Tokyo'`）の\n * 壁時計に直してから日本語にする。\n *\n * ```ts\n * explain('0 4 * * 1-5'); // '平日の午後1時'（UTC 04:00 = JST 13:00）\n * explain('0 9 * * 1-5', { tz: 'UTC' }); // '平日の午前9時'（変換しない）\n * ```\n *\n * @throws {CronSyntaxError} 式が不正な場合\n * @throws {CronTimeZoneError} `tz` を解釈できない、または cron 式に書き換えられない場合\n */\nexport function explain(expression: string, options: ExplainOptions = {}): string {\n  const parsed = parseExpression(expression, parserOptions(options));\n  const timeZone = resolveTimeZone(options.tz);\n  const text = compose(shiftAst(parsed.ast, timeZone, \"toLocal\"), resolve(options));\n  return options.showTimeZone === true ? `${text}（${timeZone}）` : text;\n}\n\nfunction kindOf(ast: FieldAST): FieldExplanation[\"kind\"] {\n  if (hasExtension(ast) || ast.kind === \"noSpecific\") return \"extension\";\n  switch (ast.kind) {\n    case \"any\":\n      return \"any\";\n    case \"value\":\n      return \"value\";\n    case \"range\":\n      return \"range\";\n    case \"step\":\n      return \"step\";\n    case \"list\":\n      return \"list\";\n    /* c8 ignore next 2 -- 拡張構文は上で処理済み */\n    default:\n      return \"extension\";\n  }\n}\n\nfunction explainField(raw: string, ast: FieldAST, spec: FieldSpec, text: string): FieldExplanation {\n  return {\n    raw,\n    kind: kindOf(ast),\n    values: hasExtension(ast) ? [] : expandField(ast, spec),\n    text,\n  };\n}\n\n/**\n * cron 式をフィールド別の内訳・注意書き・次回実行日時つきで説明する。\n *\n * `fields` は `options.tz` の壁時計に直したあとの値を説明する（`localExpression` と対応）。\n * `expression` は入力（UTC）を正規化したもの、`next` は UTC として解釈した絶対時刻。\n *\n * @throws {CronSyntaxError} 式が不正な場合\n * @throws {CronTimeZoneError} `tz` を解釈できない、または cron 式に書き換えられない場合\n */\nexport function explainDetailed(expression: string, options: ExplainOptions = {}): Explanation {\n  const parsed = parseExpression(expression, parserOptions(options));\n  const composeOptions = resolve(options);\n  const timeZone = resolveTimeZone(options.tz);\n  const ast = shiftAst(parsed.ast, timeZone, \"toLocal\");\n\n  const normalized = formatExpression(parsed.ast);\n  const localized = ast === parsed.ast ? normalized : formatExpression(ast);\n  // 書き換わったフィールドだけ raw を差し替える。触っていないフィールドは\n  // 入力の字面（JAN や MON-FRI）をそのまま見せる\n  const raw = (field: keyof typeof parsed.raw, before: FieldAST, after: FieldAST): string =>\n    before === after ? (parsed.raw[field] ?? formatField(after)) : formatField(after);\n  const dowOptions = { weekly: false, collapse: composeOptions.collapseWeekdays };\n\n  const fields: Explanation[\"fields\"] = {\n    minute: explainField(\n      raw(\"minute\", parsed.ast.minute, ast.minute),\n      ast.minute,\n      MINUTE_SPEC,\n      describeMinuteField(ast.minute),\n    ),\n    hour: explainField(\n      raw(\"hour\", parsed.ast.hour, ast.hour),\n      ast.hour,\n      HOUR_SPEC,\n      describeHourField(ast.hour, composeOptions),\n    ),\n    dayOfMonth: explainField(\n      raw(\"dayOfMonth\", parsed.ast.dayOfMonth, ast.dayOfMonth),\n      ast.dayOfMonth,\n      DOM_SPEC,\n      describeDayOfMonthField(ast.dayOfMonth),\n    ),\n    month: explainField(\n      raw(\"month\", parsed.ast.month, ast.month),\n      ast.month,\n      MONTH_SPEC,\n      describeMonthField(ast.month),\n    ),\n    dayOfWeek: explainField(\n      raw(\"dayOfWeek\", parsed.ast.dayOfWeek, ast.dayOfWeek),\n      ast.dayOfWeek,\n      DOW_SPEC,\n      describeDayOfWeekField(ast.dayOfWeek, dowOptions),\n    ),\n  };\n  if (ast.seconds !== undefined) {\n    fields.second = explainField(\n      raw(\"seconds\", parsed.ast.seconds ?? ast.seconds, ast.seconds),\n      ast.seconds,\n      SECOND_SPEC,\n      describeSecondField(ast.seconds),\n    );\n  }\n\n  const composed = compose(ast, composeOptions);\n  const text = options.showTimeZone === true ? `${composed}（${timeZone}）` : composed;\n  const { warnings } = validate(expression, parserOptions(options));\n\n  return {\n    text,\n    expression: normalized,\n    localExpression: localized,\n    tz: timeZone,\n    fields,\n    extensions: parsed.extensions,\n    notes: warnings,\n    next: next(expression, { ...parserOptions(options), count: 3 }),\n  };\n}\n","import type { TimeOfDayWord } from \"../types\";\n\nexport const DOW: Record<string, number> = {\n  日曜日: 0,\n  日曜: 0,\n  月曜日: 1,\n  月曜: 1,\n  火曜日: 2,\n  火曜: 2,\n  水曜日: 3,\n  水曜: 3,\n  木曜日: 4,\n  木曜: 4,\n  金曜日: 5,\n  金曜: 5,\n  土曜日: 6,\n  土曜: 6,\n};\n\nexport const DOW_SET: Record<string, number[]> = {\n  平日: [1, 2, 3, 4, 5],\n  週末: [0, 6],\n  土日: [0, 6],\n  休日: [0, 6],\n};\n\n/**\n * 曜日で近似した語と、そのずれの説明。\n *\n * 「休日」は祝日・振替休日も指すが、cron は曜日しか持たないので土日に寄せるほかない。\n * 黙って寄せると祝日ぶんの取りこぼしに気づけないので、note と減点を付ける（§2.3.5）。\n * 減点の量は `fill` が持つ。\n */\nexport const DOW_SET_APPROX: Record<string, string> = {\n  休日:\n    \"「休日」は祝日も指しますが、cron では曜日しか指定できないため、\" +\n    \"週末（土日）として解釈しました。祝日には実行されません\",\n};\n\nexport interface TimeOfDaySpec {\n  /** 既定の時。null は「時そのものは決まらない」 */\n  default: number | null;\n  /** その語が自然に指す時間帯 */\n  range: readonly [number, number];\n}\n\nexport const TIME_OF_DAY: Record<TimeOfDayWord, TimeOfDaySpec> = {\n  早朝: { default: 6, range: [4, 7] },\n  朝: { default: 9, range: [6, 10] },\n  午前: { default: null, range: [0, 11] },\n  昼: { default: 12, range: [11, 13] },\n  正午: { default: 12, range: [12, 12] },\n  午後: { default: null, range: [12, 23] },\n  夕方: { default: 18, range: [16, 19] },\n  夜: { default: 21, range: [19, 23] },\n  晩: { default: 21, range: [19, 23] },\n  深夜: { default: 2, range: [0, 4] },\n  夜中: { default: 2, range: [0, 4] },\n};\n\nexport type FreqUnit = \"minute\" | \"hour\" | \"day\" | \"week\" | \"month\" | \"year\";\n\nexport const FREQ: Record<string, FreqUnit> = {\n  毎分: \"minute\",\n  毎時: \"hour\",\n  毎日: \"day\",\n  毎週: \"week\",\n  毎月: \"month\",\n  毎年: \"year\",\n};\n\nexport const DOM_SPECIAL: Record<string, \"L\" | number> = { 月末: \"L\", 月初: 1 };\n\nexport const NTH: Record<string, number> = {\n  第1: 1,\n  第2: 2,\n  第3: 3,\n  第4: 4,\n  第5: 5,\n  最終: -1,\n  最後: -1,\n};\n\n/** 曜日語として認識する表記（「月」「日」単独は月名・日付と衝突するため含めない） */\nexport const DOW_HEADS = [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\"] as const;\n","import { DOM_SPEC, type FieldSpec, HOUR_SPEC, MINUTE_SPEC, MONTH_SPEC } from \"../cron/fields\";\nimport { formatField } from \"../cron/values\";\nimport { formatHour } from \"../explain/time\";\nimport type {\n  Ambiguity,\n  CronExtension,\n  FieldAST,\n  ParseOptions,\n  TimeOfDayWord,\n  Token,\n} from \"../types\";\nimport { DOW_SET_APPROX, type FreqUnit, TIME_OF_DAY } from \"./dictionary\";\nimport type { IntervalUnit, IntervalValue, TimeValue } from \"./tokenize\";\n\nexport interface Penalty {\n  reason: string;\n  amount: number;\n}\n\nexport interface Slots {\n  minute: FieldAST;\n  hour: FieldAST;\n  dom: FieldAST;\n  month: FieldAST;\n  dow: FieldAST;\n  extensions: Set<CronExtension>;\n  penalties: Penalty[];\n  ambiguities: Ambiguity[];\n  notes: string[];\n  /** 意味のあるトークンが 1 つも無かった */\n  empty: boolean;\n}\n\nconst ANY: FieldAST = { kind: \"any\" };\n\nconst FREQ_LABELS: Record<FreqUnit, string> = {\n  minute: \"毎分\",\n  hour: \"毎時\",\n  day: \"毎日\",\n  week: \"毎週\",\n  month: \"毎月\",\n  year: \"毎年\",\n};\n\nconst INTERVAL_LABELS: Record<IntervalUnit, string> = {\n  minute: \"分\",\n  hour: \"時\",\n  day: \"日\",\n  week: \"週\",\n  month: \"月\",\n};\n\n/** 値の並びを持つスロット。時刻は時と分を持つため別扱い */\ntype ListName = \"minute\" | \"dom\" | \"dow\" | \"month\";\n\n/** 間隔の単位と、その起点になる値の並び */\nconst INTERVAL_LIST: Partial<Record<IntervalUnit, ListName>> = {\n  minute: \"minute\",\n  day: \"dom\",\n  month: \"month\",\n};\n\n/** 値の並びの 1 要素。`from === to` は単独の値、それ以外は「AからBまで」 */\ninterface Span {\n  from: number;\n  to: number;\n}\n\ninterface ValueList {\n  items: Span[];\n  /** 「から」を読んだが、範囲の終端がまだ来ていない */\n  pendingRange: boolean;\n  /** 刻みの起点、あるいは分の値として読み終えた（二重指定として数えない） */\n  consumed: boolean;\n}\n\nfunction emptyList(): ValueList {\n  return { items: [], pendingRange: false, consumed: false };\n}\n\nfunction pushValue(list: ValueList, value: number): void {\n  const last = list.items[list.items.length - 1];\n  if (list.pendingRange && last !== undefined) {\n    last.to = value;\n    list.pendingRange = false;\n    return;\n  }\n  list.items.push({ from: value, to: value });\n}\n\n/** 値の並びを、連続部分を範囲に畳んだ構文木にする */\nfunction valuesToAst(values: number[]): FieldAST {\n  const sorted = [...new Set(values)].sort((a, b) => a - b);\n  const first = sorted[0];\n  if (first === undefined) return ANY;\n  if (sorted.length === 1) return { kind: \"value\", value: first };\n\n  const items: FieldAST[] = [];\n  let from = first;\n  let previous = first;\n  const flush = () => {\n    if (previous - from >= 2) items.push({ kind: \"range\", from, to: previous });\n    else for (let value = from; value <= previous; value++) items.push({ kind: \"value\", value });\n  };\n  for (const value of sorted.slice(1)) {\n    if (value === previous + 1) {\n      previous = value;\n      continue;\n    }\n    flush();\n    from = value;\n    previous = value;\n  }\n  flush();\n  const only = items[0];\n  /* c8 ignore next -- items は必ず 1 個以上になる */\n  if (only === undefined) return ANY;\n  return items.length === 1 ? only : { kind: \"list\", items };\n}\n\n/**\n * 値の並びを構文木にする。\n * 「AからBまで」と書かれた範囲は範囲のまま残す（`valuesToAst` は 3 個以上の連なりしか\n * 範囲に畳まないため、`28,31` のように意味が変わってしまう）。\n */\nfunction spansToAst(spans: Span[]): FieldAST {\n  if (spans.every((span) => span.from === span.to)) {\n    return valuesToAst(spans.map((span) => span.from));\n  }\n  const items = spans.map<FieldAST>((span) =>\n    span.from === span.to\n      ? { kind: \"value\", value: span.from }\n      : { kind: \"range\", from: span.from, to: span.to },\n  );\n  const only = items[0];\n  /* c8 ignore next -- 範囲を含むなら 1 個以上ある */\n  if (only === undefined) return ANY;\n  return items.length === 1 ? only : { kind: \"list\", items };\n}\n\nfunction listToAst(list: ValueList): FieldAST {\n  return spansToAst(list.items);\n}\n\n/**\n * 「AからBまでNごと」「AからNごと」の起点を取り出す。\n * 範囲として書かれていなければ null を返し、値の並びは値のまま残す。\n */\nfunction consumeBase(list: ValueList, spec: FieldSpec): FieldAST | null {\n  const span = list.items[0];\n  if (span === undefined || list.items.length !== 1) return null;\n  if (!list.pendingRange && span.from === span.to) return null;\n  list.consumed = true;\n  return { kind: \"range\", from: span.from, to: list.pendingRange ? spec.max : span.to };\n}\n\n/**\n * 時刻の並びの 1 要素。時間帯語は `fill` で解決するまで語のまま持つ\n * （{@link resolveWord} が曖昧さと減点を積むため、`collect` では決められない）。\n */\ntype TimeAtom =\n  | { kind: \"time\"; hour: number; minute: number }\n  | { kind: \"word\"; word: TimeOfDayWord };\n\n/** 時刻の並びの 1 要素。`to === null` は単独の時刻、それ以外は「AからBまで」 */\ninterface TimeSpan {\n  from: TimeAtom;\n  to: TimeAtom | null;\n}\n\n/** 値の並び（{@link ValueList}）の時刻版。範囲を 2 つ以上持てる */\ninterface TimeList {\n  items: TimeSpan[];\n  /** 「から」を読んだが、範囲の終端がまだ来ていない */\n  pendingRange: boolean;\n}\n\nfunction pushTime(list: TimeList, atom: TimeAtom): void {\n  const last = list.items[list.items.length - 1];\n  if (list.pendingRange && last !== undefined) {\n    last.to = atom;\n    list.pendingRange = false;\n    return;\n  }\n  list.items.push({ from: atom, to: null });\n}\n\n/** 時間帯語を解決した時刻 */\ninterface ResolvedTime {\n  hour: number;\n  minute: number;\n}\n\ninterface ResolvedSpan {\n  from: ResolvedTime;\n  to: ResolvedTime | null;\n}\n\n/** 刻みの構文木。起点が全域を覆うなら省く（`1-31/3` は「3日ごと」と同じ集合） */\nfunction stepAst(base: FieldAST | null, step: number, spec: FieldSpec): FieldAST {\n  if (base === null) return { kind: \"step\", base: ANY, step };\n  if (base.kind === \"range\" && base.from === spec.min && base.to === spec.max) {\n    return { kind: \"step\", base: ANY, step };\n  }\n  return { kind: \"step\", base, step };\n}\n\n/**\n * 時から時間帯語の範囲までの距離（時間）。時計は巡回するので 23 時と 0 時は 1 時間差。\n */\nfunction gapToRange(hour: number, [low, high]: readonly [number, number]): number {\n  if (hour >= low && hour <= high) return 0;\n  return Math.min((low - hour + 24) % 24, (hour - high + 24) % 24);\n}\n\n/**\n * 時間帯語と並んだ時を読む。\n *\n * 12 時までの数字は 12 時間制の書き方なので、そのままの時と 12 時間ずらした時のうち、\n * 語の指す時間帯に近い方を採る（「夜6時」→ 18時、「午後3時」→ 15時）。\n * 13 時以降は 24 時間制としか読めないので、そのまま採る（「朝22時」→ 22時）。\n *\n * 範囲に入っていなくても近い方を採るのは、境界のすぐ外側で読みが裏返らないようにするため。\n * 「夜」は 19 時からだが、「夜6時」を午前 6 時と読むのは行き過ぎで、離れたぶんは\n * {@link fill} が note と減点で伝える（§2.3.5）。\n *\n * 12 時のもう一方の読みは 0 時なので、「午前12時」「夜12時」はどちらも 0 時になる。\n */\nfunction readHour(word: TimeOfDayWord, hour: number): { hour: number; gap: number } {\n  const range = TIME_OF_DAY[word].range;\n  const literal = { hour, gap: gapToRange(hour, range) };\n  if (hour > 12) return literal;\n  const shifted = (hour + 12) % 24;\n  const alternative = { hour: shifted, gap: gapToRange(shifted, range) };\n  return alternative.gap < literal.gap ? alternative : literal;\n}\n\nfunction hourCandidates(from: number, to: number): Ambiguity[\"candidates\"] {\n  const candidates: Ambiguity[\"candidates\"] = [];\n  for (let hour = from; hour <= to; hour++) {\n    candidates.push({ value: hour, label: formatHour(hour, { style: \"casual\", hour: \"12h\" }) });\n  }\n  return candidates;\n}\n\ninterface Collected {\n  times: TimeList;\n  /** 「9時台」のように、時そのものではなく時の中を指している */\n  hourSpan: boolean;\n  lists: Record<ListName, ValueList>;\n  intervals: Partial<Record<IntervalUnit, number>>;\n  /** 同じ単位の間隔が 2 回書かれた */\n  duplicateIntervals: IntervalUnit[];\n  /** 値の並びと間隔のどちらが後に書かれたか（§2.3.5 の後勝ち） */\n  lastAssign: Partial<Record<ListName, \"values\" | \"interval\">>;\n  nths: Array<{ weekday: number; nth: number }>;\n  domSpecial: \"L\" | number | null;\n  freqs: FreqUnit[];\n  unknown: number;\n  meaningful: number;\n  todNotes: string[];\n  /** 時間帯の語と時刻がずれたぶんの減点 */\n  todPenalties: Penalty[];\n  /** 曜日で近似した語（「休日」）の説明 */\n  approxNotes: string[];\n}\n\nfunction collect(tokens: Token[]): Collected {\n  const state: Collected = {\n    times: { items: [], pendingRange: false },\n    hourSpan: false,\n    lists: { minute: emptyList(), dom: emptyList(), dow: emptyList(), month: emptyList() },\n    intervals: {},\n    duplicateIntervals: [],\n    lastAssign: {},\n    nths: [],\n    domSpecial: null,\n    freqs: [],\n    unknown: 0,\n    meaningful: 0,\n    todNotes: [],\n    todPenalties: [],\n    approxNotes: [],\n  };\n\n  let pendingWord: TimeOfDayWord | null = null;\n  /** 範囲の始点に掛かっていた時間帯語。終端に語が無ければこれを引き継ぐ */\n  let spanWord: TimeOfDayWord | null = null;\n  let pendingNth: number | null = null;\n  /** 直前に読んだ値がどのスロットのものか（「から」の係り先） */\n  let last: ListName | \"time\" | null = null;\n\n  /**\n   * 時刻の並びに 1 つ足す。範囲の始点なら、掛かっていた語を終端が引き継げるよう覚える\n   * （終端に語が無い「夜6時から9時まで」を 18-21 と読むため）。\n   */\n  const addTime = (atom: TimeAtom, word: TimeOfDayWord | null) => {\n    if (!state.times.pendingRange) spanWord = word;\n    pushTime(state.times, atom);\n  };\n\n  /** 時刻に結び付かなかった時間帯語を、書かれた位置のまま並びに置く */\n  const flushWord = () => {\n    if (pendingWord !== null) {\n      addTime({ kind: \"word\", word: pendingWord }, pendingWord);\n      pendingWord = null;\n    }\n  };\n\n  /** 値を並びに足し、「から」の係り先として返す */\n  const addValues = (name: ListName, values: number[]): ListName => {\n    for (const value of values) pushValue(state.lists[name], value);\n    state.lastAssign[name] = \"values\";\n    return name;\n  };\n\n  for (const token of tokens) {\n    if (token.type !== \"UNKNOWN\" && token.type !== \"SEP\") state.meaningful += 1;\n\n    switch (token.type) {\n      case \"AMPM\":\n      case \"TIME_OF_DAY\":\n        flushWord();\n        pendingWord = token.value as TimeOfDayWord;\n        last = \"time\";\n        break;\n\n      case \"TIME\": {\n        const time = token.value as TimeValue;\n        let hour = time.hour;\n        // 「夜6時から9時まで」の 9 時は始点と同じ時間帯の中。語が書かれていない\n        // 範囲の終端は、始点に掛かっていた語で読む（→ 18-21）\n        const inherited = state.times.pendingRange ? spanWord : null;\n        const word = pendingWord ?? inherited;\n        if (word !== null) {\n          const reading = readHour(word, hour);\n          hour = reading.hour;\n          // 書かれた語だけを note にする。引き継いだ語のずれを書くと、\n          // 利用者が書いていない語のせいで減点されたように見える\n          if (reading.gap > 0 && pendingWord !== null) {\n            // 語の指す時間帯から外れた読みしか無い。採った理由は言えないので、\n            // どう読んだかを note にして、離れたぶんだけ減点する\n            const [low, high] = TIME_OF_DAY[pendingWord].range;\n            state.todNotes.push(\n              `「${pendingWord}」は通常 ${low}時から${high}時ですが、${hour}時と解釈しました`,\n            );\n            state.todPenalties.push({\n              reason: \"時間帯の語と時刻のずれ\",\n              amount: Math.min(0.3, reading.gap * 0.1),\n            });\n          }\n        }\n        addTime({ kind: \"time\", hour, minute: time.minute }, pendingWord);\n        pendingWord = null;\n        last = \"time\";\n        break;\n      }\n\n      case \"MINUTE\":\n        flushWord();\n        last = addValues(\"minute\", [token.value as number]);\n        break;\n\n      case \"INTERVAL\": {\n        flushWord();\n        const interval = token.value as IntervalValue;\n        if (state.intervals[interval.unit] !== undefined) {\n          state.duplicateIntervals.push(interval.unit);\n        }\n        state.intervals[interval.unit] = interval.n;\n        const name = INTERVAL_LIST[interval.unit];\n        if (name !== undefined) state.lastAssign[name] = \"interval\";\n        // cron に週の刻みは無い。「毎週」として扱い、fill で note を付ける\n        if (interval.unit === \"week\") state.freqs.push(\"week\");\n        // 「3か月ごと」だけでは何日に動くか決まらないので「毎月」と同じ期待を置く\n        if (interval.unit === \"month\") state.freqs.push(\"month\");\n        break;\n      }\n\n      case \"RANGE_FROM\":\n        if (last === \"time\") {\n          // 「朝から17時まで」の「朝」は 17 時の修飾語ではなく、範囲の始点\n          flushWord();\n          if (state.times.items.length > 0) state.times.pendingRange = true;\n        } else if (last !== null && state.lists[last].items.length > 0) {\n          state.lists[last].pendingRange = true;\n        }\n        break;\n\n      case \"RANGE_TO\":\n        break;\n\n      case \"NTH\":\n        flushWord();\n        pendingNth = token.value as number;\n        break;\n\n      case \"DOW\": {\n        flushWord();\n        const weekday = token.value as number;\n        if (pendingNth !== null) {\n          state.nths.push({ weekday, nth: pendingNth });\n          pendingNth = null;\n        } else {\n          last = addValues(\"dow\", [weekday]);\n        }\n        break;\n      }\n\n      case \"DOW_SET\": {\n        flushWord();\n        // 「休日」のように曜日と厳密には一致しない語は、寄せたことを fill で note にする\n        const approx = DOW_SET_APPROX[token.raw];\n        if (approx !== undefined) state.approxNotes.push(approx);\n        last = addValues(\"dow\", token.value as number[]);\n        break;\n      }\n\n      case \"DOM\":\n        flushWord();\n        last = addValues(\"dom\", [token.value as number]);\n        break;\n\n      case \"DOM_SPECIAL\": {\n        flushWord();\n        const value = token.value as \"L\" | number;\n        if (value === \"L\") state.domSpecial = \"L\";\n        else last = addValues(\"dom\", [value]);\n        break;\n      }\n\n      case \"MONTH\":\n        flushWord();\n        last = addValues(\"month\", [token.value as number]);\n        break;\n\n      case \"FREQ\":\n        flushWord();\n        state.freqs.push(token.value as FreqUnit);\n        break;\n\n      case \"AND\":\n        // 「午前0時と正午」の「正午」は 2 つ目の時刻。前の語をここで切る\n        flushWord();\n        break;\n\n      case \"HOUR_SPAN\":\n        state.hourSpan = true;\n        break;\n\n      default:\n        if (token.type === \"UNKNOWN\") state.unknown += 1;\n        break;\n    }\n  }\n\n  flushWord();\n  return state;\n}\n\n/**\n * トークン列から cron の各フィールドを埋める。\n */\nexport function fill(tokens: Token[], options: ParseOptions = {}): Slots {\n  const requested = options.defaultHour ?? 9;\n  const defaultHour =\n    Number.isInteger(requested) && requested >= 0 && requested <= 23 ? requested : 9;\n  const state = collect(tokens);\n\n  const slots: Slots = {\n    minute: ANY,\n    hour: ANY,\n    dom: ANY,\n    month: ANY,\n    dow: ANY,\n    extensions: new Set<CronExtension>(),\n    penalties: [],\n    ambiguities: [],\n    notes: [...state.todNotes],\n    empty: state.meaningful === 0,\n  };\n  if (slots.empty) return slots;\n\n  const penalize = (reason: string, amount: number) => {\n    slots.penalties.push({ reason, amount });\n  };\n\n  /** 同じフィールドに 2 通りの指定が並んだとき（§2.3.5 の「2 回代入」） */\n  const noteConflict = (label: string) => {\n    slots.notes.push(`「${label}」の指定が 2 通りあるため、後に書かれた方を採用しました`);\n    penalize(\"同じフィールドへの二重指定\", 0.2);\n  };\n\n  // 時間帯の語と時刻のずれ（note は collect が積んでいる）\n  for (const penalty of state.todPenalties) slots.penalties.push(penalty);\n\n  for (const unit of state.duplicateIntervals) noteConflict(INTERVAL_LABELS[unit]);\n\n  // 曜日に寄せた語は、指す日がずれるぶんを減点する（cron に祝日は書けない）\n  for (const note of state.approxNotes) {\n    slots.notes.push(note);\n    penalize(\"曜日で近似した語\", 0.2);\n  }\n\n  /** 時間帯の語を時に落とす。幅のある語は曖昧さとして報告する */\n  const resolveWord = (word: TimeOfDayWord): number => {\n    const spec = TIME_OF_DAY[word];\n    const override = options.timeOfDay?.[word];\n    // 「正午」のように時が一意に定まる語は曖昧ではない\n    if (spec.range[0] !== spec.range[1] && override === undefined) {\n      slots.ambiguities.push({\n        field: \"hour\",\n        question: `「${word}」は何時ですか？`,\n        candidates: hourCandidates(spec.range[0], spec.range[1]),\n      });\n      penalize(\"時刻を表す語が曖昧\", 0.3);\n    }\n    return override ?? spec.default ?? defaultHour;\n  };\n\n  // 時刻に結び付かなかった時間帯語は、それ自体が 1 つの時刻（「午前0時と正午」）。\n  // 並びの位置は `collect` が保っているので、書かれた順のまま解決する\n  const resolveAtom = (atom: TimeAtom): ResolvedTime =>\n    atom.kind === \"time\"\n      ? { hour: atom.hour, minute: atom.minute }\n      : { hour: resolveWord(atom.word), minute: 0 };\n  const spans = state.times.items.map<ResolvedSpan>((span) => ({\n    from: resolveAtom(span.from),\n    to: span.to === null ? null : resolveAtom(span.to),\n  }));\n\n  /* ---------------- 時刻 ---------------- */\n\n  const minutes = state.lists.minute;\n  const minuteStep = state.intervals.minute;\n  const hourStep = state.intervals.hour;\n  const hasTime = spans.length > 0;\n  const hasRange = spans.some((span) => span.to !== null);\n  // 時刻の側に書かれた分。範囲の終端が持つ 0 分は「まで」の側なので採らない\n  // （「9時30分から17時まで」の分は 30 であって 0,30 ではない）\n  const spanMinutes = [...new Set(spans.map((span) => span.from.minute))];\n\n  /** 時刻の並びを時フィールドにする。書かれた範囲は範囲のまま残す */\n  const hourList = (): FieldAST =>\n    spansToAst(spans.map((span) => ({ from: span.from.hour, to: (span.to ?? span.from).hour })));\n\n  /**\n   * 時の刻み。「AからBまでN時間ごと」は範囲ごとに掛かるので、書かれた範囲それぞれに適用する。\n   * 範囲が 1 つも無ければ起点を持たない全域からの刻み。\n   */\n  const hourStepAst = (step: number): FieldAST => {\n    if (!hasRange) return { kind: \"step\", base: ANY, step };\n    const items = spans.map<FieldAST>((span) =>\n      span.to === null\n        ? { kind: \"value\", value: span.from.hour }\n        : stepAst({ kind: \"range\", from: span.from.hour, to: span.to.hour }, step, HOUR_SPEC),\n    );\n    const only = items[0];\n    /* c8 ignore next -- hasRange が真なら 1 個以上ある */\n    if (only === undefined) return { kind: \"step\", base: ANY, step };\n    return items.length === 1 ? only : { kind: \"list\", items };\n  };\n\n  /** 「N時まで」が N 時台を含むことを断る。終端ごとに曖昧なので範囲の数だけ付ける */\n  const noteHourRanges = () => {\n    for (const span of spans) {\n      const to = span.to;\n      if (to === null) continue;\n      slots.notes.push(\n        `「${to.hour}時まで」を ${to.hour}時台まで（${span.from.hour}-${to.hour}）と解釈しました。` +\n          `${to.hour}:00 で終える場合は ${span.from.hour}-${to.hour - 1} を指定してください`,\n      );\n      penalize(\"時刻範囲の終端が曖昧\", 0.1);\n    }\n  };\n\n  if (state.freqs.includes(\"minute\")) {\n    slots.minute = ANY;\n    if (hourStep !== undefined) {\n      // 「2時間ごと（毎分）」の時の刻み。毎分だけを見て捨てると刻みが消える\n      slots.hour = hourStepAst(hourStep);\n    } else if (hasTime) {\n      // 「午前9時台の毎分」のように時が書かれていれば、その時の中での毎分\n      slots.hour = hourList();\n    }\n    noteHourRanges();\n  } else if (minuteStep !== undefined || hourStep !== undefined) {\n    if (minuteStep !== undefined) {\n      // 「1分から59分まで2分ごと」の起点。範囲が書かれていなければ全域からの刻み\n      slots.minute = stepAst(consumeBase(minutes, MINUTE_SPEC), minuteStep, MINUTE_SPEC);\n    }\n    if (hourStep !== undefined) {\n      slots.hour = hourStepAst(hourStep);\n      if (minuteStep === undefined) {\n        slots.minute =\n          minutes.items.length > 0\n            ? listToAst(minutes)\n            : { kind: \"value\", value: spanMinutes[0] ?? 0 };\n        minutes.consumed = true;\n      }\n    } else if (hasRange) {\n      slots.hour = hourList();\n    }\n\n    noteHourRanges();\n    if (!hasRange && hasTime) {\n      // 「午前9時台と午後6時台の5分ごと」のように時が並ぶことがあるので、全部を採る\n      if (minuteStep !== undefined) slots.hour = hourList();\n      // 「9時台の10分ごと」は「その時の中で N 分ごと」で、読み方は 1 つしかない。\n      // 「9時に10分ごと」のように時が一点を指すときだけ、どちらの意味か決まらない\n      const spanned = state.hourSpan && minuteStep !== undefined && hourStep === undefined;\n      if (!spanned) {\n        slots.ambiguities.push({\n          field: \"hour\",\n          question: \"「〜ごと」と時刻の両方が指定されています。どちらの意味ですか？\",\n          candidates: [\n            { value: \"interval\", label: \"指定した間隔で繰り返す\" },\n            { value: \"at\", label: \"指定した時刻にだけ実行する\" },\n          ],\n        });\n        penalize(\"間隔と時刻の併用\", 0.2);\n      }\n    }\n\n    if (minutes.items.length > 0 && !minutes.consumed) {\n      noteConflict(INTERVAL_LABELS.minute);\n      if (state.lastAssign.minute === \"values\") slots.minute = listToAst(minutes);\n    }\n  } else if (hasTime) {\n    // 「午前9時台の10分と44分」のように分が別に書かれていれば、そちらが分フィールド。\n    // 「9時」が持つ 0 分は書かれた値ではないので、時だけを取る\n    const writtenMinutes = minutes.items.length > 0;\n    // 「9時30分と45分」のように時刻の側にも分が書かれていれば、分の二重指定\n    if (writtenMinutes && spanMinutes.some((minute) => minute !== 0)) {\n      noteConflict(INTERVAL_LABELS.minute);\n    }\n\n    slots.hour = hourList();\n    noteHourRanges();\n\n    const only = spanMinutes[0];\n    if (writtenMinutes) {\n      slots.minute = listToAst(minutes);\n    } else if (spanMinutes.length === 1 && only !== undefined) {\n      slots.minute = { kind: \"value\", value: only };\n    } else {\n      slots.minute = valuesToAst(spanMinutes);\n      slots.notes.push(\"複数の時刻が指定されているため、時と分のすべての組み合わせで実行されます\");\n      penalize(\"時と分の組み合わせが曖昧\", 0.1);\n    }\n  } else if (state.freqs.includes(\"hour\")) {\n    slots.hour = ANY;\n    slots.minute = minutes.items.length > 0 ? listToAst(minutes) : { kind: \"value\", value: 0 };\n  } else if (minutes.items.length > 0) {\n    slots.hour = ANY;\n    slots.minute = listToAst(minutes);\n  } else {\n    slots.hour = { kind: \"value\", value: defaultHour };\n    slots.minute = { kind: \"value\", value: 0 };\n    const freqLabel = state.freqs[0] === undefined ? undefined : FREQ_LABELS[state.freqs[0]];\n    slots.ambiguities.push({\n      field: \"hour\",\n      question: freqLabel === undefined ? \"何時に実行しますか？\" : `「${freqLabel}」は何時ですか？`,\n      candidates: hourCandidates(0, 23),\n    });\n    penalize(\"時刻が指定されていない\", 0.4);\n  }\n\n  /* ---------------- 日付・曜日 ---------------- */\n\n  const doms = state.lists.dom;\n  const dows = state.lists.dow;\n  const months = state.lists.month;\n  const dayStep = state.intervals.day;\n  const monthStep = state.intervals.month;\n\n  if (state.nths.length > 0) {\n    const items = state.nths.map<FieldAST>((entry) => ({\n      kind: \"nth\",\n      weekday: entry.weekday,\n      nth: entry.nth,\n    }));\n    const first = items[0];\n    /* c8 ignore next -- nths.length > 0 なら必ず取れる */\n    slots.dow = items.length === 1 && first !== undefined ? first : { kind: \"list\", items };\n    for (const entry of state.nths) slots.extensions.add(entry.nth === -1 ? \"L\" : \"#\");\n  } else if (dows.items.length > 0) {\n    slots.dow = listToAst(dows);\n  }\n\n  if (state.domSpecial === \"L\") {\n    slots.dom = { kind: \"last\" };\n    slots.extensions.add(\"L\");\n    if (dayStep !== undefined) noteConflict(INTERVAL_LABELS.day);\n  } else if (dayStep !== undefined) {\n    // 「1日から3日ごと」は 1 日を起点にした刻み\n    slots.dom = stepAst(consumeBase(doms, DOM_SPEC), dayStep, DOM_SPEC);\n    if (doms.items.length > 0 && !doms.consumed) {\n      noteConflict(INTERVAL_LABELS.day);\n      if (state.lastAssign.dom === \"values\") slots.dom = listToAst(doms);\n    }\n  } else if (doms.items.length > 0) {\n    slots.dom = listToAst(doms);\n  }\n\n  if (monthStep !== undefined) {\n    slots.month = stepAst(consumeBase(months, MONTH_SPEC), monthStep, MONTH_SPEC);\n    if (months.items.length > 0 && !months.consumed) {\n      noteConflict(INTERVAL_LABELS.month);\n      if (state.lastAssign.month === \"values\") slots.month = listToAst(months);\n    }\n  } else if (months.items.length > 0) {\n    slots.month = listToAst(months);\n  }\n\n  const weekStep = state.intervals.week;\n  if (weekStep !== undefined) {\n    slots.notes.push(\n      `cron には週単位の刻みが無いため「${weekStep}週間ごと」は表現できません。` +\n        \"毎週として解釈しました\",\n    );\n    penalize(\"週単位の刻み\", 0.3);\n  }\n\n  /* ---------------- 頻度語の期待 ---------------- */\n\n  const domSpecified = slots.dom.kind !== \"any\";\n  const dowSpecified = slots.dow.kind !== \"any\";\n\n  for (const freq of state.freqs) {\n    if (freq === \"day\" && (domSpecified || dowSpecified)) {\n      slots.notes.push(\n        \"「毎日」と日付・曜日の指定が同時にあるため、日付・曜日の指定を優先しました\",\n      );\n      penalize(\"頻度語と日付指定の不一致\", 0.1);\n    }\n    if (freq === \"week\" && !dowSpecified) {\n      slots.dow = { kind: \"value\", value: 1 };\n      slots.ambiguities.push({\n        field: \"dayOfWeek\",\n        question: \"「毎週」は何曜日ですか？\",\n        candidates: [\n          { value: 0, label: \"日曜日\" },\n          { value: 1, label: \"月曜日\" },\n          { value: 2, label: \"火曜日\" },\n          { value: 3, label: \"水曜日\" },\n          { value: 4, label: \"木曜日\" },\n          { value: 5, label: \"金曜日\" },\n          { value: 6, label: \"土曜日\" },\n        ],\n      });\n      penalize(\"「毎週」の曜日が未指定\", 0.3);\n    }\n    // 「3か月ごとの毎日」は日が決まっている。「毎日」が無いときだけ日を補う\n    if (freq === \"month\" && !domSpecified && !dowSpecified && !state.freqs.includes(\"day\")) {\n      slots.dom = { kind: \"value\", value: 1 };\n      slots.ambiguities.push({\n        field: \"dayOfMonth\",\n        question: \"「毎月」は何日ですか？\",\n        candidates: [\n          { value: 1, label: \"1日\" },\n          { value: 15, label: \"15日\" },\n          { value: \"L\", label: \"月末\" },\n        ],\n      });\n      penalize(\"「毎月」の日が未指定\", 0.3);\n    }\n    if (freq === \"year\" && slots.month.kind === \"any\") {\n      slots.month = { kind: \"value\", value: 1 };\n      if (slots.dom.kind === \"any\") slots.dom = { kind: \"value\", value: 1 };\n      slots.ambiguities.push({\n        field: \"month\",\n        question: \"「毎年」は何月ですか？\",\n        candidates: Array.from({ length: 12 }, (_, index) => ({\n          value: index + 1,\n          label: `${index + 1}月`,\n        })),\n      });\n      penalize(\"「毎年」の月が未指定\", 0.3);\n    }\n  }\n\n  /* ---------------- 衝突・減点 ---------------- */\n\n  if (slots.dom.kind !== \"any\" && slots.dow.kind !== \"any\") {\n    slots.notes.push(\n      \"標準の cron では日と曜日を同時に指定すると OR 条件になり、どちらかに一致する日に実行されます\",\n    );\n    penalize(\"日と曜日の同時指定\", 0.2);\n  }\n\n  const hasDateToken =\n    dows.items.length > 0 ||\n    state.nths.length > 0 ||\n    doms.items.length > 0 ||\n    state.domSpecial !== null ||\n    months.items.length > 0;\n  const hasInterval = Object.keys(state.intervals).length > 0;\n  if (state.freqs.length === 0 && !hasDateToken && !hasInterval) {\n    slots.notes.push(\"頻度が明示されていないため、毎日として解釈しました\");\n    penalize(\"頻度語が無い\", 0.2);\n  }\n\n  if (slots.extensions.size > 0 && options.allowExtensions !== true) {\n    const used = [...slots.extensions].join(\"', '\");\n    slots.notes.push(\n      `'${used}' は Quartz 拡張です。標準の cron では動作しません（allowExtensions で抑制できます）`,\n    );\n    penalize(\"拡張構文の使用\", 0.1);\n  }\n\n  if (state.unknown > 0) {\n    penalize(\"解釈できない語\", Math.min(0.3, state.unknown * 0.1));\n  }\n\n  return slots;\n}\n\n/** スロットを cron 式にする */\nexport function emit(slots: Slots): string {\n  return [slots.minute, slots.hour, slots.dom, slots.month, slots.dow].map(formatField).join(\" \");\n}\n","const KANJI_DIGITS: Record<string, number> = {\n  〇: 0,\n  零: 0,\n  一: 1,\n  二: 2,\n  三: 3,\n  四: 4,\n  五: 5,\n  六: 6,\n  七: 7,\n  八: 8,\n  九: 9,\n};\n\nconst KANJI_RUN = /[〇零一二三四五六七八九十]+/g;\n\nfunction convertRun(run: string): string {\n  if (!run.includes(\"十\")) {\n    let digits = \"\";\n    for (const char of run) {\n      const digit = KANJI_DIGITS[char];\n      /* c8 ignore next -- KANJI_RUN が一致した文字は必ず辞書にある */\n      if (digit === undefined) return run;\n      digits += String(digit);\n    }\n    return digits;\n  }\n\n  let total = 0;\n  let current = 0;\n  for (const char of run) {\n    if (char === \"十\") {\n      total += (current === 0 ? 1 : current) * 10;\n      current = 0;\n    } else {\n      const digit = KANJI_DIGITS[char];\n      /* c8 ignore next -- KANJI_RUN が一致した文字は必ず辞書にある */\n      if (digit === undefined) return run;\n      current = digit;\n    }\n  }\n  return String(total + current);\n}\n\n/** 漢数字を算用数字に変換する（「半」はそのまま残す） */\nexport function kanjiToArabic(text: string): string {\n  return text.replace(KANJI_RUN, (run) => convertRun(run));\n}\n\n/** 文末の動詞句・丁寧表現を落とす */\nconst TAIL_PATTERNS: RegExp[] = [\n  /(に|で)?(実行|起動|開始|動作)(する|して|し|す)?(たい|ください|下さい|ます|ましょう|よう)?$/,\n  /(して)?(ください|下さい|ほしい|欲しい|たい)$/,\n  /(です|ます|だ|である)(か)?$/,\n  /[。！!？?、,\\s]+$/,\n];\n\nexport function stripTail(text: string): string {\n  let result = text;\n  for (let i = 0; i < 5; i++) {\n    let changed = false;\n    for (const pattern of TAIL_PATTERNS) {\n      const next = result.replace(pattern, \"\");\n      if (next !== result && next.length > 0) {\n        result = next;\n        changed = true;\n      }\n    }\n    if (!changed) break;\n  }\n  return result;\n}\n\n/**\n * 解析前の前処理。NFKC 正規化 → 漢数字変換 → 文末表現の除去。\n */\nexport function normalize(text: string): string {\n  return stripTail(kanjiToArabic(text.normalize(\"NFKC\")).trim()).trim();\n}\n","import type { TimeOfDayWord, Token } from \"../types\";\nimport { DOM_SPECIAL, DOW, DOW_SET, FREQ, type FreqUnit, NTH } from \"./dictionary\";\n\nexport type IntervalUnit = \"minute\" | \"hour\" | \"day\" | \"week\" | \"month\";\n\nexport interface IntervalValue {\n  unit: IntervalUnit;\n  n: number;\n}\n\nexport interface TimeValue {\n  hour: number;\n  minute: number;\n}\n\ntype Rule = [RegExp, (match: RegExpMatchArray) => Omit<Token, \"raw\" | \"position\"> | null];\n\nfunction int(text: string | undefined): number {\n  return Number(text ?? \"0\");\n}\n\n/** 範囲外の数値はトークンにしない（後続のルール、最終的には UNKNOWN に回す） */\nfunction inRange(value: number, min: number, max: number): boolean {\n  return Number.isInteger(value) && value >= min && value <= max;\n}\n\n/**\n * 長い表現から順に試すため、並び順に意味がある。\n *\n * 「毎」で終わる間隔（「15分毎」）は、後ろに頻度語の単位が続く場合だけ採らない。\n * 「1月毎日」を「1か月ごと」+「日」と切ってしまうのを避けるため。\n */\nconst RULES: Rule[] = [\n  [\n    /^(\\d{1,2})時間(?:ごと|おき|毎(?![分時日週月年]))に?/,\n    (m) => {\n      const n = int(m[1]);\n      if (!inRange(n, 1, 23)) return null;\n      return { type: \"INTERVAL\", value: { unit: \"hour\", n } satisfies IntervalValue };\n    },\n  ],\n  [\n    /^(\\d{1,2})分(?:ごと|おき|毎(?![分時日週月年]))に?/,\n    (m) => {\n      const n = int(m[1]);\n      if (!inRange(n, 1, 59)) return null;\n      return { type: \"INTERVAL\", value: { unit: \"minute\", n } satisfies IntervalValue };\n    },\n  ],\n  [\n    /^(\\d{1,2})日(?:ごと|おき|毎(?![分時日週月年]))に?/,\n    (m) => {\n      const n = int(m[1]);\n      if (!inRange(n, 1, 31)) return null;\n      return { type: \"INTERVAL\", value: { unit: \"day\", n } satisfies IntervalValue };\n    },\n  ],\n  [\n    // 「か月」の表記ゆれ（か / ヶ / ヵ / ケ / カ / 箇）と、「3月ごと」の省略形を受ける\n    /^(\\d{1,2})[かカヵケヶ箇]?月(?:ごと|おき|毎(?![分時日週月年]))に?/,\n    (m) => {\n      const n = int(m[1]);\n      if (!inRange(n, 1, 12)) return null;\n      return { type: \"INTERVAL\", value: { unit: \"month\", n } satisfies IntervalValue };\n    },\n  ],\n  [\n    /^(\\d{1,2})週間?(?:ごと|おき|毎(?![分時日週月年]))に?/,\n    (m) => {\n      const n = int(m[1]);\n      if (!inRange(n, 1, 52)) return null;\n      return { type: \"INTERVAL\", value: { unit: \"week\", n } satisfies IntervalValue };\n    },\n  ],\n  [\n    /^(\\d{1,2}):(\\d{2})/,\n    (m) => {\n      const hour = int(m[1]);\n      const minute = int(m[2]);\n      if (!inRange(hour, 0, 23) || !inRange(minute, 0, 59)) return null;\n      return { type: \"TIME\", value: { hour, minute } satisfies TimeValue };\n    },\n  ],\n  [\n    /^(\\d{1,2})時(半|(\\d{1,2})分)?/,\n    (m) => {\n      const hour = int(m[1]);\n      const minute = m[2] === \"半\" ? 30 : int(m[3]);\n      if (!inRange(hour, 0, 23) || !inRange(minute, 0, 59)) return null;\n      return { type: \"TIME\", value: { hour, minute } satisfies TimeValue };\n    },\n  ],\n  [\n    /^(\\d{1,2})分/,\n    (m) => {\n      const value = int(m[1]);\n      return inRange(value, 0, 59) ? { type: \"MINUTE\", value } : null;\n    },\n  ],\n  [\n    /^(第[1-5]|最終|最後)(週|の)?/,\n    (m) => {\n      const nth = NTH[m[1] ?? \"\"];\n      return nth === undefined ? null : { type: \"NTH\", value: nth };\n    },\n  ],\n  [\n    /^(\\d{1,2})月/,\n    (m) => {\n      const value = int(m[1]);\n      return inRange(value, 1, 12) ? { type: \"MONTH\", value } : null;\n    },\n  ],\n  [\n    /^(\\d{1,2})日/,\n    (m) => {\n      const value = int(m[1]);\n      return inRange(value, 1, 31) ? { type: \"DOM\", value } : null;\n    },\n  ],\n  [\n    /^(平日|週末|土日|休日)/,\n    (m) => {\n      const values = DOW_SET[m[1] ?? \"\"];\n      return values === undefined ? null : { type: \"DOW_SET\", value: [...values] };\n    },\n  ],\n  [\n    /^(日|月|火|水|木|金|土)曜日?/,\n    (m) => {\n      const value = DOW[`${m[1]}曜`];\n      return value === undefined ? null : { type: \"DOW\", value };\n    },\n  ],\n  [\n    /^毎?(月末|月初)/,\n    (m) => {\n      const value = DOM_SPECIAL[m[1] ?? \"\"];\n      return value === undefined ? null : { type: \"DOM_SPECIAL\", value };\n    },\n  ],\n  [\n    /^(早朝|朝|正午|昼|夕方|夜中|深夜|夜|晩|午前|午後)/,\n    (m) => {\n      const word = m[1] as TimeOfDayWord;\n      if (word === \"午前\" || word === \"午後\") return { type: \"AMPM\", value: word };\n      return { type: \"TIME_OF_DAY\", value: word };\n    },\n  ],\n  [\n    /^毎(分|時|日|週|月|年)/,\n    (m) => {\n      const unit: FreqUnit | undefined = FREQ[`毎${m[1]}`];\n      return unit === undefined ? null : { type: \"FREQ\", value: unit };\n    },\n  ],\n  [\n    // 「毎晩」「毎朝」は「毎日」＋時間帯語。「毎」だけを頻度語として読み、\n    // 続く時間帯語は次の周回で時間帯語の規則に任せる\n    /^毎(?=早朝|朝|正午|昼|夕方|夜中|深夜|夜|晩)/,\n    () => ({ type: \"FREQ\", value: \"day\" satisfies FreqUnit }),\n  ],\n  [/^(から|以降)/, () => ({ type: \"RANGE_FROM\" })],\n  [/^(まで|以前)/, () => ({ type: \"RANGE_TO\" })],\n  [/^(および|かつ|と|、|,)/, () => ({ type: \"AND\" })],\n  // 「9時台」は「9時00分」ではなく 9 時の中を指す。区切りとして捨てると\n  // 「9時台の10分ごと」が間隔と単独時刻の併用に見えるので、専用のトークンにする\n  [/^台/, () => ({ type: \"HOUR_SPAN\" })],\n  [/^(の|に|は|が|を|\\s|。)+/, () => ({ type: \"SEP\" })],\n];\n\n/**\n * 正規化済みの日本語をトークン列に分解する。\n */\nexport function tokenize(text: string): Token[] {\n  const tokens: Token[] = [];\n  let position = 0;\n\n  while (position < text.length) {\n    const rest = text.slice(position);\n    let matched = false;\n\n    for (const [pattern, build] of RULES) {\n      const match = pattern.exec(rest);\n      if (match === null || match[0] === \"\") continue;\n      const token = build(match);\n      /* c8 ignore next -- 辞書引きに失敗した場合のみ。通常は起きない */\n      if (token === null) continue;\n      tokens.push({ ...token, raw: match[0], position });\n      position += match[0].length;\n      matched = true;\n      break;\n    }\n\n    if (!matched) {\n      tokens.push({ type: \"UNKNOWN\", raw: text[position] ?? \"\", position });\n      position += 1;\n    }\n  }\n\n  return tokens;\n}\n","import { resolveTimeZone, shiftExpression } from \"../cron\";\nimport { ParseAmbiguityError } from \"../errors\";\nimport type { ParseOptions, ParseResult } from \"../types\";\nimport { emit, fill } from \"./fill\";\nimport { normalize } from \"./normalize\";\nimport { tokenize } from \"./tokenize\";\n\nfunction round2(value: number): number {\n  return Math.round(value * 100) / 100;\n}\n\n/**\n * 日本語の予定表現を cron 式に変換する。\n *\n * 日本語は `options.tz`（既定 `'Asia/Tokyo'`）の壁時計として読み、UTC のサーバーで\n * 動かすための cron 式を返す。\n *\n * ```ts\n * parse('毎日午後1時').expression; // '0 4 * * *'（JST 13:00 = UTC 04:00）\n * parse('平日の朝9時', { tz: 'UTC' }).expression; // '0 9 * * 1-5'（変換しない）\n * ```\n *\n * @throws {ParseAmbiguityError} `strict: true` かつ解釈が曖昧な場合\n * @throws {CronTimeZoneError} `tz` を解釈できない、または UTC の cron 式に書き換えられない場合\n */\nexport function parse(text: string, options: ParseOptions = {}): ParseResult {\n  const timeZone = resolveTimeZone(options.tz);\n\n  const tokens = tokenize(normalize(text));\n  const slots = fill(tokens, options);\n\n  if (slots.empty) {\n    const result: ParseResult = {\n      expression: null,\n      localExpression: null,\n      tz: timeZone,\n      confidence: 0,\n      ambiguities: [],\n      notes: [\"時間表現が見つかりませんでした\"],\n      tokens,\n    };\n    if (options.strict === true) {\n      throw new ParseAmbiguityError(\"時間表現が見つかりませんでした\", result);\n    }\n    return result;\n  }\n\n  const total = slots.penalties.reduce((sum, penalty) => sum + penalty.amount, 0);\n  const local = emit(slots);\n  const result: ParseResult = {\n    expression: shiftExpression(local, timeZone, \"toServer\"),\n    localExpression: local,\n    tz: timeZone,\n    confidence: round2(Math.max(0, 1 - total)),\n    ambiguities: slots.ambiguities,\n    notes: slots.notes,\n    tokens,\n  };\n\n  if (options.strict === true && result.ambiguities.length > 0) {\n    const first = result.ambiguities[0];\n    throw new ParseAmbiguityError(\n      `解釈が曖昧です: ${first?.question ?? \"入力を特定できません\"}`,\n      result,\n    );\n  }\n\n  return result;\n}\n\nexport * from \"./dictionary\";\nexport { emit, fill } from \"./fill\";\nexport { kanjiToArabic, normalize, stripTail } from \"./normalize\";\nexport { tokenize } from \"./tokenize\";\n"],"mappings":";;AAgBA,MAAa,cAAsC;CACjD,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,MAAa,YAAoC;CAC/C,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,MAAa,cAAyB;CACpC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK;CACL,UAAU;AACZ;AACA,MAAa,cAAyB;CACpC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK;CACL,UAAU;AACZ;AACA,MAAa,YAAuB;CAAE,OAAO;CAAQ,OAAO;CAAK,KAAK;CAAG,KAAK;CAAI,UAAU;AAAG;AAC/F,MAAa,WAAsB;CACjC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK;CACL,UAAU;AACZ;AACA,MAAa,aAAwB;CACnC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK;CACL,UAAU;CACV,OAAO;AACT;AACA,MAAa,WAAsB;CACjC,OAAO;CACP,OAAO;CACP,KAAK;CACL,KAAK;CACL,UAAU;CACV,OAAO;AACT;;AAGA,MAAa,cAA2B;CAAC;CAAa;CAAW;CAAU;CAAY;AAAQ;;AAG/F,MAAa,2BAAwC,CAAC,aAAa,GAAG,WAAW;AAEjF,MAAa,SAAiC;CAC5C,WAAW;CACX,aAAa;CACb,YAAY;CACZ,WAAW;CACX,UAAU;CACV,aAAa;CACb,WAAW;AACb;;;;;AAMA,MAAa,uBAA+C,EAC1D,WAAW,oCACb;AAEA,MAAa,aAAa;CAAC;CAAO;CAAO;CAAO;CAAO;CAAO;CAAO;AAAK;;;;;;ACnG1E,IAAa,kBAAb,cAAqC,MAAM;CACzC;CACA;CAEA,YAAY,SAAiB,UAAoD,CAAC,GAAG;EACnF,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,IAAI,QAAQ,UAAU,KAAA,GAAW,KAAK,QAAQ,QAAQ;EACtD,IAAI,QAAQ,aAAa,KAAA,GAAW,KAAK,WAAW,QAAQ;CAC9D;AACF;;;;AAKA,IAAa,sBAAb,cAAyC,MAAM;CAC7C;CAEA,YAAY,SAAiB,QAAqB;EAChD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;AACF;;;;AAKA,IAAa,oBAAb,cAAuC,MAAM;;CAE3C;CAEA,YAAY,SAAiB,UAAkB;EAC7C,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,WAAW;CAClB;AACF;;;;ACTA,SAAS,WAAW,MAAc,QAAgB,WAA2B;CAC3E,MAAM,QAAgB,CAAC;CACvB,IAAI,QAAQ;CACZ,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,QAAQ,KAChC,IAAI,MAAM,KAAK,UAAU,KAAK,OAAO,WAAW;EAC9C,MAAM,KAAK;GAAE,MAAM,KAAK,MAAM,OAAO,CAAC;GAAG,QAAQ,SAAS;EAAM,CAAC;EACjE,QAAQ,IAAI;CACd;CAEF,OAAO;AACT;;AAGA,SAAS,iBAAiB,OAAe,MAAyB;CAChE,OAAO,KAAK,UAAU,eAAe,UAAU,IAAI,IAAI;AACzD;;AAGA,SAAS,YAAY,MAAc,MAAiB,UAA0B;CAC5E,MAAM,QAAQ,KAAK,YAAY;CAC/B,MAAM,QAAQ,KAAK,QAAQ;CAC3B,IAAI,UAAU,KAAA,GAAW,OAAO;CAEhC,IAAI,CAAC,YAAY,KAAK,IAAI,GACxB,MAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,YAAY,KAAK,aAAa;EACpE,OAAO,KAAK;EACZ;CACF,CAAC;CAEH,MAAM,QAAQ,OAAO,IAAI;CACzB,IAAI,QAAQ,KAAK,OAAO,QAAQ,KAAK,UACnC,MAAM,IAAI,gBACR,GAAG,KAAK,MAAM,WAAW,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,SAAS,IACpE;EAAE,OAAO,KAAK;EAAO;CAAS,CAChC;CAEF,OAAO;AACT;;AAGA,SAAS,WAAW,MAAc,MAAiB,UAA0B;CAC3E,OAAO,iBAAiB,YAAY,MAAM,MAAM,QAAQ,GAAG,IAAI;AACjE;AAEA,SAAS,UAAU,MAAc,MAAiB,UAA4B;CAC5E,IAAI,SAAS,IACX,MAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,aAAa;EACnD,OAAO,KAAK;EACZ;CACF,CAAC;CAEH,IAAI,SAAS,KAAK,OAAO,EAAE,MAAM,MAAM;CAEvC,IAAI,SAAS,KAAK;EAChB,IAAI,KAAK,UAAU,gBAAgB,KAAK,UAAU,aAChD,MAAM,IAAI,gBAAgB,2BAA2B;GACnD,OAAO,KAAK;GACZ;EACF,CAAC;EAEH,OAAO,EAAE,MAAM,aAAa;CAC9B;CAEA,IAAI,KAAK,UAAU,cAAc;EAC/B,IAAI,SAAS,KAAK,OAAO,EAAE,MAAM,OAAO;EACxC,MAAM,aAAa,gBAAgB,KAAK,IAAI;EAC5C,IAAI,aAAa,OAAO,KAAA,GAAW;GACjC,MAAM,SAAS,OAAO,WAAW,EAAE;GACnC,IAAI,SAAS,IACX,MAAM,IAAI,gBAAgB,MAAM,OAAO,8BAA8B;IACnE,OAAO,KAAK;IACZ;GACF,CAAC;GAEH,OAAO;IAAE,MAAM;IAAQ;GAAO;EAChC;EACA,MAAM,UAAU,gBAAgB,KAAK,IAAI;EACzC,IAAI,UAAU,OAAO,KAAA,GACnB,OAAO;GAAE,MAAM;GAAkB,KAAK,WAAW,QAAQ,IAAI,MAAM,QAAQ;EAAE;CAEjF;CAEA,IAAI,KAAK,UAAU,aAAa;EAC9B,MAAM,OAAO,KAAK,QAAQ,GAAG;EAC7B,IAAI,QAAQ,GAAG;GACb,MAAM,UAAU,WAAW,KAAK,MAAM,GAAG,IAAI,GAAG,MAAM,QAAQ;GAC9D,MAAM,UAAU,KAAK,MAAM,OAAO,CAAC;GACnC,IAAI,CAAC,UAAU,KAAK,OAAO,GACzB,MAAM,IAAI,gBAAgB,yBAAyB;IACjD,OAAO,KAAK;IACZ,UAAU,WAAW,OAAO;GAC9B,CAAC;GAEH,OAAO;IAAE,MAAM;IAAO;IAAS,KAAK,OAAO,OAAO;GAAE;EACtD;EACA,IAAI,SAAS,KAAK,IAAI,GAEpB,OAAO;GAAE,MAAM;GAAO,SADN,WAAW,KAAK,MAAM,GAAG,EAAE,GAAG,MAAM,QACxB;GAAG,KAAK;EAAG;EAEzC,IAAI,KAAK,YAAY,MAAM,KACzB,MAAM,IAAI,gBAAgB,yCAAyC;GACjE,OAAO,KAAK;GACZ;EACF,CAAC;CAEL;CAEA,MAAM,OAAO,KAAK,QAAQ,GAAG;CAC7B,IAAI,OAAO,GAAG;EACZ,MAAM,OAAO,YAAY,KAAK,MAAM,GAAG,IAAI,GAAG,MAAM,QAAQ;EAC5D,MAAM,KAAK,YAAY,KAAK,MAAM,OAAO,CAAC,GAAG,MAAM,WAAW,OAAO,CAAC;EAItE,IAAI,KAAK,UAAU,eAAe,SAAS,KAAK,OAAO,OAAO,KAAK,UACjE,OAAO;GAAE,MAAM;GAAS,MAAM,KAAK;GAAK,IAAI,KAAK;EAAI;EAEvD,OAAO;GACL,MAAM;GACN,MAAM,iBAAiB,MAAM,IAAI;GACjC,IAAI,iBAAiB,IAAI,IAAI;EAC/B;CACF;CAEA,OAAO;EAAE,MAAM;EAAS,OAAO,WAAW,MAAM,MAAM,QAAQ;CAAE;AAClE;AAEA,SAAS,UAAU,MAAc,MAAiB,UAA4B;CAC5E,MAAM,QAAQ,KAAK,QAAQ,GAAG;CAC9B,IAAI,QAAQ,GAAG,OAAO,UAAU,MAAM,MAAM,QAAQ;CAEpD,MAAM,WAAW,KAAK,MAAM,QAAQ,CAAC;CACrC,IAAI,CAAC,YAAY,KAAK,QAAQ,GAC5B,MAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,cAAc,SAAS,aAAa;EAC1E,OAAO,KAAK;EACZ,UAAU,WAAW,QAAQ;CAC/B,CAAC;CAEH,MAAM,OAAO,OAAO,QAAQ;CAC5B,IAAI,OAAO,GACT,MAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,4BAA4B;EAClE,OAAO,KAAK;EACZ,UAAU,WAAW,QAAQ;CAC/B,CAAC;CAGH,MAAM,WAAW,KAAK,MAAM,GAAG,KAAK;CACpC,MAAM,OAAO,UAAU,aAAa,KAAK,MAAM,UAAU,MAAM,QAAQ;CACvE,IAAI,KAAK,SAAS,SAIhB,OAAO;EAAE,MAAM;EAAQ,MAAM,UAAU,GAAG,SAAS,GAAG,KAAK,YAAY,MAAM,QAAQ;EAAG;CAAK;CAE/F,IAAI,KAAK,SAAS,SAAS,KAAK,SAAS,SACvC,MAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,8BAA8B;EACpE,OAAO,KAAK;EACZ;CACF,CAAC;CAEH,OAAO;EAAE,MAAM;EAAQ;EAAM;CAAK;AACpC;AAEA,SAAS,WAAW,MAAc,MAAiB,QAA0B;CAE3E,MAAM,QADQ,WAAW,MAAM,QAAQ,GACrB,CAAC,CAAC,KAAK,SAAS,UAAU,KAAK,MAAM,MAAM,KAAK,MAAM,CAAC;CACzE,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,aAAa;EACnD,OAAO,KAAK;EACZ,UAAU;CACZ,CAAC;CAEH,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,OAAO;EAAE,MAAM;EAAQ;CAAM;AAC/B;AAEA,SAAS,kBAAkB,KAAe,MAAgC;CACxE,QAAQ,IAAI,MAAZ;EACE,KAAK;GACH,KAAK,IAAI,GAAG;GACZ;EACF,KAAK;GACH,KAAK,IAAI,IAAI,QAAQ,KAAK,MAAM,GAAG;GACnC;EACF,KAAK;GACH,KAAK,IAAI,GAAG;GACZ;EACF,KAAK;GACH,KAAK,IAAI,GAAG;GACZ;EACF,KAAK;GACH,KAAK,MAAM,QAAQ,IAAI,OAAO,kBAAkB,MAAM,IAAI;GAC1D;EACF,KAAK,QACH,kBAAkB,IAAI,MAAM,IAAI;CAIpC;AACF;;;;AAKA,SAAgB,gBAAgB,YAAoB,UAAyB,CAAC,GAAqB;CACjG,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,gBAAgB,qBAAqB;CAEjD,MAAM,UAAU,WAAW,KAAK;CAChC,IAAI,YAAY,IACd,MAAM,IAAI,gBAAgB,YAAY;CAGxC,IAAI,SAAS;CACb,IAAI;CACJ,IAAI,OAAO,WAAW,GAAG,GAAG;EAG1B,MAAM,QAAQ,OAAO,KAAK,MAAM,CAAC,GAAG,MAAM;EAC1C,MAAM,QAAQ,MAAM,YAAY;EAChC,MAAM,WAAW,OAAO;EACxB,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,SAAS,qBAAqB;GACpC,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,gBAAgB,IAAI,MAAM,KAAK,UAAU,EAAE,UAAU,EAAE,CAAC;GAEpE,MAAM,IAAI,gBAAgB,QAAQ,MAAM,eAAe,EAAE,UAAU,EAAE,CAAC;EACxE;EACA,QAAQ;EACR,SAAS;CACX;CAEA,MAAM,QAAQ,QAAQ,YAAY,OAAO,2BAA2B;CACpE,MAAM,SAAiB,CAAC;CACxB,MAAM,KAAK;CACX,IAAI,QAAQ,GAAG,KAAK,MAAM;CAC1B,OAAO,UAAU,MAAM;EACrB,OAAO,KAAK;GAAE,MAAM,MAAM;GAAI,QAAQ,MAAM;EAAM,CAAC;EACnD,QAAQ,GAAG,KAAK,MAAM;CACxB;CAEA,IAAI,OAAO,WAAW,MAAM,QAAQ;EAClC,MAAM,OACJ,OAAO,WAAW,KAAK,QAAQ,YAAY,OACvC,oCACA;EACN,MAAM,IAAI,gBACR,eAAe,MAAM,OAAO,UAAU,OAAO,OAAO,QAAQ,QAC5D,EAAE,UAAU,EAAE,CAChB;CACF;CAOA,MAAM,SAAkB,MAAM,KAAK,MAAM,UAAU;EACjD,MAAM,OAAO,OAAO;;EAEpB,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,gBAAgB,aAAa;EAC/D,OAAO;GAAE;GAAM;GAAM,KAAK,WAAW,KAAK,MAAM,MAAM,KAAK,MAAM;EAAE;CACrE,CAAC;CAED,MAAM,UAAU,IAAI,IAAsB,OAAO,KAAK,UAAU,CAAC,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC;CAC1F,MAAM,OAAO,UAA4B;EACvC,MAAM,QAAQ,QAAQ,IAAI,KAAK;;EAE/B,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,gBAAgB,eAAe;EAClE,OAAO;CACT;CAEA,MAAM,SAAS,IAAI,QAAQ;CAC3B,MAAM,OAAO,IAAI,MAAM;CACvB,MAAM,aAAa,IAAI,YAAY;CACnC,MAAM,QAAQ,IAAI,OAAO;CACzB,MAAM,YAAY,IAAI,WAAW;CACjC,MAAM,UAAU,QAAQ,YAAY,OAAO,IAAI,QAAQ,IAAI,KAAA;CAE3D,MAAM,MAAe;EACnB,QAAQ,OAAO;EACf,MAAM,KAAK;EACX,YAAY,WAAW;EACvB,OAAO,MAAM;EACb,WAAW,UAAU;CACvB;CACA,IAAI,YAAY,KAAA,GAAW,IAAI,UAAU,QAAQ;CAEjD,MAAM,6BAAa,IAAI,IAAmB;CAC1C,KAAK,MAAM,SAAS,QAAQ,kBAAkB,MAAM,KAAK,UAAU;CAEnE,MAAM,SAA2B;EAC/B;EACA,KAAK;GACH,QAAQ,OAAO,KAAK;GACpB,MAAM,KAAK,KAAK;GAChB,YAAY,WAAW,KAAK;GAC5B,OAAO,MAAM,KAAK;GAClB,WAAW,UAAU,KAAK;EAC5B;EACA,YAAY,CAAC,GAAG,UAAU;CAC5B;CACA,IAAI,YAAY,KAAA,GAAW,OAAO,IAAI,UAAU,QAAQ,KAAK;CAC7D,IAAI,UAAU,KAAA,GAAW,OAAO,QAAQ;CACxC,OAAO;AACT;;;;AC/UA,SAAgB,aAAa,KAAwB;CACnD,QAAQ,IAAI,MAAZ;EACE,KAAK;EACL,KAAK;EACL,KAAK,kBACH,OAAO;EACT,KAAK,QACH,OAAO,IAAI,MAAM,KAAK,YAAY;EACpC,KAAK,QACH,OAAO,aAAa,IAAI,IAAI;EAC9B,SACE,OAAO;CACX;AACF;;AAGA,SAAgB,MAAM,KAAwB;CAC5C,IAAI,IAAI,SAAS,SAAS,IAAI,SAAS,cAAc,OAAO;CAC5D,IAAI,IAAI,SAAS,QAAQ,OAAO,IAAI,SAAS,KAAK,MAAM,IAAI,IAAI;CAChE,OAAO;AACT;;AAGA,SAAgB,UAAU,KAAe,MAA0B;CACjE,IAAI,MAAM,GAAG,GAAG,OAAO;CACvB,IAAI,aAAa,GAAG,GAAG,OAAO;CAC9B,OAAO,YAAY,KAAK,IAAI,CAAC,CAAC,WAAW,KAAK,MAAM,KAAK,MAAM;AACjE;;;;;AAMA,SAAgB,cAAc,KAAe,MAAqC;CAChF,IAAI,IAAI,SAAS,QAAQ,OAAO,KAAA;CAChC,MAAM,OAAO,IAAI;CAKjB,IAAI,EADF,MAAM,IAAI,KAAM,KAAK,SAAS,WAAW,KAAK,SAAS,KAAK,OAAO,KAAK,OAAO,KAAK,MACxE,OAAO,KAAA;CAErB,IAAI,IAAI,OAAO,KAAK,MAAM,KAAK,KAAK,OAAO,KAAA;CAC3C,OAAO,IAAI;AACb;;;;;AAMA,SAAgB,UACd,KACA,MACwD;CACxD,IAAI,IAAI,SAAS,UAAU,IAAI,KAAK,SAAS,SAAS,OAAO,KAAA;CAC7D,MAAM,EAAE,MAAM,OAAO,IAAI;CACzB,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM;CACnC,MAAM,QAAQ,QAAQ,KAAK,KAAK,OAAO,OAAO,OAAO;CACrD,IAAI,IAAI,OAAO,OAAO,OAAO,KAAA;CAC7B,OAAO;EAAE;EAAM;EAAI,MAAM,IAAI;CAAK;AACpC;AAEA,SAAS,YAAY,MAAc,IAAY,MAAiB,MAAwB;CACtF,MAAM,SAAmB,CAAC;CAC1B,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM;CAEnC,MAAM,SAAS,QAAQ,KAAK,KAAK,OAAO,IAAI,OAAO,OAAO,KAAK;CAC/D,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,MAC/B,OAAO,KAAK,KAAK,OAAQ,OAAO,KAAK,MAAM,KAAK,IAAK;CAEvD,OAAO;AACT;;;;;AAMA,SAAgB,YAAY,KAAe,MAA2B;CACpE,MAAM,SAASA,UAAQ,KAAK,IAAI;CAChC,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;AAClD;AAEA,SAASA,UAAQ,KAAe,MAA2B;CACzD,QAAQ,IAAI,MAAZ;EACE,KAAK;EACL,KAAK,cACH,OAAO,YAAY,KAAK,KAAK,KAAK,KAAK,MAAM,CAAC;EAChD,KAAK,SACH,OAAO,CAAC,IAAI,KAAK;EACnB,KAAK,SACH,OAAO,YAAY,IAAI,MAAM,IAAI,IAAI,MAAM,CAAC;EAC9C,KAAK,QAAQ;GACX,MAAM,OAAO,IAAI;GACjB,IAAI,KAAK,SAAS,SAAS,OAAO,YAAY,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,IAAI;GAChF,OAAO,YAAY,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI;EACvD;EACA,KAAK,QACH,OAAO,IAAI,MAAM,SAAS,SAASA,UAAQ,MAAM,IAAI,CAAC;EACxD,SACE,OAAO,CAAC;CACZ;AACF;;AAGA,SAAgB,YAAY,KAAuB;CACjD,QAAQ,IAAI,MAAZ;EACE,KAAK,OACH,OAAO;EACT,KAAK,cACH,OAAO;EACT,KAAK,SACH,OAAO,OAAO,IAAI,KAAK;EACzB,KAAK,SACH,OAAO,GAAG,IAAI,KAAK,GAAG,IAAI;EAC5B,KAAK,QACH,OAAO,GAAG,YAAY,IAAI,IAAI,EAAE,GAAG,IAAI;EACzC,KAAK,QACH,OAAO,IAAI,MAAM,IAAI,WAAW,CAAC,CAAC,KAAK,GAAG;EAC5C,KAAK,QACH,OAAO,IAAI,WAAW,KAAA,IAAY,MAAM,KAAK,IAAI;EACnD,KAAK,OACH,OAAO,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,GAAG,IAAI;EACpE,KAAK,kBACH,OAAO,GAAG,IAAI,IAAI;CACtB;AACF;;AAGA,SAAgB,SAAS,QAA2C;CAClE,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,OAAO,OAAO,SAAS;EACpC,IAAI,SAAS,KAAA,KAAa,UAAU,KAAK,KAAK,GAC5C,KAAK,KAAK;OAEV,OAAO,KAAK,CAAC,OAAO,KAAK,CAAC;CAE9B;CACA,OAAO;AACT;;AAGA,SAAgB,iBAAiB,KAAsB;CACrD,MAAM,SAAS;EAAC,IAAI;EAAQ,IAAI;EAAM,IAAI;EAAY,IAAI;EAAO,IAAI;CAAS,CAAC,CAAC,IAAI,WAAW;CAC/F,IAAI,IAAI,YAAY,KAAA,GAAW,OAAO,QAAQ,YAAY,IAAI,OAAO,CAAC;CACtE,OAAO,OAAO,KAAK,GAAG;AACxB;;;;ACtIA,SAAS,QAAQ,MAAmB;CAClC,OAAO;EACL,MAAM,KAAK,eAAe;EAC1B,OAAO,KAAK,YAAY,IAAI;EAC5B,KAAK,KAAK,WAAW;EACrB,MAAM,KAAK,YAAY;EACvB,QAAQ,KAAK,cAAc;EAC3B,QAAQ,KAAK,cAAc;EAC3B,WAAW,KAAK,UAAU;CAC5B;AACF;;AAGA,SAAS,OACP,MACA,OACA,KACA,MACA,QACA,QACM;CACN,OAAO,IAAI,KAAK,KAAK,IAAI,MAAM,QAAQ,GAAG,KAAK,MAAM,QAAQ,QAAQ,CAAC,CAAC;AACzE;;AAGA,SAAS,QAAQ,QAAkB,OAA8B;CAC/D,KAAK,MAAM,aAAa,QACtB,IAAI,aAAa,OAAO,OAAO;CAEjC,OAAO;AACT;;AAGA,MAAM,eAAe;;AAGrB,MAAM,iBAAiB;;;;;;;;;AAUvB,SAAgB,KAAK,YAAoB,UAAuB,CAAC,GAAW;CAE1E,MAAM,SAAS,gBAAgB,YADT,QAAQ,YAAY,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC,CACd;CACxD,IAAI,OAAO,WAAW,MAAM,cAAc,cAAc,GAAG,GAAG,OAAO,CAAC;CAEtE,MAAM,QAAQ,QAAQ,SAAS;CAC/B,IAAI,SAAS,GAAG,OAAO,CAAC;CAExB,MAAM,OAAO,QAAQ,wBAAQ,IAAI,KAAK;CACtC,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO,CAAC;CAE1C,MAAM,MAAM,OAAO;CACnB,MAAM,UAAU,IAAI,YAAY,KAAA,IAAY,CAAC,CAAC,IAAI,YAAY,IAAI,SAAS,WAAW;CACtF,MAAM,UAAU,YAAY,IAAI,QAAQ,WAAW;CACnD,MAAM,QAAQ,YAAY,IAAI,MAAM,SAAS;CAC7C,MAAM,SAAS,YAAY,IAAI,OAAO,UAAU;CAChD,MAAM,OAAO,YAAY,IAAI,YAAY,QAAQ;CACjD,MAAM,WAAW,YAAY,IAAI,WAAW,QAAQ;CACpD,IAAI;EAAC;EAAS;EAAS;EAAO;CAAM,CAAC,CAAC,MAAM,WAAW,OAAO,WAAW,CAAC,GAAG,OAAO,CAAC;CAErF,MAAM,gBAAgB,CAAC,MAAM,IAAI,UAAU;CAC3C,MAAM,gBAAgB,CAAC,MAAM,IAAI,SAAS;CAC1C,MAAM,SAAS,IAAI,IAAI,IAAI;CAC3B,MAAM,aAAa,IAAI,IAAI,QAAQ;CACnC,MAAM,WAAW,IAAI,IAAI,MAAM;CAE/B,MAAM,cAAc,UAA0B;EAC5C,IAAI,iBAAiB,eACnB,OAAO,OAAO,IAAI,MAAM,GAAG,KAAK,WAAW,IAAI,MAAM,SAAS;EAEhE,IAAI,eAAe,OAAO,OAAO,IAAI,MAAM,GAAG;EAC9C,IAAI,eAAe,OAAO,WAAW,IAAI,MAAM,SAAS;EACxD,OAAO;CACT;CAGA,MAAM,YADa,QAAQ,IACA,CAAC,CAAC,OAAO;CAGpC,MAAM,UAAU,QAAQ,IAAI,KAAK,KAAK,QAAQ,IAAI,GAAI,CAAC;CACvD,IAAI,SAAS,OACX,QAAQ,MACR,QAAQ,OACR,QAAQ,KACR,QAAQ,MACR,QAAQ,QACR,QAAQ,MACV;CAEA,MAAM,UAAkB,CAAC;CACzB,IAAI,aAAa;CACjB,OAAO,QAAQ,SAAS,SAAS,aAAa,gBAAgB;EAC5D,cAAc;EACd,MAAM,QAAQ,QAAQ,MAAM;EAC5B,IAAI,MAAM,OAAO,WAAW;EAE5B,IAAI,CAAC,SAAS,IAAI,MAAM,KAAK,GAAG;GAC9B,SAAS,OAAO,MAAM,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC;GACvD;EACF;EACA,IAAI,CAAC,WAAW,KAAK,GAAG;GACtB,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC;GAC/D;EACF;EACA,MAAM,OAAO,QAAQ,OAAO,MAAM,IAAI;EACtC,IAAI,SAAS,MAAM;GACjB,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC;GAC/D;EACF;EACA,IAAI,SAAS,MAAM,MAAM;GACvB,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,GAAG,CAAC;GAC9D;EACF;EACA,MAAM,SAAS,QAAQ,SAAS,MAAM,MAAM;EAC5C,IAAI,WAAW,MAAM;GACnB,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,OAAO,GAAG,GAAG,CAAC;GACxE;EACF;EACA,IAAI,WAAW,MAAM,QAAQ;GAC3B,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,MAAM,QAAQ,CAAC;GACzE;EACF;EACA,MAAM,SAAS,QAAQ,SAAS,MAAM,MAAM;EAC5C,IAAI,WAAW,MAAM;GACnB,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,MAAM,MAAM,SAAS,GAAG,CAAC;GACnF;EACF;EACA,IAAI,WAAW,MAAM,QAAQ;GAC3B,SAAS,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,MAAM,MAAM,QAAQ,MAAM;GACpF;EACF;EAEA,QAAQ,KAAK,IAAI,KAAK,OAAO,QAAQ,CAAC,CAAC;EACvC,SAAS,IAAI,KAAK,OAAO,QAAQ,IAAI,GAAI;CAC3C;CAEA,OAAO;AACT;;;;;;;;ACxJA,MAAa,oBAAoB;;AAsBjC,MAAM,6BAAa,IAAI,IAAiC;AAExD,SAAS,UAAU,UAAuC;CACxD,MAAM,SAAS,WAAW,IAAI,QAAQ;CACtC,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,UAAU,IAAI,KAAK,eAAe,SAAS;EAC/C;EAEA,WAAW;EACX,MAAM;EACN,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACR,QAAQ;CACV,CAAC;CACD,WAAW,IAAI,UAAU,OAAO;CAChC,OAAO;AACT;;;;;;;AAQA,SAAgB,gBAAgB,IAAqB;CACnD,IAAI,OAAO,KAAA,GAAW,OAAO;CAC7B,MAAM,YACJ,OAAA,UAAyB,IAAI,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC,WAAW;CAClF,IAAI;EACF,OAAO,IAAI,KAAK,eAAe,SAAS,EAAE,UAAU,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;CACrF,QAAQ;EACN,MAAM,IAAI,kBAAkB,WAAW,GAAG,aAAa,EAAE;CAC3D;AACF;;AAGA,SAAS,MAAM,MAAyB;CACtC,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK,QAAQ,GAAG,KAAK,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,MAAM;AAC1F;;AAGA,SAAgB,oBACd,UACA,MACqC;CACrC,MAAM,QAAgC,CAAC;CACvC,KAAK,MAAM,QAAQ,UAAU,QAAQ,CAAC,CAAC,cAAc,IAAI,GACvD,IAAI,KAAK,SAAS,WAAW,MAAM,KAAK,QAAQ,KAAK;CAEvD,MAAM,OAAO,OAAO,MAAM,IAAI;CAC9B,MAAM,QAAQ,OAAO,MAAM,KAAK;CAChC,MAAM,MAAM,OAAO,MAAM,GAAG;CAC5B,MAAM,OAAkB;EACtB;EACA;EACA;EAEA,MAAM,OAAO,MAAM,IAAI,IAAI;EAC3B,QAAQ,OAAO,MAAM,MAAM;EAC3B,QAAQ,OAAO,MAAM,MAAM;EAE3B,WAAW,IAAI,KAAK,KAAK,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU;CAChE;CACA,OAAO;EAAE;EAAM,SAAS,MAAM,IAAI,IAAI,KAAK,MAAM,KAAK,QAAQ,IAAI,GAAI,IAAI,OAAQ;CAAO;AAC3F;;AAGA,SAAS,cAAc,UAAkB,MAAoB;CAC3D,OAAO,oBAAoB,UAAU,IAAI,CAAC,CAAC;AAC7C;AAsBA,MAAM,+BAAe,IAAI,IAAoB;;;;;;;;;;;AAY7C,SAAgB,mBAAmB,UAAkB,4BAAkB,IAAI,KAAK,GAAW;CACzF,MAAM,OAAO,UAAU,eAAe;CACtC,MAAM,MAAM,GAAG,SAAS,GAAG;CAC3B,MAAM,SAAS,aAAa,IAAI,GAAG;CACnC,IAAI,WAAW,KAAA,GAAW,OAAO;CAEjC,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,IAAI,QAAQ,GAAG,QAAQ,IAAI,SAAS,GACvC,QAAQ,IAAI,cAAc,UAAU,IAAI,KAAK,KAAK,IAAI,MAAM,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;CAE9E,MAAM,CAAC,UAAU,CAAC,GAAG,OAAO;CAC5B,IAAI,QAAQ,OAAO,KAAK,WAAW,KAAA,GACjC,MAAM,IAAI,kBACR,GAAG,SAAS,KAAK,KAAK,GAAG,OAAO,EAAE,kDAElC,QACF;CAEF,aAAa,IAAI,KAAK,MAAM;CAC5B,OAAO;AACT;;;AC5IA,MAAM,kBAAkB;;AAGxB,MAAM,eAAe;AACrB,MAAM,eAAe;AAErB,SAAS,IAAI,OAAe,MAAsB;CAChD,QAAS,QAAQ,OAAQ,QAAQ;AACnC;AAEA,SAAS,OAAO,QAAoC;CAClD,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;AAClD;AAEA,SAAS,WAAW,MAAgB,OAA0B;CAC5D,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,OAAO,OAAO,UAAU,UAAU,MAAM,MAAM;AAC5F;;AAGA,SAAS,aAAa,SAAyB;CAC7C,MAAM,WAAW,KAAK,IAAI,OAAO;CACjC,MAAM,OAAO,KAAK,MAAM,WAAW,EAAE;CACrC,MAAM,SAAS,WAAW;CAC1B,OAAO,GAAG,UAAU,IAAI,MAAM,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,CAAC,SAAS,GAAG,GAAG;AAC5E;;;;;;;AAQA,SAAS,WAAW,QAAkB,MAA2B;CAC/D,MAAM,QAAQ,OAAO;CACrB,MAAM,OAAO,OAAO,OAAO,SAAS;;CAEpC,IAAI,UAAU,KAAA,KAAa,SAAS,KAAA,GAAW,OAAO,EAAE,MAAM,MAAM;CACpE,IAAI,OAAO,WAAW,KAAK,MAAM,KAAK,MAAM,GAAG,OAAO,EAAE,MAAM,MAAM;CACpE,IAAI,OAAO,WAAW,GAAG,OAAO;EAAE,MAAM;EAAS,OAAO;CAAM;CAE9D,MAAM,OAAQ,OAAO,KAAgB;CAKrC,IAHE,OAAO,SAAS,KAChB,OAAO,KACP,OAAO,OAAO,OAAO,UAAU,UAAU,KAAK,QAAS,OAAO,QAAQ,OAAkB,IAAI,GAK5F,OAAO;EAAE,MAAM;EAAQ,MAFP,UAAU,KAAK,OAAO,OAAO,OAAO,KAAK,MACxB,EAAE,MAAM,MAAM,IAAI;GAAE,MAAM;GAAS,MAAM;GAAO,IAAI;EAAK;EAC7D;CAAK;CAGpC,MAAM,QAAQ,SAAS,MAAM,CAAC,CAAC,KAC5B,CAAC,MAAM,QACN,SAAS,KAAK;EAAE,MAAM;EAAS,OAAO;CAAK,IAAI;EAAE,MAAM;EAAS;EAAM;CAAG,CAC7E;CACA,OAAO,MAAM,WAAW,IAAK,MAAM,KAAkB;EAAE,MAAM;EAAQ;CAAM;AAC7E;;;;;;;;;;AAWA,SAAgB,SAAS,KAAc,UAAkB,WAAoC;CAE3F,IAAI,aAAA,OAA+B,OAAO;CAE1C,MAAM,aAAa,mBAAmB,QAAQ;CAC9C,MAAM,eAAe,cAAc,YAAY,aAAa,CAAC;CAC7D,IAAI,iBAAiB,GAAG,OAAO;CAG/B,MAAM,SAAS,aAAa,UAAU;CACtC,MAAM,QAAQ,WAA0B;EACtC,MAAM,IAAI,kBAAkB,GAAG,SAAS,MAAM,OAAO,KAAK,UAAU,QAAQ;CAC9E;CAEA,MAAM,UAAU,YAAY,IAAI,QAAQ,WAAW;CACnD,MAAM,QAAQ,YAAY,IAAI,MAAM,SAAS;CAC7C,IAAI,QAAQ,WAAW,KAAK,MAAM,WAAW,GAC3C,OAAO,KAAK,qCAAqC;CAInD,MAAM,wBAAQ,IAAI,IAAY;CAC9B,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAQ,OAAO,KAAK,SAAS;EACnC,MAAM,IAAI,IAAI,OAAO,eAAe,CAAC;EACrC,QAAQ,IAAI,KAAK,MAAM,QAAQ,eAAe,CAAC;CACjD;CAGF,MAAM,aAAa,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,UAAU,QAAQ,EAAE,CAAC;CAC/D,MAAM,WAAW,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,UAAU,KAAK,MAAM,QAAQ,EAAE,CAAC,CAAC;CAEzE,IAAI,WAAW,SAAS,SAAS,WAAW,MAAM,MAChD,OAAO,KACL,uDAEF;CAMF,MAAM,gBAAgB,CAAC,MAAM,IAAI,UAAU;CAC3C,MAAM,gBAAgB,CAAC,MAAM,IAAI,SAAS;CAC1C,MAAM,kBAAkB,CAAC,UAAU,IAAI,OAAO,UAAU;CACxD,MAAM,WAAW,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAEtD,MAAM,CAAC,aAAa,CAAC,GAAG,OAAO;CAC/B,MAAM,WAAW,QAAQ,SAAS,KAAK,cAAc,KAAA,IAAY,YAAY;CAC7E,IAAI,aAAa,QAAQ,CAAC,UACxB,OAAO,KAAK,yCAAyC;CAGvD,IAAI,aAAa,IAAI;CACrB,IAAI,YAAY,IAAI;CACpB,IAAI,aAAa,QAAQ,aAAa,KAAK,CAAC,UAAU;EACpD,IAAI,aAAa,IAAI,UAAU,KAAK,aAAa,IAAI,SAAS,GAC5D,OAAO,KAAK,uCAAuC;EAIrD,IAAI,oBAAoB,CAAC,iBAAiB,gBACxC,OAAO,KAAK,oCAAoC;EAElD,IAAI,eAAe;GACjB,MAAM,OAAO,YAAY,IAAI,YAAY,QAAQ;GACjD,MAAM,cAAc,KAAK,KAAK,QAAQ,MAAM,QAAQ;GAQpD,IAAI,CANS,KAAK,OACf,KAAK,UACJ,OAAO,gBACN,YAAY,UAAqB,gBACjC,YAAY,UAAqB,YAE9B,GACN,OAAO,KACL,uEAEF;GAEF,aAAa,WAAW,aAAa,QAAQ;EAC/C;EACA,IAAI,eAEF,YAAY,WAAW,OADN,YAAY,IAAI,WAAW,QACP,CAAC,CAAC,KAAK,QAAQ,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ;CAE1F;CAEA,OAAO;EACL,GAAG;EACH,QAAQ,WAAW,YAAY,OAAO,IAAI,IAAI,SAAS,WAAW,YAAY,WAAW;EACzF,MAAM,WAAW,UAAU,KAAK,IAAI,IAAI,OAAO,WAAW,UAAU,SAAS;EAC7E;EACA;CACF;AACF;;;;;;;AAQA,SAAgB,gBACd,YACA,UACA,WACA,UAAyB,CAAC,GAClB;CACR,IAAI,aAAA,OAA+B,OAAO;CAC1C,MAAM,EAAE,QAAQ,gBAAgB,YAAY,OAAO;CACnD,OAAO,iBAAiB,SAAS,KAAK,UAAU,SAAS,CAAC;AAC5D;;;AC9LA,MAAM,gBAAgB;CAAC;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AAAE;AACrE,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;AAKA,SAAgB,SAAS,YAAoB,UAAyB,CAAC,GAAqB;CAC1F,MAAM,SAA4B,CAAC;CACnC,MAAM,WAAqB,CAAC;CAE5B,IAAI;CACJ,IAAI;EACF,SAAS,gBAAgB,YAAY,OAAO;CAC9C,SAAS,OAAO;EACd,IAAI,iBAAiB,iBAAiB;GACpC,MAAM,QAAyB;IAC7B,OAAO,MAAM,SAAS;IACtB,SAAS,MAAM;GACjB;GACA,IAAI,MAAM,aAAa,KAAA,GAAW,MAAM,WAAW,MAAM;GACzD,OAAO,KAAK,KAAK;GACjB,OAAO;IAAE,OAAO;IAAO;IAAQ;GAAS;EAC1C;;EAEA,MAAM;CACR;CAEA,MAAM,EAAE,KAAK,eAAe;CAE5B,IAAI,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,GAAG;EACpF,MAAM,OAAO,WAAW,QAAQ,cAAc,cAAc,GAAG,CAAC,CAAC,KAAK,MAAM;EAC5E,SAAS,KAAK,IAAI,KAAK,6CAA6C;EACpE,SAAS,KAAK,gCAAgC;CAChD;CAEA,IAAI,CAAC,MAAM,IAAI,UAAU,KAAK,CAAC,MAAM,IAAI,SAAS,GAChD,SAAS,KACP,qDACF;CAGF,IACE,CAAC,MAAM,IAAI,KAAK,KAChB,CAAC,MAAM,IAAI,UAAU,KACrB,CAAC,aAAa,IAAI,UAAU,KAC5B,CAAC,aAAa,IAAI,KAAK,GACvB;EACA,MAAM,SAAS,YAAY,IAAI,OAAO,UAAU;EAChD,MAAM,OAAO,YAAY,IAAI,YAAY,QAAQ;EACjD,MAAM,aAAuB,CAAC;EAC9B,IAAI,cAAc;EAClB,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,QAAQ,cAAc,QAAQ,MAAM;GAC1C,KAAK,MAAM,OAAO,MAChB,IAAI,OAAO,OACT,cAAc;QAEd,WAAW,KAAK,GAAG,aAAa,QAAQ,MAAM,GAAG,MAAM,KAAK,IAAI,EAAE;EAGxE;EACA,IAAI,CAAC,eAAe,WAAW,SAAS,GACtC,SAAS,KAAK,GAAG,WAAW,KAAK,GAAG,EAAE,uBAAuB;OACxD,IAAI,WAAW,SAAS,GAC7B,SAAS,KAAK,GAAG,WAAW,KAAK,GAAG,EAAE,qBAAqB;EAE7D,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,SAAS,EAAE,GACxC,SAAS,KAAK,qBAAqB;CAEvC;CAEA,OAAO;EAAE,OAAO;EAAM;EAAQ;CAAS;AACzC;;;ACtFA,SAAS,KAAK,OAAuB;CACnC,OAAO,QAAQ,KAAK,IAAI,UAAU,OAAO,KAAK;AAChD;;;;AAKA,SAAgB,WAAW,MAAc,OAA0B;CACjE,IAAI,MAAM,SAAS,OAAO,OAAO,GAAG,KAAK;CACzC,IAAI,OAAO,IAAI,OAAO,KAAK,KAAK;CAChC,OAAO,KAAK,OAAO,GAAG;AACxB;;;;AAKA,SAAgB,WAAW,MAAc,QAAgB,OAA0B;CACjF,IAAI,MAAM,UAAU,YAAY,MAAM,SAAS,SAAS,SAAS,MAAM,WAAW,GAChF,OAAO;CAET,MAAM,OAAO,WAAW,MAAM,KAAK;CACnC,IAAI,MAAM,UAAU,UAAU,OAAO,GAAG,OAAO,KAAK,MAAM,EAAE;CAC5D,OAAO,WAAW,IAAI,OAAO,GAAG,OAAO,OAAO;AAChD;;;;ACPA,SAAgB,OAAO,OAAyB;CAC9C,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,IAAI,MAAM,WAAW,GAAG,OAAO,MAAM,MAAM;CAC3C,IAAI,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,GAAG,MAAM;CACpD,OAAO,MAAM,KAAK,GAAG;AACvB;;;;AAKA,SAAgB,eACd,QACA,OACA,OACQ;CACR,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,CAAC,MAAM,OAAO,SAAS,MAAM,GAEtC,IAAI,KAAK,QAAQ,GACf,MAAM,KAAK,MAAM,MAAM,EAAE,CAAC;MAE1B,KAAK,IAAI,QAAQ,MAAM,SAAS,IAAI,SAAS,MAAM,KAAK,MAAM,KAAK,CAAC;CAGxE,OAAO,OAAO,KAAK;AACrB;AAEA,SAAgB,qBAAqB,KAAuB;CAE1D,OAAO,eADQ,YAAY,KAAK,WAEzB,IACJ,UAAU,GAAG,MAAM,KACnB,MAAM,OAAO,GAAG,KAAK,KAAK,GAAG,IAChC;AACF;;;;;;AAeA,SAAgB,WAAW,KAA2B;CACpD,IAAI,UAAU,KAAK,WAAW,GAAG,OAAO,EAAE,MAAM,MAAM;CACtD,MAAM,OAAO,cAAc,KAAK,WAAW;CAC3C,IAAI,SAAS,KAAA,GAAW,OAAO;EAAE,MAAM;EAAQ,MAAM,GAAG,KAAK;CAAK;CAClE,MAAM,SAAS,UAAU,KAAK,WAAW;CACzC,IAAI,WAAW,KAAA,GAAW,OAAO;EAAE,MAAM;EAAa,GAAG;CAAO;CAChE,MAAM,SAAS,YAAY,KAAK,WAAW;CAC3C,MAAM,QAAQ,OAAO;CACrB,IAAI,OAAO,WAAW,KAAK,UAAU,KAAA,GAAW,OAAO;EAAE,MAAM;EAAU,OAAO;CAAM;CACtF,OAAO;EAAE,MAAM;EAAU,MAAM,qBAAqB,GAAG;CAAE;AAC3D;;AAGA,SAAgB,WAAW,MAA0B;CACnD,QAAQ,KAAK,MAAb;EACE,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO,KAAK;EACd,KAAK,aACH,OAAO,GAAG,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK;EAClD,KAAK,UACH,OAAO,GAAG,KAAK,MAAM;EACvB,KAAK,UACH,OAAO,KAAK;CAChB;AACF;;;;;;AAOA,SAAgB,iBAAiB,MAA0B;CACzD,IAAI,KAAK,SAAS,aAAa,OAAO,WAAW,IAAI;CACrD,MAAM,EAAE,MAAM,IAAI,SAAS;CAC3B,IAAI,OAAO,YAAY,KAAK,OAAO,GAAG,KAAK,KAAK,KAAK;CACrD,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK;AACnC;;AAGA,SAAgB,oBAAoB,KAAuB;CACzD,OAAO,WAAW,WAAW,GAAG,CAAC;AACnC;AAEA,SAAgB,oBAAoB,KAAuB;CACzD,IAAI,UAAU,KAAK,WAAW,GAAG,OAAO;CACxC,MAAM,OAAO,cAAc,KAAK,WAAW;CAC3C,IAAI,SAAS,KAAA,GAAW,OAAO,GAAG,KAAK;CAEvC,OAAO,eADQ,YAAY,KAAK,WAEzB,IACJ,UAAU,GAAG,MAAM,KACnB,MAAM,OAAO,GAAG,KAAK,KAAK,GAAG,IAChC;AACF;AAEA,SAAgB,mBAAmB,KAAe,OAA0B;CAE1E,OAAO,eADQ,YAAY,KAAK,SAEzB,IACJ,UAAU,WAAW,OAAO,KAAK,IACjC,MAAM,OAAO,GAAG,WAAW,MAAM,KAAK,EAAE,IAAI,WAAW,IAAI,KAAK,EAAE,GACrE;AACF;AAEA,SAAgB,kBAAkB,KAAe,OAA0B;CACzE,IAAI,UAAU,KAAK,SAAS,GAAG,OAAO;CACtC,MAAM,OAAO,cAAc,KAAK,SAAS;CACzC,IAAI,SAAS,KAAA,GAAW,OAAO,GAAG,KAAK;CACvC,MAAM,SAAS,UAAU,KAAK,SAAS;CACvC,IAAI,WAAW,KAAA,GAGb,OAAO,GAFM,WAAW,OAAO,MAAM,KAExB,EAAE,IADJ,WAAW,OAAO,IAAI,KACb,EAAE,IAAI,OAAO,KAAK;CAExC,OAAO,mBAAmB,KAAK,KAAK;AACtC;AAEA,SAAgB,mBAAmB,KAAuB;CACxD,IAAI,UAAU,KAAK,UAAU,GAAG,OAAO;CACvC,MAAM,OAAO,cAAc,KAAK,UAAU;CAC1C,IAAI,SAAS,KAAA,GAAW,OAAO,GAAG,KAAK;CAEvC,OAAO,eADQ,YAAY,KAAK,UAEzB,IACJ,UAAU,GAAG,MAAM,KACnB,MAAM,OAAO,GAAG,KAAK,KAAK,GAAG,IAChC;AACF;AAEA,SAAgB,wBAAwB,KAAuB;CAC7D,IAAI,UAAU,KAAK,QAAQ,GAAG,OAAO;CACrC,IAAI,IAAI,SAAS,QACf,OAAO,IAAI,WAAW,KAAA,IAAY,OAAO,MAAM,IAAI,OAAO;CAE5D,IAAI,IAAI,SAAS,kBAAkB,OAAO,GAAG,IAAI,IAAI;CAGrD,MAAM,OAAO,cAAc,KAAK,QAAQ;CACxC,IAAI,SAAS,KAAA,GAAW,OAAO,GAAG,KAAK;CACvC,IAAI,IAAI,SAAS,UAAU,aAAa,GAAG,GACzC,OAAO,OAAO,IAAI,MAAM,IAAI,uBAAuB,CAAC;CAGtD,OAAO,eADQ,YAAY,KAAK,QAEzB,IACJ,UAAU,GAAG,MAAM,KACnB,MAAM,OAAO,GAAG,KAAK,KAAK,GAAG,IAChC;AACF;AASA,SAAS,SAAS,OAAuB;CACvC,OAAO,WAAW,UAAU,GAAG;AACjC;AAEA,SAAgB,uBAAuB,KAAe,SAA6B;CACjF,IAAI,IAAI,SAAS,SAAS,IAAI,SAAS,cAAc,OAAO;CAC5D,IAAI,IAAI,SAAS,OAAO;EACtB,MAAM,QAAQ,SAAS,IAAI,OAAO;EAClC,OAAO,IAAI,QAAQ,KAAK,KAAK,UAAU,IAAI,IAAI,MAAM;CACvD;CACA,IAAI,IAAI,SAAS,UAAU,aAAa,GAAG,GACzC,OAAO,OACL,IAAI,MAAM,KAAK,SAAS,uBAAuB,MAAM;EAAE,GAAG;EAAS,QAAQ;CAAM,CAAC,CAAC,CACrF;CAGF,MAAM,SAAS,YAAY,KAAK,QAAQ;CACxC,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,IAAI,QAAQ,UAAU;EACpB,MAAM,MAAM,OAAO,KAAK,GAAG;EAC3B,IAAI,QAAQ,aAAa,OAAO;EAChC,IAAI,QAAQ,OAAO,OAAO;CAC5B;CACA,MAAM,OAAO,eACX,QACA,WACC,MAAM,OAAO,GAAG,SAAS,IAAI,EAAE,IAAI,SAAS,EAAE,EAAE,GACnD;CACA,OAAO,QAAQ,SAAS,KAAK,SAAS;AACxC;;;;AC7LA,SAAS,YAAY,MAA0B;CAC7C,QAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;EACL,KAAK,aACH,OAAO,WAAW,IAAI;EACxB,KAAK,UACH,OAAO,KAAK,KAAK,MAAM;EACzB,KAAK,UACH,OAAO,KAAK,KAAK;CACrB;AACF;;;;;;;AAQA,SAAS,iBAAiB,MAA0B;CAClD,IAAI,KAAK,SAAS,aAAa,OAAO,KAAK,iBAAiB,IAAI;CAChE,OAAO,YAAY,IAAI;AACzB;;;;AAWA,SAAgB,aAAa,KAAc,SAA0C;CACnF,MAAM,SAAS,WAAW,IAAI,MAAM;CACpC,MAAM,OAAO,IAAI;CACjB,IAAI;CAEJ,MAAM,WAAW,cAAc,MAAM,SAAS;CAC9C,MAAM,YAAY,UAAU,MAAM,SAAS;CAE3C,IAAI,UAAU,MAAM,SAAS,GAC3B,SAAS;EAAE,MAAM,YAAY,MAAM;EAAG,WAAW;CAAK;MACjD,IAAI,aAAa,KAAA,GACtB,SAAS;EAAE,MAAM,GAAG,SAAS,OAAO,iBAAiB,MAAM,EAAE;EAAI,WAAW;CAAK;MAC5E,IAAI,cAAc,KAAA,GAIvB,SAAS;EAAE,MAAM,GAHJ,WAAW,UAAU,MAAM,OAGjB,EAAE,IAFd,WAAW,UAAU,IAAI,OAEN,EAAE,IAAI,GADpB,UAAU,KAAK,OAAO,iBAAiB,MAAM,EAAE;EACnB,WAAW;CAAM;MACxD;EACL,MAAM,SAAS,YAAY,MAAM,SAAS;EAK1C,MAAM,YAJS,SAAS,MAID,CAAC,CAAC,OAAO,CAAC,MAAM,QAAQ,KAAK,OAAO,CAAC;EAC5D,IAAI,aAAa,OAAO,SAAS,UAC/B,SAAS;GACP,MAAM,OAAO,OAAO,KAAK,UAAU,WAAW,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC;GAC5E,WAAW;EACb;OACK,IAAI,WAIT,SAAS;GAAE,MAAM,GAFH,OAAO,OAAO,KAAK,UAAU,GAAG,WAAW,OAAO,OAAO,EAAE,EAAE,CAEnD,EAAE,GAAG,iBAAiB,MAAM;GAAK,WAAW;EAAM;OAE1E,SAAS;GACP,MAAM,GAAG,mBAAmB,MAAM,OAAO,IAAI,iBAAiB,MAAM;GACpE,WAAW;EACb;CAEJ;CAEA,MAAM,UAAU,IAAI;CACpB,IAAI,YAAY,KAAA,GAAW,OAAO;CAElC,IAAI,QAAQ,SAAS,WAAW,QAAQ,UAAU,GAAG,OAAO;CAE5D,IAAI,UAAU,IAAI,MAAM,SAAS,KAAK,UAAU,IAAI,QAAQ,WAAW,GAAG;EACxE,IAAI,UAAU,SAAS,WAAW,GAAG,OAAO;GAAE,MAAM;GAAM,WAAW;EAAK;EAC1E,MAAM,aAAa,cAAc,SAAS,WAAW;EACrD,IAAI,eAAe,KAAA,GAAW,OAAO;GAAE,MAAM,GAAG,WAAW;GAAM,WAAW;EAAK;CACnF;CACA,OAAO;EAAE,MAAM,GAAG,OAAO,KAAK,GAAG,oBAAoB,OAAO;EAAK,WAAW,OAAO;CAAU;AAC/F;;;;AAaA,SAAgB,aAAa,KAAc,SAA0C;CACnF,MAAM,SAAS,UAAU,IAAI,YAAY,QAAQ;CACjD,MAAM,WAAW,UAAU,IAAI,OAAO,UAAU;CAChD,MAAM,SAAS,UAAU,IAAI,WAAW,QAAQ;CAKhD,MAAM,mBAAmB,CAAC,MAAM,IAAI,UAAU,KAAK,CAAC,MAAM,IAAI,SAAS,MAAM,UAAU;CACvF,MAAM,SAAS,UAAU;CACzB,MAAM,SAAS,UAAU;CAEzB,IAAI,UAAU,YAAY,QACxB,OAAO;EAAE,MAAM;EAAM,YAAY;EAAO,UAAU;CAAK;CAGzD,MAAM,YAAY,mBAAmB,IAAI,KAAK;CAE9C,IAAI,UAAU,CAAC,QAAQ;EACrB,MAAM,MAAM,uBAAuB,IAAI,WAAW;GAChD,QAAQ;GACR,UAAU,QAAQ;EACpB,CAAC;EAED,OAAO;GAAE,MADI,WAAW,MAAM,GAAG,UAAU,GAAG;GAC/B,YAAY;GAAM,UAAU;EAAM;CACnD;CAEA,IAAI,CAAC,UAAU,QAAQ;EACrB,MAAM,MAAM,wBAAwB,IAAI,UAAU;EAClD,IAAI,UAAU,OAAO;GAAE,MAAM,KAAK;GAAO,YAAY;GAAM,UAAU;EAAM;EAC3E,IAAI,IAAI,MAAM,SAAS,WAAW,IAAI,WAAW,SAAS,SACxD,OAAO;GAAE,MAAM,KAAK,YAAY;GAAO,YAAY;GAAM,UAAU;EAAM;EAE3E,OAAO;GAAE,MAAM,GAAG,UAAU,GAAG;GAAO,YAAY;GAAM,UAAU;EAAM;CAC1E;CAEA,IAAI,CAAC,UAAU,CAAC,QAAQ;EACtB,MAAM,MAAM,wBAAwB,IAAI,UAAU;EAClD,MAAM,MAAM,uBAAuB,IAAI,WAAW;GAChD,QAAQ;GACR,UAAU,QAAQ;EACpB,CAAC;EAMD,OAAO;GAAE,MAAM,GALF,WACT,KAAK,QACL,IAAI,MAAM,SAAS,WAAW,IAAI,WAAW,SAAS,UACpD,KAAK,YAAY,QACjB,GAAG,UAAU,GAAG,MACC,KAAK;GAAO,YAAY;GAAM,UAAU;EAAM;CACvE;CAGA,OAAO;EAAE,MAAM,GAAG,UAAU;EAAM,YAAY;EAAO,UAAU;CAAM;AACvE;;;;AAKA,SAAgB,QAAQ,KAAc,SAAiC;CACrE,MAAM,OAAO,aAAa,KAAK,OAAO;CACtC,MAAM,OAAO,aAAa,KAAK,OAAO;CACtC,IAAI,KAAK,YAAY,KAAK,WAAW,OAAO,KAAK;CACjD,OAAO,GAAG,KAAK,OAAO,KAAK,aAAa,MAAM,KAAK,KAAK;AAC1D;;;AC1JA,SAAS,QAAQ,SAAyC;CACxD,OAAO;EACL,OAAO,QAAQ,SAAS;EACxB,MAAM,QAAQ,QAAQ;EACtB,kBAAkB,QAAQ,oBAAoB;CAChD;AACF;AAEA,SAAS,cAAc,SAAwC;CAC7D,OAAO,QAAQ,YAAY,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;AACzD;;;;;;;;;;;;;;;AAgBA,SAAgB,QAAQ,YAAoB,UAA0B,CAAC,GAAW;CAChF,MAAM,SAAS,gBAAgB,YAAY,cAAc,OAAO,CAAC;CACjE,MAAM,WAAW,gBAAgB,QAAQ,EAAE;CAC3C,MAAM,OAAO,QAAQ,SAAS,OAAO,KAAK,UAAU,SAAS,GAAG,QAAQ,OAAO,CAAC;CAChF,OAAO,QAAQ,iBAAiB,OAAO,GAAG,KAAK,GAAG,SAAS,KAAK;AAClE;AAEA,SAAS,OAAO,KAAyC;CACvD,IAAI,aAAa,GAAG,KAAK,IAAI,SAAS,cAAc,OAAO;CAC3D,QAAQ,IAAI,MAAZ;EACE,KAAK,OACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,QACH,OAAO;;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,aAAa,KAAa,KAAe,MAAiB,MAAgC;CACjG,OAAO;EACL;EACA,MAAM,OAAO,GAAG;EAChB,QAAQ,aAAa,GAAG,IAAI,CAAC,IAAI,YAAY,KAAK,IAAI;EACtD;CACF;AACF;;;;;;;;;;AAWA,SAAgB,gBAAgB,YAAoB,UAA0B,CAAC,GAAgB;CAC7F,MAAM,SAAS,gBAAgB,YAAY,cAAc,OAAO,CAAC;CACjE,MAAM,iBAAiB,QAAQ,OAAO;CACtC,MAAM,WAAW,gBAAgB,QAAQ,EAAE;CAC3C,MAAM,MAAM,SAAS,OAAO,KAAK,UAAU,SAAS;CAEpD,MAAM,aAAa,iBAAiB,OAAO,GAAG;CAC9C,MAAM,YAAY,QAAQ,OAAO,MAAM,aAAa,iBAAiB,GAAG;CAGxE,MAAM,OAAO,OAAgC,QAAkB,UAC7D,WAAW,QAAS,OAAO,IAAI,UAAU,YAAY,KAAK,IAAK,YAAY,KAAK;CAClF,MAAM,aAAa;EAAE,QAAQ;EAAO,UAAU,eAAe;CAAiB;CAE9E,MAAM,SAAgC;EACpC,QAAQ,aACN,IAAI,UAAU,OAAO,IAAI,QAAQ,IAAI,MAAM,GAC3C,IAAI,QACJ,aACA,oBAAoB,IAAI,MAAM,CAChC;EACA,MAAM,aACJ,IAAI,QAAQ,OAAO,IAAI,MAAM,IAAI,IAAI,GACrC,IAAI,MACJ,WACA,kBAAkB,IAAI,MAAM,cAAc,CAC5C;EACA,YAAY,aACV,IAAI,cAAc,OAAO,IAAI,YAAY,IAAI,UAAU,GACvD,IAAI,YACJ,UACA,wBAAwB,IAAI,UAAU,CACxC;EACA,OAAO,aACL,IAAI,SAAS,OAAO,IAAI,OAAO,IAAI,KAAK,GACxC,IAAI,OACJ,YACA,mBAAmB,IAAI,KAAK,CAC9B;EACA,WAAW,aACT,IAAI,aAAa,OAAO,IAAI,WAAW,IAAI,SAAS,GACpD,IAAI,WACJ,UACA,uBAAuB,IAAI,WAAW,UAAU,CAClD;CACF;CACA,IAAI,IAAI,YAAY,KAAA,GAClB,OAAO,SAAS,aACd,IAAI,WAAW,OAAO,IAAI,WAAW,IAAI,SAAS,IAAI,OAAO,GAC7D,IAAI,SACJ,aACA,oBAAoB,IAAI,OAAO,CACjC;CAGF,MAAM,WAAW,QAAQ,KAAK,cAAc;CAC5C,MAAM,OAAO,QAAQ,iBAAiB,OAAO,GAAG,SAAS,GAAG,SAAS,KAAK;CAC1E,MAAM,EAAE,aAAa,SAAS,YAAY,cAAc,OAAO,CAAC;CAEhE,OAAO;EACL;EACA,YAAY;EACZ,iBAAiB;EACjB,IAAI;EACJ;EACA,YAAY,OAAO;EACnB,OAAO;EACP,MAAM,KAAK,YAAY;GAAE,GAAG,cAAc,OAAO;GAAG,OAAO;EAAE,CAAC;CAChE;AACF;;;AC7KA,MAAa,MAA8B;CACzC,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;AACN;AAEA,MAAa,UAAoC;CAC/C,IAAI;EAAC;EAAG;EAAG;EAAG;EAAG;CAAC;CAClB,IAAI,CAAC,GAAG,CAAC;CACT,IAAI,CAAC,GAAG,CAAC;CACT,IAAI,CAAC,GAAG,CAAC;AACX;;;;;;;;AASA,MAAa,iBAAyC,EACpD,IACE,gEAEJ;AASA,MAAa,cAAoD;CAC/D,IAAI;EAAE,SAAS;EAAG,OAAO,CAAC,GAAG,CAAC;CAAE;CAChC,GAAG;EAAE,SAAS;EAAG,OAAO,CAAC,GAAG,EAAE;CAAE;CAChC,IAAI;EAAE,SAAS;EAAM,OAAO,CAAC,GAAG,EAAE;CAAE;CACpC,GAAG;EAAE,SAAS;EAAI,OAAO,CAAC,IAAI,EAAE;CAAE;CAClC,IAAI;EAAE,SAAS;EAAI,OAAO,CAAC,IAAI,EAAE;CAAE;CACnC,IAAI;EAAE,SAAS;EAAM,OAAO,CAAC,IAAI,EAAE;CAAE;CACrC,IAAI;EAAE,SAAS;EAAI,OAAO,CAAC,IAAI,EAAE;CAAE;CACnC,GAAG;EAAE,SAAS;EAAI,OAAO,CAAC,IAAI,EAAE;CAAE;CAClC,GAAG;EAAE,SAAS;EAAI,OAAO,CAAC,IAAI,EAAE;CAAE;CAClC,IAAI;EAAE,SAAS;EAAG,OAAO,CAAC,GAAG,CAAC;CAAE;CAChC,IAAI;EAAE,SAAS;EAAG,OAAO,CAAC,GAAG,CAAC;CAAE;AAClC;AAIA,MAAa,OAAiC;CAC5C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,MAAa,cAA4C;CAAE,IAAI;CAAK,IAAI;AAAE;AAE1E,MAAa,MAA8B;CACzC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;AChDA,MAAM,MAAgB,EAAE,MAAM,MAAM;AAEpC,MAAM,cAAwC;CAC5C,QAAQ;CACR,MAAM;CACN,KAAK;CACL,MAAM;CACN,OAAO;CACP,MAAM;AACR;AAEA,MAAM,kBAAgD;CACpD,QAAQ;CACR,MAAM;CACN,KAAK;CACL,MAAM;CACN,OAAO;AACT;;AAMA,MAAM,gBAAyD;CAC7D,QAAQ;CACR,KAAK;CACL,OAAO;AACT;AAgBA,SAAS,YAAuB;CAC9B,OAAO;EAAE,OAAO,CAAC;EAAG,cAAc;EAAO,UAAU;CAAM;AAC3D;AAEA,SAAS,UAAU,MAAiB,OAAqB;CACvD,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,SAAS;CAC5C,IAAI,KAAK,gBAAgB,SAAS,KAAA,GAAW;EAC3C,KAAK,KAAK;EACV,KAAK,eAAe;EACpB;CACF;CACA,KAAK,MAAM,KAAK;EAAE,MAAM;EAAO,IAAI;CAAM,CAAC;AAC5C;;AAGA,SAAS,YAAY,QAA4B;CAC/C,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CACxD,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,WAAW,GAAG,OAAO;EAAE,MAAM;EAAS,OAAO;CAAM;CAE9D,MAAM,QAAoB,CAAC;CAC3B,IAAI,OAAO;CACX,IAAI,WAAW;CACf,MAAM,cAAc;EAClB,IAAI,WAAW,QAAQ,GAAG,MAAM,KAAK;GAAE,MAAM;GAAS;GAAM,IAAI;EAAS,CAAC;OACrE,KAAK,IAAI,QAAQ,MAAM,SAAS,UAAU,SAAS,MAAM,KAAK;GAAE,MAAM;GAAS;EAAM,CAAC;CAC7F;CACA,KAAK,MAAM,SAAS,OAAO,MAAM,CAAC,GAAG;EACnC,IAAI,UAAU,WAAW,GAAG;GAC1B,WAAW;GACX;EACF;EACA,MAAM;EACN,OAAO;EACP,WAAW;CACb;CACA,MAAM;CACN,MAAM,OAAO,MAAM;;CAEnB,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,OAAO,MAAM,WAAW,IAAI,OAAO;EAAE,MAAM;EAAQ;CAAM;AAC3D;;;;;;AAOA,SAAS,WAAW,OAAyB;CAC3C,IAAI,MAAM,OAAO,SAAS,KAAK,SAAS,KAAK,EAAE,GAC7C,OAAO,YAAY,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC;CAEnD,MAAM,QAAQ,MAAM,KAAe,SACjC,KAAK,SAAS,KAAK,KACf;EAAE,MAAM;EAAS,OAAO,KAAK;CAAK,IAClC;EAAE,MAAM;EAAS,MAAM,KAAK;EAAM,IAAI,KAAK;CAAG,CACpD;CACA,MAAM,OAAO,MAAM;;CAEnB,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,OAAO,MAAM,WAAW,IAAI,OAAO;EAAE,MAAM;EAAQ;CAAM;AAC3D;AAEA,SAAS,UAAU,MAA2B;CAC5C,OAAO,WAAW,KAAK,KAAK;AAC9B;;;;;AAMA,SAAS,YAAY,MAAiB,MAAkC;CACtE,MAAM,OAAO,KAAK,MAAM;CACxB,IAAI,SAAS,KAAA,KAAa,KAAK,MAAM,WAAW,GAAG,OAAO;CAC1D,IAAI,CAAC,KAAK,gBAAgB,KAAK,SAAS,KAAK,IAAI,OAAO;CACxD,KAAK,WAAW;CAChB,OAAO;EAAE,MAAM;EAAS,MAAM,KAAK;EAAM,IAAI,KAAK,eAAe,KAAK,MAAM,KAAK;CAAG;AACtF;AAuBA,SAAS,SAAS,MAAgB,MAAsB;CACtD,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,SAAS;CAC5C,IAAI,KAAK,gBAAgB,SAAS,KAAA,GAAW;EAC3C,KAAK,KAAK;EACV,KAAK,eAAe;EACpB;CACF;CACA,KAAK,MAAM,KAAK;EAAE,MAAM;EAAM,IAAI;CAAK,CAAC;AAC1C;;AAcA,SAAS,QAAQ,MAAuB,MAAc,MAA2B;CAC/E,IAAI,SAAS,MAAM,OAAO;EAAE,MAAM;EAAQ,MAAM;EAAK;CAAK;CAC1D,IAAI,KAAK,SAAS,WAAW,KAAK,SAAS,KAAK,OAAO,KAAK,OAAO,KAAK,KACtE,OAAO;EAAE,MAAM;EAAQ,MAAM;EAAK;CAAK;CAEzC,OAAO;EAAE,MAAM;EAAQ;EAAM;CAAK;AACpC;;;;AAKA,SAAS,WAAW,MAAc,CAAC,KAAK,OAA0C;CAChF,IAAI,QAAQ,OAAO,QAAQ,MAAM,OAAO;CACxC,OAAO,KAAK,KAAK,MAAM,OAAO,MAAM,KAAK,OAAO,OAAO,MAAM,EAAE;AACjE;;;;;;;;;;;;;;AAeA,SAAS,SAAS,MAAqB,MAA6C;CAClF,MAAM,QAAQ,YAAY,KAAK,CAAC;CAChC,MAAM,UAAU;EAAE;EAAM,KAAK,WAAW,MAAM,KAAK;CAAE;CACrD,IAAI,OAAO,IAAI,OAAO;CACtB,MAAM,WAAW,OAAO,MAAM;CAC9B,MAAM,cAAc;EAAE,MAAM;EAAS,KAAK,WAAW,SAAS,KAAK;CAAE;CACrE,OAAO,YAAY,MAAM,QAAQ,MAAM,cAAc;AACvD;AAEA,SAAS,eAAe,MAAc,IAAqC;CACzE,MAAM,aAAsC,CAAC;CAC7C,KAAK,IAAI,OAAO,MAAM,QAAQ,IAAI,QAChC,WAAW,KAAK;EAAE,OAAO;EAAM,OAAO,WAAW,MAAM;GAAE,OAAO;GAAU,MAAM;EAAM,CAAC;CAAE,CAAC;CAE5F,OAAO;AACT;AAwBA,SAAS,QAAQ,QAA4B;CAC3C,MAAM,QAAmB;EACvB,OAAO;GAAE,OAAO,CAAC;GAAG,cAAc;EAAM;EACxC,UAAU;EACV,OAAO;GAAE,QAAQ,UAAU;GAAG,KAAK,UAAU;GAAG,KAAK,UAAU;GAAG,OAAO,UAAU;EAAE;EACrF,WAAW,CAAC;EACZ,oBAAoB,CAAC;EACrB,YAAY,CAAC;EACb,MAAM,CAAC;EACP,YAAY;EACZ,OAAO,CAAC;EACR,SAAS;EACT,YAAY;EACZ,UAAU,CAAC;EACX,cAAc,CAAC;EACf,aAAa,CAAC;CAChB;CAEA,IAAI,cAAoC;;CAExC,IAAI,WAAiC;CACrC,IAAI,aAA4B;;CAEhC,IAAI,OAAiC;;;;;CAMrC,MAAM,WAAW,MAAgB,SAA+B;EAC9D,IAAI,CAAC,MAAM,MAAM,cAAc,WAAW;EAC1C,SAAS,MAAM,OAAO,IAAI;CAC5B;;CAGA,MAAM,kBAAkB;EACtB,IAAI,gBAAgB,MAAM;GACxB,QAAQ;IAAE,MAAM;IAAQ,MAAM;GAAY,GAAG,WAAW;GACxD,cAAc;EAChB;CACF;;CAGA,MAAM,aAAa,MAAgB,WAA+B;EAChE,KAAK,MAAM,SAAS,QAAQ,UAAU,MAAM,MAAM,OAAO,KAAK;EAC9D,MAAM,WAAW,QAAQ;EACzB,OAAO;CACT;CAEA,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,MAAM,SAAS,aAAa,MAAM,SAAS,OAAO,MAAM,cAAc;EAE1E,QAAQ,MAAM,MAAd;GACE,KAAK;GACL,KAAK;IACH,UAAU;IACV,cAAc,MAAM;IACpB,OAAO;IACP;GAEF,KAAK,QAAQ;IACX,MAAM,OAAO,MAAM;IACnB,IAAI,OAAO,KAAK;IAGhB,MAAM,YAAY,MAAM,MAAM,eAAe,WAAW;IACxD,MAAM,OAAO,eAAe;IAC5B,IAAI,SAAS,MAAM;KACjB,MAAM,UAAU,SAAS,MAAM,IAAI;KACnC,OAAO,QAAQ;KAGf,IAAI,QAAQ,MAAM,KAAK,gBAAgB,MAAM;MAG3C,MAAM,CAAC,KAAK,QAAQ,YAAY,YAAY,CAAC;MAC7C,MAAM,SAAS,KACb,IAAI,YAAY,OAAO,IAAI,KAAK,KAAK,OAAO,KAAK,SACnD;MACA,MAAM,aAAa,KAAK;OACtB,QAAQ;OACR,QAAQ,KAAK,IAAI,IAAK,QAAQ,MAAM,EAAG;MACzC,CAAC;KACH;IACF;IACA,QAAQ;KAAE,MAAM;KAAQ;KAAM,QAAQ,KAAK;IAAO,GAAG,WAAW;IAChE,cAAc;IACd,OAAO;IACP;GACF;GAEA,KAAK;IACH,UAAU;IACV,OAAO,UAAU,UAAU,CAAC,MAAM,KAAe,CAAC;IAClD;GAEF,KAAK,YAAY;IACf,UAAU;IACV,MAAM,WAAW,MAAM;IACvB,IAAI,MAAM,UAAU,SAAS,UAAU,KAAA,GACrC,MAAM,mBAAmB,KAAK,SAAS,IAAI;IAE7C,MAAM,UAAU,SAAS,QAAQ,SAAS;IAC1C,MAAM,OAAO,cAAc,SAAS;IACpC,IAAI,SAAS,KAAA,GAAW,MAAM,WAAW,QAAQ;IAEjD,IAAI,SAAS,SAAS,QAAQ,MAAM,MAAM,KAAK,MAAM;IAErD,IAAI,SAAS,SAAS,SAAS,MAAM,MAAM,KAAK,OAAO;IACvD;GACF;GAEA,KAAK;IACH,IAAI,SAAS,QAAQ;KAEnB,UAAU;KACV,IAAI,MAAM,MAAM,MAAM,SAAS,GAAG,MAAM,MAAM,eAAe;IAC/D,OAAO,IAAI,SAAS,QAAQ,MAAM,MAAM,KAAK,CAAC,MAAM,SAAS,GAC3D,MAAM,MAAM,KAAK,CAAC,eAAe;IAEnC;GAEF,KAAK,YACH;GAEF,KAAK;IACH,UAAU;IACV,aAAa,MAAM;IACnB;GAEF,KAAK,OAAO;IACV,UAAU;IACV,MAAM,UAAU,MAAM;IACtB,IAAI,eAAe,MAAM;KACvB,MAAM,KAAK,KAAK;MAAE;MAAS,KAAK;KAAW,CAAC;KAC5C,aAAa;IACf,OACE,OAAO,UAAU,OAAO,CAAC,OAAO,CAAC;IAEnC;GACF;GAEA,KAAK,WAAW;IACd,UAAU;IAEV,MAAM,SAAS,eAAe,MAAM;IACpC,IAAI,WAAW,KAAA,GAAW,MAAM,YAAY,KAAK,MAAM;IACvD,OAAO,UAAU,OAAO,MAAM,KAAiB;IAC/C;GACF;GAEA,KAAK;IACH,UAAU;IACV,OAAO,UAAU,OAAO,CAAC,MAAM,KAAe,CAAC;IAC/C;GAEF,KAAK,eAAe;IAClB,UAAU;IACV,MAAM,QAAQ,MAAM;IACpB,IAAI,UAAU,KAAK,MAAM,aAAa;SACjC,OAAO,UAAU,OAAO,CAAC,KAAK,CAAC;IACpC;GACF;GAEA,KAAK;IACH,UAAU;IACV,OAAO,UAAU,SAAS,CAAC,MAAM,KAAe,CAAC;IACjD;GAEF,KAAK;IACH,UAAU;IACV,MAAM,MAAM,KAAK,MAAM,KAAiB;IACxC;GAEF,KAAK;IAEH,UAAU;IACV;GAEF,KAAK;IACH,MAAM,WAAW;IACjB;GAEF,SACE,IAAI,MAAM,SAAS,WAAW,MAAM,WAAW;EAEnD;CACF;CAEA,UAAU;CACV,OAAO;AACT;;;;AAKA,SAAgB,KAAK,QAAiB,UAAwB,CAAC,GAAU;CACvE,MAAM,YAAY,QAAQ,eAAe;CACzC,MAAM,cACJ,OAAO,UAAU,SAAS,KAAK,aAAa,KAAK,aAAa,KAAK,YAAY;CACjF,MAAM,QAAQ,QAAQ,MAAM;CAE5B,MAAM,QAAe;EACnB,QAAQ;EACR,MAAM;EACN,KAAK;EACL,OAAO;EACP,KAAK;EACL,4BAAY,IAAI,IAAmB;EACnC,WAAW,CAAC;EACZ,aAAa,CAAC;EACd,OAAO,CAAC,GAAG,MAAM,QAAQ;EACzB,OAAO,MAAM,eAAe;CAC9B;CACA,IAAI,MAAM,OAAO,OAAO;CAExB,MAAM,YAAY,QAAgB,WAAmB;EACnD,MAAM,UAAU,KAAK;GAAE;GAAQ;EAAO,CAAC;CACzC;;CAGA,MAAM,gBAAgB,UAAkB;EACtC,MAAM,MAAM,KAAK,IAAI,MAAM,8BAA8B;EACzD,SAAS,iBAAiB,EAAG;CAC/B;CAGA,KAAK,MAAM,WAAW,MAAM,cAAc,MAAM,UAAU,KAAK,OAAO;CAEtE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,aAAa,gBAAgB,KAAK;CAG/E,KAAK,MAAM,QAAQ,MAAM,aAAa;EACpC,MAAM,MAAM,KAAK,IAAI;EACrB,SAAS,YAAY,EAAG;CAC1B;;CAGA,MAAM,eAAe,SAAgC;EACnD,MAAM,OAAO,YAAY;EACzB,MAAM,WAAW,QAAQ,YAAY;EAErC,IAAI,KAAK,MAAM,OAAO,KAAK,MAAM,MAAM,aAAa,KAAA,GAAW;GAC7D,MAAM,YAAY,KAAK;IACrB,OAAO;IACP,UAAU,IAAI,KAAK;IACnB,YAAY,eAAe,KAAK,MAAM,IAAI,KAAK,MAAM,EAAE;GACzD,CAAC;GACD,SAAS,aAAa,EAAG;EAC3B;EACA,OAAO,YAAY,KAAK,WAAW;CACrC;CAIA,MAAM,eAAe,SACnB,KAAK,SAAS,SACV;EAAE,MAAM,KAAK;EAAM,QAAQ,KAAK;CAAO,IACvC;EAAE,MAAM,YAAY,KAAK,IAAI;EAAG,QAAQ;CAAE;CAChD,MAAM,QAAQ,MAAM,MAAM,MAAM,KAAmB,UAAU;EAC3D,MAAM,YAAY,KAAK,IAAI;EAC3B,IAAI,KAAK,OAAO,OAAO,OAAO,YAAY,KAAK,EAAE;CACnD,EAAE;CAIF,MAAM,UAAU,MAAM,MAAM;CAC5B,MAAM,aAAa,MAAM,UAAU;CACnC,MAAM,WAAW,MAAM,UAAU;CACjC,MAAM,UAAU,MAAM,SAAS;CAC/B,MAAM,WAAW,MAAM,MAAM,SAAS,KAAK,OAAO,IAAI;CAGtD,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,KAAK,MAAM,CAAC,CAAC;;CAGtE,MAAM,iBACJ,WAAW,MAAM,KAAK,UAAU;EAAE,MAAM,KAAK,KAAK;EAAM,KAAK,KAAK,MAAM,KAAK,KAAA,CAAM;CAAK,EAAE,CAAC;;;;;CAM7F,MAAM,eAAe,SAA2B;EAC9C,IAAI,CAAC,UAAU,OAAO;GAAE,MAAM;GAAQ,MAAM;GAAK;EAAK;EACtD,MAAM,QAAQ,MAAM,KAAe,SACjC,KAAK,OAAO,OACR;GAAE,MAAM;GAAS,OAAO,KAAK,KAAK;EAAK,IACvC,QAAQ;GAAE,MAAM;GAAS,MAAM,KAAK,KAAK;GAAM,IAAI,KAAK,GAAG;EAAK,GAAG,MAAM,SAAS,CACxF;EACA,MAAM,OAAO,MAAM;;EAEnB,IAAI,SAAS,KAAA,GAAW,OAAO;GAAE,MAAM;GAAQ,MAAM;GAAK;EAAK;EAC/D,OAAO,MAAM,WAAW,IAAI,OAAO;GAAE,MAAM;GAAQ;EAAM;CAC3D;;CAGA,MAAM,uBAAuB;EAC3B,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,KAAK,KAAK;GAChB,IAAI,OAAO,MAAM;GACjB,MAAM,MAAM,KACV,IAAI,GAAG,KAAK,QAAQ,GAAG,KAAK,OAAO,KAAK,KAAK,KAAK,GAAG,GAAG,KAAK,WACxD,GAAG,KAAK,cAAc,KAAK,KAAK,KAAK,GAAG,GAAG,OAAO,EAAE,WAC3D;GACA,SAAS,cAAc,EAAG;EAC5B;CACF;CAEA,IAAI,MAAM,MAAM,SAAS,QAAQ,GAAG;EAClC,MAAM,SAAS;EACf,IAAI,aAAa,KAAA,GAEf,MAAM,OAAO,YAAY,QAAQ;OAC5B,IAAI,SAET,MAAM,OAAO,SAAS;EAExB,eAAe;CACjB,OAAO,IAAI,eAAe,KAAA,KAAa,aAAa,KAAA,GAAW;EAC7D,IAAI,eAAe,KAAA,GAEjB,MAAM,SAAS,QAAQ,YAAY,SAAS,WAAW,GAAG,YAAY,WAAW;EAEnF,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,OAAO,YAAY,QAAQ;GACjC,IAAI,eAAe,KAAA,GAAW;IAC5B,MAAM,SACJ,QAAQ,MAAM,SAAS,IACnB,UAAU,OAAO,IACjB;KAAE,MAAM;KAAS,OAAO,YAAY,MAAM;IAAE;IAClD,QAAQ,WAAW;GACrB;EACF,OAAO,IAAI,UACT,MAAM,OAAO,SAAS;EAGxB,eAAe;EACf,IAAI,CAAC,YAAY,SAAS;GAExB,IAAI,eAAe,KAAA,GAAW,MAAM,OAAO,SAAS;GAIpD,IAAI,EADY,MAAM,YAAY,eAAe,KAAA,KAAa,aAAa,KAAA,IAC7D;IACZ,MAAM,YAAY,KAAK;KACrB,OAAO;KACP,UAAU;KACV,YAAY,CACV;MAAE,OAAO;MAAY,OAAO;KAAc,GAC1C;MAAE,OAAO;MAAM,OAAO;KAAgB,CACxC;IACF,CAAC;IACD,SAAS,YAAY,EAAG;GAC1B;EACF;EAEA,IAAI,QAAQ,MAAM,SAAS,KAAK,CAAC,QAAQ,UAAU;GACjD,aAAa,gBAAgB,MAAM;GACnC,IAAI,MAAM,WAAW,WAAW,UAAU,MAAM,SAAS,UAAU,OAAO;EAC5E;CACF,OAAO,IAAI,SAAS;EAGlB,MAAM,iBAAiB,QAAQ,MAAM,SAAS;EAE9C,IAAI,kBAAkB,YAAY,MAAM,WAAW,WAAW,CAAC,GAC7D,aAAa,gBAAgB,MAAM;EAGrC,MAAM,OAAO,SAAS;EACtB,eAAe;EAEf,MAAM,OAAO,YAAY;EACzB,IAAI,gBACF,MAAM,SAAS,UAAU,OAAO;OAC3B,IAAI,YAAY,WAAW,KAAK,SAAS,KAAA,GAC9C,MAAM,SAAS;GAAE,MAAM;GAAS,OAAO;EAAK;OACvC;GACL,MAAM,SAAS,YAAY,WAAW;GACtC,MAAM,MAAM,KAAK,sCAAsC;GACvD,SAAS,gBAAgB,EAAG;EAC9B;CACF,OAAO,IAAI,MAAM,MAAM,SAAS,MAAM,GAAG;EACvC,MAAM,OAAO;EACb,MAAM,SAAS,QAAQ,MAAM,SAAS,IAAI,UAAU,OAAO,IAAI;GAAE,MAAM;GAAS,OAAO;EAAE;CAC3F,OAAO,IAAI,QAAQ,MAAM,SAAS,GAAG;EACnC,MAAM,OAAO;EACb,MAAM,SAAS,UAAU,OAAO;CAClC,OAAO;EACL,MAAM,OAAO;GAAE,MAAM;GAAS,OAAO;EAAY;EACjD,MAAM,SAAS;GAAE,MAAM;GAAS,OAAO;EAAE;EACzC,MAAM,YAAY,MAAM,MAAM,OAAO,KAAA,IAAY,KAAA,IAAY,YAAY,MAAM,MAAM;EACrF,MAAM,YAAY,KAAK;GACrB,OAAO;GACP,UAAU,cAAc,KAAA,IAAY,eAAe,IAAI,UAAU;GACjE,YAAY,eAAe,GAAG,EAAE;EAClC,CAAC;EACD,SAAS,eAAe,EAAG;CAC7B;CAIA,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,SAAS,MAAM,MAAM;CAC3B,MAAM,UAAU,MAAM,UAAU;CAChC,MAAM,YAAY,MAAM,UAAU;CAElC,IAAI,MAAM,KAAK,SAAS,GAAG;EACzB,MAAM,QAAQ,MAAM,KAAK,KAAe,WAAW;GACjD,MAAM;GACN,SAAS,MAAM;GACf,KAAK,MAAM;EACb,EAAE;EACF,MAAM,QAAQ,MAAM;;EAEpB,MAAM,MAAM,MAAM,WAAW,KAAK,UAAU,KAAA,IAAY,QAAQ;GAAE,MAAM;GAAQ;EAAM;EACtF,KAAK,MAAM,SAAS,MAAM,MAAM,MAAM,WAAW,IAAI,MAAM,QAAQ,KAAK,MAAM,GAAG;CACnF,OAAO,IAAI,KAAK,MAAM,SAAS,GAC7B,MAAM,MAAM,UAAU,IAAI;CAG5B,IAAI,MAAM,eAAe,KAAK;EAC5B,MAAM,MAAM,EAAE,MAAM,OAAO;EAC3B,MAAM,WAAW,IAAI,GAAG;EACxB,IAAI,YAAY,KAAA,GAAW,aAAa,gBAAgB,GAAG;CAC7D,OAAO,IAAI,YAAY,KAAA,GAAW;EAEhC,MAAM,MAAM,QAAQ,YAAY,MAAM,QAAQ,GAAG,SAAS,QAAQ;EAClE,IAAI,KAAK,MAAM,SAAS,KAAK,CAAC,KAAK,UAAU;GAC3C,aAAa,gBAAgB,GAAG;GAChC,IAAI,MAAM,WAAW,QAAQ,UAAU,MAAM,MAAM,UAAU,IAAI;EACnE;CACF,OAAO,IAAI,KAAK,MAAM,SAAS,GAC7B,MAAM,MAAM,UAAU,IAAI;CAG5B,IAAI,cAAc,KAAA,GAAW;EAC3B,MAAM,QAAQ,QAAQ,YAAY,QAAQ,UAAU,GAAG,WAAW,UAAU;EAC5E,IAAI,OAAO,MAAM,SAAS,KAAK,CAAC,OAAO,UAAU;GAC/C,aAAa,gBAAgB,KAAK;GAClC,IAAI,MAAM,WAAW,UAAU,UAAU,MAAM,QAAQ,UAAU,MAAM;EACzE;CACF,OAAO,IAAI,OAAO,MAAM,SAAS,GAC/B,MAAM,QAAQ,UAAU,MAAM;CAGhC,MAAM,WAAW,MAAM,UAAU;CACjC,IAAI,aAAa,KAAA,GAAW;EAC1B,MAAM,MAAM,KACV,sBAAsB,SAAS,0BAEjC;EACA,SAAS,UAAU,EAAG;CACxB;CAIA,MAAM,eAAe,MAAM,IAAI,SAAS;CACxC,MAAM,eAAe,MAAM,IAAI,SAAS;CAExC,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,IAAI,SAAS,UAAU,gBAAgB,eAAe;GACpD,MAAM,MAAM,KACV,uCACF;GACA,SAAS,gBAAgB,EAAG;EAC9B;EACA,IAAI,SAAS,UAAU,CAAC,cAAc;GACpC,MAAM,MAAM;IAAE,MAAM;IAAS,OAAO;GAAE;GACtC,MAAM,YAAY,KAAK;IACrB,OAAO;IACP,UAAU;IACV,YAAY;KACV;MAAE,OAAO;MAAG,OAAO;KAAM;KACzB;MAAE,OAAO;MAAG,OAAO;KAAM;KACzB;MAAE,OAAO;MAAG,OAAO;KAAM;KACzB;MAAE,OAAO;MAAG,OAAO;KAAM;KACzB;MAAE,OAAO;MAAG,OAAO;KAAM;KACzB;MAAE,OAAO;MAAG,OAAO;KAAM;KACzB;MAAE,OAAO;MAAG,OAAO;KAAM;IAC3B;GACF,CAAC;GACD,SAAS,eAAe,EAAG;EAC7B;EAEA,IAAI,SAAS,WAAW,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,MAAM,SAAS,KAAK,GAAG;GACtF,MAAM,MAAM;IAAE,MAAM;IAAS,OAAO;GAAE;GACtC,MAAM,YAAY,KAAK;IACrB,OAAO;IACP,UAAU;IACV,YAAY;KACV;MAAE,OAAO;MAAG,OAAO;KAAK;KACxB;MAAE,OAAO;MAAI,OAAO;KAAM;KAC1B;MAAE,OAAO;MAAK,OAAO;KAAK;IAC5B;GACF,CAAC;GACD,SAAS,cAAc,EAAG;EAC5B;EACA,IAAI,SAAS,UAAU,MAAM,MAAM,SAAS,OAAO;GACjD,MAAM,QAAQ;IAAE,MAAM;IAAS,OAAO;GAAE;GACxC,IAAI,MAAM,IAAI,SAAS,OAAO,MAAM,MAAM;IAAE,MAAM;IAAS,OAAO;GAAE;GACpE,MAAM,YAAY,KAAK;IACrB,OAAO;IACP,UAAU;IACV,YAAY,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,WAAW;KACpD,OAAO,QAAQ;KACf,OAAO,GAAG,QAAQ,EAAE;IACtB,EAAE;GACJ,CAAC;GACD,SAAS,cAAc,EAAG;EAC5B;CACF;CAIA,IAAI,MAAM,IAAI,SAAS,SAAS,MAAM,IAAI,SAAS,OAAO;EACxD,MAAM,MAAM,KACV,qDACF;EACA,SAAS,aAAa,EAAG;CAC3B;CAEA,MAAM,eACJ,KAAK,MAAM,SAAS,KACpB,MAAM,KAAK,SAAS,KACpB,KAAK,MAAM,SAAS,KACpB,MAAM,eAAe,QACrB,OAAO,MAAM,SAAS;CACxB,MAAM,cAAc,OAAO,KAAK,MAAM,SAAS,CAAC,CAAC,SAAS;CAC1D,IAAI,MAAM,MAAM,WAAW,KAAK,CAAC,gBAAgB,CAAC,aAAa;EAC7D,MAAM,MAAM,KAAK,2BAA2B;EAC5C,SAAS,UAAU,EAAG;CACxB;CAEA,IAAI,MAAM,WAAW,OAAO,KAAK,QAAQ,oBAAoB,MAAM;EACjE,MAAM,OAAO,CAAC,GAAG,MAAM,UAAU,CAAC,CAAC,KAAK,MAAM;EAC9C,MAAM,MAAM,KACV,IAAI,KAAK,2DACX;EACA,SAAS,WAAW,EAAG;CACzB;CAEA,IAAI,MAAM,UAAU,GAClB,SAAS,WAAW,KAAK,IAAI,IAAK,MAAM,UAAU,EAAG,CAAC;CAGxD,OAAO;AACT;;AAGA,SAAgB,KAAK,OAAsB;CACzC,OAAO;EAAC,MAAM;EAAQ,MAAM;EAAM,MAAM;EAAK,MAAM;EAAO,MAAM;CAAG,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,KAAK,GAAG;AAChG;;;ACrzBA,MAAM,eAAuC;CAC3C,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,MAAM,YAAY;AAElB,SAAS,WAAW,KAAqB;CACvC,IAAI,CAAC,IAAI,SAAS,GAAG,GAAG;EACtB,IAAI,SAAS;EACb,KAAK,MAAM,QAAQ,KAAK;GACtB,MAAM,QAAQ,aAAa;;GAE3B,IAAI,UAAU,KAAA,GAAW,OAAO;GAChC,UAAU,OAAO,KAAK;EACxB;EACA,OAAO;CACT;CAEA,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,KACjB,IAAI,SAAS,KAAK;EAChB,UAAU,YAAY,IAAI,IAAI,WAAW;EACzC,UAAU;CACZ,OAAO;EACL,MAAM,QAAQ,aAAa;;EAE3B,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,UAAU;CACZ;CAEF,OAAO,OAAO,QAAQ,OAAO;AAC/B;;AAGA,SAAgB,cAAc,MAAsB;CAClD,OAAO,KAAK,QAAQ,YAAY,QAAQ,WAAW,GAAG,CAAC;AACzD;;AAGA,MAAM,gBAA0B;CAC9B;CACA;CACA;CACA;AACF;AAEA,SAAgB,UAAU,MAAsB;CAC9C,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,IAAI,UAAU;EACd,KAAK,MAAM,WAAW,eAAe;GACnC,MAAM,OAAO,OAAO,QAAQ,SAAS,EAAE;GACvC,IAAI,SAAS,UAAU,KAAK,SAAS,GAAG;IACtC,SAAS;IACT,UAAU;GACZ;EACF;EACA,IAAI,CAAC,SAAS;CAChB;CACA,OAAO;AACT;;;;AAKA,SAAgB,UAAU,MAAsB;CAC9C,OAAO,UAAU,cAAc,KAAK,UAAU,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;AACtE;;;AC7DA,SAAS,IAAI,MAAkC;CAC7C,OAAO,OAAO,QAAQ,GAAG;AAC3B;;AAGA,SAAS,QAAQ,OAAe,KAAa,KAAsB;CACjE,OAAO,OAAO,UAAU,KAAK,KAAK,SAAS,OAAO,SAAS;AAC7D;;;;;;;AAQA,MAAM,QAAgB;CACpB,CACE,0CACC,MAAM;EACL,MAAM,IAAI,IAAI,EAAE,EAAE;EAClB,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO;EAC/B,OAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAQ;GAAE;EAA0B;CAChF,CACF;CACA,CACE,yCACC,MAAM;EACL,MAAM,IAAI,IAAI,EAAE,EAAE;EAClB,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO;EAC/B,OAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAU;GAAE;EAA0B;CAClF,CACF;CACA,CACE,yCACC,MAAM;EACL,MAAM,IAAI,IAAI,EAAE,EAAE;EAClB,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO;EAC/B,OAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAO;GAAE;EAA0B;CAC/E,CACF;CACA,CAEE,kDACC,MAAM;EACL,MAAM,IAAI,IAAI,EAAE,EAAE;EAClB,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO;EAC/B,OAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAS;GAAE;EAA0B;CACjF,CACF;CACA,CACE,2CACC,MAAM;EACL,MAAM,IAAI,IAAI,EAAE,EAAE;EAClB,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO;EAC/B,OAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAQ;GAAE;EAA0B;CAChF,CACF;CACA,CACE,uBACC,MAAM;EACL,MAAM,OAAO,IAAI,EAAE,EAAE;EACrB,MAAM,SAAS,IAAI,EAAE,EAAE;EACvB,IAAI,CAAC,QAAQ,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,QAAQ,GAAG,EAAE,GAAG,OAAO;EAC7D,OAAO;GAAE,MAAM;GAAQ,OAAO;IAAE;IAAM;GAAO;EAAsB;CACrE,CACF;CACA,CACE,+BACC,MAAM;EACL,MAAM,OAAO,IAAI,EAAE,EAAE;EACrB,MAAM,SAAS,EAAE,OAAO,MAAM,KAAK,IAAI,EAAE,EAAE;EAC3C,IAAI,CAAC,QAAQ,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,QAAQ,GAAG,EAAE,GAAG,OAAO;EAC7D,OAAO;GAAE,MAAM;GAAQ,OAAO;IAAE;IAAM;GAAO;EAAsB;CACrE,CACF;CACA,CACE,gBACC,MAAM;EACL,MAAM,QAAQ,IAAI,EAAE,EAAE;EACtB,OAAO,QAAQ,OAAO,GAAG,EAAE,IAAI;GAAE,MAAM;GAAU;EAAM,IAAI;CAC7D,CACF;CACA,CACE,0BACC,MAAM;EACL,MAAM,MAAM,IAAI,EAAE,MAAM;EACxB,OAAO,QAAQ,KAAA,IAAY,OAAO;GAAE,MAAM;GAAO,OAAO;EAAI;CAC9D,CACF;CACA,CACE,gBACC,MAAM;EACL,MAAM,QAAQ,IAAI,EAAE,EAAE;EACtB,OAAO,QAAQ,OAAO,GAAG,EAAE,IAAI;GAAE,MAAM;GAAS;EAAM,IAAI;CAC5D,CACF;CACA,CACE,gBACC,MAAM;EACL,MAAM,QAAQ,IAAI,EAAE,EAAE;EACtB,OAAO,QAAQ,OAAO,GAAG,EAAE,IAAI;GAAE,MAAM;GAAO;EAAM,IAAI;CAC1D,CACF;CACA,CACE,mBACC,MAAM;EACL,MAAM,SAAS,QAAQ,EAAE,MAAM;EAC/B,OAAO,WAAW,KAAA,IAAY,OAAO;GAAE,MAAM;GAAW,OAAO,CAAC,GAAG,MAAM;EAAE;CAC7E,CACF;CACA,CACE,wBACC,MAAM;EACL,MAAM,QAAQ,IAAI,GAAG,EAAE,GAAG;EAC1B,OAAO,UAAU,KAAA,IAAY,OAAO;GAAE,MAAM;GAAO;EAAM;CAC3D,CACF;CACA,CACE,eACC,MAAM;EACL,MAAM,QAAQ,YAAY,EAAE,MAAM;EAClC,OAAO,UAAU,KAAA,IAAY,OAAO;GAAE,MAAM;GAAe;EAAM;CACnE,CACF;CACA,CACE,oCACC,MAAM;EACL,MAAM,OAAO,EAAE;EACf,IAAI,SAAS,QAAQ,SAAS,MAAM,OAAO;GAAE,MAAM;GAAQ,OAAO;EAAK;EACvE,OAAO;GAAE,MAAM;GAAe,OAAO;EAAK;CAC5C,CACF;CACA,CACE,oBACC,MAAM;EACL,MAAM,OAA6B,KAAK,IAAI,EAAE;EAC9C,OAAO,SAAS,KAAA,IAAY,OAAO;GAAE,MAAM;GAAQ,OAAO;EAAK;CACjE,CACF;CACA,CAGE,uCACO;EAAE,MAAM;EAAQ,OAAO;CAAyB,EACzD;CACA,CAAC,mBAAmB,EAAE,MAAM,aAAa,EAAE;CAC3C,CAAC,mBAAmB,EAAE,MAAM,WAAW,EAAE;CACzC,CAAC,0BAA0B,EAAE,MAAM,MAAM,EAAE;CAG3C,CAAC,aAAa,EAAE,MAAM,YAAY,EAAE;CACpC,CAAC,6BAA6B,EAAE,MAAM,MAAM,EAAE;AAChD;;;;AAKA,SAAgB,SAAS,MAAuB;CAC9C,MAAM,SAAkB,CAAC;CACzB,IAAI,WAAW;CAEf,OAAO,WAAW,KAAK,QAAQ;EAC7B,MAAM,OAAO,KAAK,MAAM,QAAQ;EAChC,IAAI,UAAU;EAEd,KAAK,MAAM,CAAC,SAAS,UAAU,OAAO;GACpC,MAAM,QAAQ,QAAQ,KAAK,IAAI;GAC/B,IAAI,UAAU,QAAQ,MAAM,OAAO,IAAI;GACvC,MAAM,QAAQ,MAAM,KAAK;;GAEzB,IAAI,UAAU,MAAM;GACpB,OAAO,KAAK;IAAE,GAAG;IAAO,KAAK,MAAM;IAAI;GAAS,CAAC;GACjD,YAAY,MAAM,EAAE,CAAC;GACrB,UAAU;GACV;EACF;EAEA,IAAI,CAAC,SAAS;GACZ,OAAO,KAAK;IAAE,MAAM;IAAW,KAAK,KAAK,aAAa;IAAI;GAAS,CAAC;GACpE,YAAY;EACd;CACF;CAEA,OAAO;AACT;;;AClMA,SAAS,OAAO,OAAuB;CACrC,OAAO,KAAK,MAAM,QAAQ,GAAG,IAAI;AACnC;;;;;;;;;;;;;;;AAgBA,SAAgB,MAAM,MAAc,UAAwB,CAAC,GAAgB;CAC3E,MAAM,WAAW,gBAAgB,QAAQ,EAAE;CAE3C,MAAM,SAAS,SAAS,UAAU,IAAI,CAAC;CACvC,MAAM,QAAQ,KAAK,QAAQ,OAAO;CAElC,IAAI,MAAM,OAAO;EACf,MAAM,SAAsB;GAC1B,YAAY;GACZ,iBAAiB;GACjB,IAAI;GACJ,YAAY;GACZ,aAAa,CAAC;GACd,OAAO,CAAC,iBAAiB;GACzB;EACF;EACA,IAAI,QAAQ,WAAW,MACrB,MAAM,IAAI,oBAAoB,mBAAmB,MAAM;EAEzD,OAAO;CACT;CAEA,MAAM,QAAQ,MAAM,UAAU,QAAQ,KAAK,YAAY,MAAM,QAAQ,QAAQ,CAAC;CAC9E,MAAM,QAAQ,KAAK,KAAK;CACxB,MAAM,SAAsB;EAC1B,YAAY,gBAAgB,OAAO,UAAU,UAAU;EACvD,iBAAiB;EACjB,IAAI;EACJ,YAAY,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC;EACzC,aAAa,MAAM;EACnB,OAAO,MAAM;EACb;CACF;CAEA,IAAI,QAAQ,WAAW,QAAQ,OAAO,YAAY,SAAS,GAAG;EAC5D,MAAM,QAAQ,OAAO,YAAY;EACjC,MAAM,IAAI,oBACR,YAAY,OAAO,YAAY,gBAC/B,MACF;CACF;CAEA,OAAO;AACT"}