{"version":3,"file":"datetime_extended.cjs","names":[],"sources":["../../../src/batteries/tools/datetime_extended/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.\n *\n * @module @nhtio/adk/batteries/tools/datetime_extended\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport * as chrono from 'chrono-node'\nimport { Tool } from '@nhtio/adk/common'\nimport { DateTime, IANAZone } from 'luxon'\nimport { validator } from '@nhtio/validation'\n\nfunction resolveZone(timezone: string | undefined): { zone: string; error?: string } {\n  if (!timezone) return { zone: 'UTC' }\n  if (!IANAZone.isValidZone(timezone)) return { zone: '', error: `Invalid timezone \"${timezone}\".` }\n  return { zone: timezone }\n}\n\nfunction countBusinessDays(from: DateTime, to: DateTime): number {\n  const forward = to >= from\n  const start = forward ? from.startOf('day') : to.startOf('day')\n  const end = forward ? to.startOf('day') : from.startOf('day')\n\n  const totalDays = Math.round(end.diff(start, 'days').days)\n  const fullWeeks = Math.floor(totalDays / 7)\n  let bdays = fullWeeks * 5\n\n  let cursor = start.plus({ days: fullWeeks * 7 })\n  while (cursor < end) {\n    cursor = cursor.plus({ days: 1 })\n    if (cursor.weekday <= 5) bdays++\n  }\n\n  return forward ? bdays : -bdays\n}\n\n/**\n * Find the Nth occurrence of a weekday in a given month.\n *\n * @remarks\n * Examples: \"2nd Friday of March 2026\", \"last Monday of January 2025\". Accepts 1st–5th and\n * `last`. Returns an error if the month does not contain that many occurrences of the weekday.\n */\nexport const dateNthWeekdayTool = new Tool({\n  name: 'date_nth_weekday',\n  description:\n    'Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".',\n  inputSchema: validator.object({\n    nth: validator\n      .string()\n      .required()\n      .description('Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\".'),\n    weekday: validator\n      .string()\n      .valid('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')\n      .required()\n      .description('Day of the week.'),\n    month: validator.number().required().description('Month number (1–12).'),\n    year: validator.number().optional().description('Year (defaults to current year).'),\n    timezone: validator\n      .string()\n      .optional()\n      .allow('')\n      .description('IANA timezone. Omit or send an empty string to use UTC.'),\n  }),\n  handler: async (args) => {\n    const {\n      nth,\n      weekday,\n      month: rawMonth,\n      year: rawYear,\n      timezone,\n    } = args as {\n      nth: string\n      weekday: string\n      month: number\n      year?: number\n      timezone?: string\n    }\n    const { zone, error: zoneError } = resolveZone(timezone)\n    if (zoneError) return `Error: ${zoneError}`\n\n    const weekdayNames: Record<string, number> = {\n      monday: 1,\n      tuesday: 2,\n      wednesday: 3,\n      thursday: 4,\n      friday: 5,\n      saturday: 6,\n      sunday: 7,\n    }\n\n    const targetWeekday = weekdayNames[weekday.toLowerCase()]\n    const month = Math.floor(rawMonth)\n    if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`\n\n    const year = Math.floor(rawYear ?? DateTime.now().setZone(zone).year)\n    const nthRaw = nth.toLowerCase().replace(/\\s/g, '')\n\n    const firstOfMonth = DateTime.fromObject({ year, month, day: 1 }, { zone })\n    if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`\n\n    const occurrences: DateTime[] = []\n    let cursor = firstOfMonth\n    while (cursor.weekday !== targetWeekday) {\n      cursor = cursor.plus({ days: 1 })\n    }\n    while (cursor.month === month) {\n      occurrences.push(cursor)\n      cursor = cursor.plus({ weeks: 1 })\n    }\n\n    let result: DateTime | undefined\n\n    if (nthRaw === 'last') {\n      result = occurrences[occurrences.length - 1]\n    } else {\n      const nthMap: Record<string, number> = {\n        '1st': 1,\n        '1': 1,\n        'first': 1,\n        '2nd': 2,\n        '2': 2,\n        'second': 2,\n        '3rd': 3,\n        '3': 3,\n        'third': 3,\n        '4th': 4,\n        '4': 4,\n        'fourth': 4,\n        '5th': 5,\n        '5': 5,\n        'fifth': 5,\n      }\n      const n = nthMap[nthRaw]\n      if (!n) return `Error: Invalid nth value \"${nth}\". Use 1st–5th or \"last\".`\n      if (n > occurrences.length) {\n        return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat('LLLL yyyy')} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? 's' : ''}).`\n      }\n      result = occurrences[n - 1]\n    }\n\n    if (!result) return 'Error: Could not compute the date.'\n\n    return `${nth} ${weekday} of ${result.toFormat('LLLL yyyy')}: ${result.toISODate()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy')}`\n  },\n})\n\n/**\n * Get calendar metadata for a date.\n *\n * @remarks\n * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via\n * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO\n * dates, natural-language (\"next Tuesday\"), and `now`.\n */\nexport const dateCalendarInfoTool = new Tool({\n  name: 'date_calendar_info',\n  description:\n    'Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.',\n  inputSchema: validator.object({\n    date: validator\n      .string()\n      .required()\n      .description('ISO 8601 date, natural language date, or \"now\".'),\n    timezone: validator\n      .string()\n      .optional()\n      .allow('')\n      .description('IANA timezone. Omit or send an empty string to use UTC.'),\n    fiscal_year_start_month: validator\n      .number()\n      .default(1)\n      .description('Month when fiscal year starts (1–12, default: 1 = calendar year).'),\n  }),\n  handler: async (args) => {\n    const {\n      date: dateStr,\n      timezone,\n      fiscal_year_start_month: rawFyStart,\n    } = args as {\n      date: string\n      timezone?: string\n      fiscal_year_start_month: number\n    }\n    const { zone, error: zoneError } = resolveZone(timezone)\n    if (zoneError) return `Error: ${zoneError}`\n\n    let dt: DateTime\n\n    if (dateStr.toLowerCase() === 'now') {\n      dt = DateTime.now().setZone(zone)\n    } else {\n      dt = DateTime.fromISO(dateStr, { zone })\n      if (!dt.isValid) {\n        const parsed = chrono.parseDate(dateStr, new Date())\n        if (!parsed) return `Error: Could not parse date \"${dateStr}\".`\n        dt = DateTime.fromJSDate(parsed).setZone(zone)\n      }\n    }\n\n    const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n    const calendarQuarter = Math.ceil(dt.month / 3)\n\n    const monthInFY = (dt.month - fyStart + 12) % 12\n    const fiscalQuarter = Math.floor(monthInFY / 3) + 1\n    const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1\n\n    const firstOfMonth = dt.startOf('month')\n    const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7)\n\n    const dayOfYear = Math.floor(dt.diff(dt.startOf('year'), 'days').days) + 1\n\n    const isWeekend = dt.weekday >= 6\n\n    const lines = [\n      `Date: ${dt.toISODate()} (${dt.toFormat('cccc, LLLL d, yyyy')})`,\n      '',\n      `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,\n      `Day of year: ${dayOfYear} / ${dt.daysInYear}`,\n      `Day of week: ${dt.weekday} (${dt.toFormat('cccc')})`,\n      `Week of month: ${weekOfMonth}`,\n      `Weekend: ${isWeekend ? 'Yes' : 'No'}`,\n      '',\n      `Calendar quarter: Q${calendarQuarter}`,\n      `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ''})`,\n    ]\n\n    return lines.join('\\n')\n  },\n})\n\n/**\n * Parse a date/time expression from natural language or common formats.\n *\n * @remarks\n * Examples: `\"next Monday\"`, `\"March 5th\"`, `\"in 2 weeks\"`, `\"yesterday\"`. Uses chrono-node for\n * relative parsing. `reference_date` overrides the \"now\" anchor.\n */\nexport const dateParseTool = new Tool({\n  name: 'date_parse',\n  description:\n    'Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.',\n  inputSchema: validator.object({\n    text: validator\n      .string()\n      .required()\n      .description('Date/time expression to parse (natural language or structured)'),\n    reference_date: validator\n      .string()\n      .optional()\n      .allow('')\n      .description(\n        'ISO date to treat as \"now\" for relative expressions. Omit or send an empty string to use the current time.'\n      ),\n    timezone: validator\n      .string()\n      .optional()\n      .allow('')\n      .description('IANA timezone for the result. Omit or send an empty string to use UTC.'),\n  }),\n  handler: async (args) => {\n    const {\n      text,\n      reference_date: referenceDate,\n      timezone,\n    } = args as {\n      text: string\n      reference_date?: string\n      timezone?: string\n    }\n    const { zone, error: zoneError } = resolveZone(timezone)\n    if (zoneError) return `Error: ${zoneError}`\n\n    let refDate = new Date()\n    if (referenceDate) {\n      refDate = new Date(referenceDate)\n      if (Number.isNaN(refDate.getTime()))\n        return `Error: Invalid reference_date \"${referenceDate}\".`\n    }\n\n    const parsed = chrono.parseDate(text, refDate)\n    if (!parsed) return `Error: Could not parse a date from \"${text}\".`\n\n    const dt = DateTime.fromJSDate(parsed).setZone(zone)\n    return `ISO: ${dt.toISO()}\\nFormatted: ${dt.toFormat('cccc, LLLL d, yyyy h:mm a ZZZZ')}`\n  },\n})\n\n/**\n * Get the start or end of a time period containing a given date.\n *\n * @remarks\n * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year\n * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).\n */\nexport const datePeriodTool = new Tool({\n  name: 'date_period',\n  description:\n    'Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.',\n  inputSchema: validator.object({\n    date: validator.string().required().description('ISO 8601 date or \"now\"'),\n    period: validator\n      .string()\n      .valid('day', 'week', 'isoweek', 'month', 'quarter', 'year')\n      .required()\n      .description('Time period (isoweek = Monday-start week)'),\n    boundary: validator\n      .string()\n      .valid('start', 'end')\n      .required()\n      .description('\"start\" for the first moment, \"end\" for the last moment of the period'),\n    timezone: validator\n      .string()\n      .optional()\n      .allow('')\n      .description('IANA timezone. Omit or send an empty string to use UTC.'),\n    fiscal_year_start_month: validator\n      .number()\n      .default(1)\n      .description(\n        'For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)'\n      ),\n  }),\n  handler: async (args) => {\n    const {\n      date: dateStr,\n      period,\n      boundary,\n      timezone,\n      fiscal_year_start_month: rawFyStart,\n    } = args as {\n      date: string\n      period: 'day' | 'week' | 'isoweek' | 'month' | 'quarter' | 'year'\n      boundary: 'start' | 'end'\n      timezone?: string\n      fiscal_year_start_month: number\n    }\n    const { zone, error: zoneError } = resolveZone(timezone)\n    if (zoneError) return `Error: ${zoneError}`\n\n    const dt =\n      dateStr.toLowerCase() === 'now'\n        ? DateTime.now().setZone(zone)\n        : DateTime.fromISO(dateStr, { zone })\n    if (!dt.isValid) return `Error: Invalid date \"${dateStr}\".`\n\n    const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n    let result: DateTime\n\n    switch (period) {\n      case 'day':\n        result = boundary === 'start' ? dt.startOf('day') : dt.endOf('day')\n        break\n      case 'week':\n        result = boundary === 'start' ? dt.startOf('week') : dt.endOf('week')\n        break\n      case 'isoweek':\n        result =\n          boundary === 'start'\n            ? dt.startOf('week').set({ weekday: 1 })\n            : dt.startOf('week').set({ weekday: 7 }).endOf('day')\n        break\n      case 'month':\n        result = boundary === 'start' ? dt.startOf('month') : dt.endOf('month')\n        break\n      case 'quarter': {\n        // Months since the fiscal year began (0–11), then the offset into the current quarter.\n        // Stepping back that many whole months from the start of `dt`'s month lands on the quarter\n        // start — and crucially handles quarters that span the calendar-year boundary (e.g. an\n        // FY-Feb Q4 of Nov–Jan): subtracting months rolls the year back correctly, where the old\n        // `dt.set({month})` kept the current year and produced a date in the wrong quarter.\n        const monthInFY = (dt.month - fyStart + 12) % 12\n        const monthsIntoQuarter = monthInFY % 3\n        const qStart = dt.startOf('month').minus({ months: monthsIntoQuarter })\n        result =\n          boundary === 'start' ? qStart : qStart.plus({ months: 3 }).minus({ days: 1 }).endOf('day')\n        break\n      }\n      case 'year':\n        if (fyStart === 1) {\n          result = boundary === 'start' ? dt.startOf('year') : dt.endOf('year')\n        } else {\n          const fyStartThis = dt.set({ month: fyStart, day: 1 }).startOf('day')\n          const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 })\n          result =\n            boundary === 'start'\n              ? fyBase\n              : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf('day')\n        }\n        break\n    }\n\n    return `${boundary === 'start' ? 'Start' : 'End'} of ${period} containing ${dateStr}: ${result.toISO()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy h:mm:ss a ZZZZ')}`\n  },\n})\n\n/**\n * Count business days between two dates, or compute the date N business days away.\n *\n * @remarks\n * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or\n * `add_days` (compute target date). Negative `add_days` walks backwards.\n */\nexport const dateBusinessDaysTool = new Tool({\n  name: 'date_business_days',\n  description:\n    'Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.',\n  inputSchema: validator.object({\n    from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n    to: validator\n      .string()\n      .optional()\n      .allow('')\n      .description(\n        'End date (ISO 8601 or \"now\") — for counting business days between two dates. Omit or send an empty string when using \"add_days\" instead.'\n      ),\n    add_days: validator\n      .number()\n      .optional()\n      .description('Instead of \"to\": number of business days to add (negative to subtract)'),\n    timezone: validator\n      .string()\n      .optional()\n      .allow('')\n      .description('IANA timezone. Omit or send an empty string to use UTC.'),\n  }),\n  handler: async (args) => {\n    const {\n      from: fromStr,\n      to: toStr,\n      add_days: addDays,\n      timezone,\n    } = args as {\n      from: string\n      to?: string\n      add_days?: number\n      timezone?: string\n    }\n    const { zone, error: zoneError } = resolveZone(timezone)\n    if (zoneError) return `Error: ${zoneError}`\n\n    const fromDt = (\n      fromStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(fromStr)\n    ).setZone(zone)\n    if (!fromDt.isValid) return `Error: Invalid from date \"${fromStr}\".`\n\n    if (addDays !== undefined) {\n      const n = Math.floor(addDays)\n      let cursor = fromDt.startOf('day')\n      let remaining = Math.abs(n)\n      const dir = n >= 0 ? 1 : -1\n      while (remaining > 0) {\n        cursor = cursor.plus({ days: dir })\n        if (cursor.weekday <= 5) remaining--\n      }\n      return `${n >= 0 ? '+' : ''}${n} business day${Math.abs(n) !== 1 ? 's' : ''} from ${fromStr}: ${cursor.toISODate()}\\nFormatted: ${cursor.toFormat('cccc, LLLL d, yyyy')}`\n    }\n\n    if (!toStr) return 'Error: Provide either \"to\" date or \"add_days\".'\n\n    const toDt = (toStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(toStr)).setZone(\n      zone\n    )\n    if (!toDt.isValid) return `Error: Invalid to date \"${toStr}\".`\n\n    const count = countBusinessDays(fromDt, toDt)\n    return `Business days from ${fromStr} to ${toStr}: ${count}`\n  },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAeA,SAAS,YAAY,UAAgE;CACnF,IAAI,CAAC,UAAU,OAAO,EAAE,MAAM,MAAM;CACpC,IAAI,CAAC,MAAA,SAAS,YAAY,QAAQ,GAAG,OAAO;EAAE,MAAM;EAAI,OAAO,qBAAqB,SAAS;CAAI;CACjG,OAAO,EAAE,MAAM,SAAS;AAC1B;AAEA,SAAS,kBAAkB,MAAgB,IAAsB;CAC/D,MAAM,UAAU,MAAM;CACtB,MAAM,QAAQ,UAAU,KAAK,QAAQ,KAAK,IAAI,GAAG,QAAQ,KAAK;CAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,KAAK,IAAI,KAAK,QAAQ,KAAK;CAE5D,MAAM,YAAY,KAAK,MAAM,IAAI,KAAK,OAAO,MAAM,EAAE,IAAI;CACzD,MAAM,YAAY,KAAK,MAAM,YAAY,CAAC;CAC1C,IAAI,QAAQ,YAAY;CAExB,IAAI,SAAS,MAAM,KAAK,EAAE,MAAM,YAAY,EAAE,CAAC;CAC/C,OAAO,SAAS,KAAK;EACnB,SAAS,OAAO,KAAK,EAAE,MAAM,EAAE,CAAC;EAChC,IAAI,OAAO,WAAW,GAAG;CAC3B;CAEA,OAAO,UAAU,QAAQ,CAAC;AAC5B;;;;;;;;AASA,IAAa,qBAAqB,IAAI,yBAAA,KAAK;CACzC,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,KAAK,kBAAA,UACF,OAAO,EACP,SAAS,EACT,YAAY,6EAAiE;EAChF,SAAS,kBAAA,UACN,OAAO,EACP,MAAM,UAAU,WAAW,aAAa,YAAY,UAAU,YAAY,QAAQ,EAClF,SAAS,EACT,YAAY,kBAAkB;EACjC,OAAO,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,sBAAsB;EACvE,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,kCAAkC;EAClF,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YAAY,yDAAyD;CAC1E,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,KACA,SACA,OAAO,UACP,MAAM,SACN,aACE;EAOJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAYhC,MAAM,gBAAgB;GATpB,QAAQ;GACR,SAAS;GACT,WAAW;GACX,UAAU;GACV,QAAQ;GACR,UAAU;GACV,QAAQ;EAGY,EAAa,QAAQ,YAAY;EACvD,MAAM,QAAQ,KAAK,MAAM,QAAQ;EACjC,IAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO,kCAAkC,SAAS;EAE/E,MAAM,OAAO,KAAK,MAAM,WAAW,MAAA,SAAS,IAAI,EAAE,QAAQ,IAAI,EAAE,IAAI;EACpE,MAAM,SAAS,IAAI,YAAY,EAAE,QAAQ,OAAO,EAAE;EAElD,MAAM,eAAe,MAAA,SAAS,WAAW;GAAE;GAAM;GAAO,KAAK;EAAE,GAAG,EAAE,KAAK,CAAC;EAC1E,IAAI,CAAC,aAAa,SAAS,OAAO,2BAA2B,KAAK,GAAG,MAAM;EAE3E,MAAM,cAA0B,CAAC;EACjC,IAAI,SAAS;EACb,OAAO,OAAO,YAAY,eACxB,SAAS,OAAO,KAAK,EAAE,MAAM,EAAE,CAAC;EAElC,OAAO,OAAO,UAAU,OAAO;GAC7B,YAAY,KAAK,MAAM;GACvB,SAAS,OAAO,KAAK,EAAE,OAAO,EAAE,CAAC;EACnC;EAEA,IAAI;EAEJ,IAAI,WAAW,QACb,SAAS,YAAY,YAAY,SAAS;OACrC;GAkBL,MAAM,IAAI;IAhBR,OAAO;IACP,KAAK;IACL,SAAS;IACT,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,KAAK;IACL,SAAS;IACT,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,KAAK;IACL,SAAS;GAED,EAAO;GACjB,IAAI,CAAC,GAAG,OAAO,6BAA6B,IAAI;GAChD,IAAI,IAAI,YAAY,QAClB,OAAO,sBAAsB,IAAI,GAAG,QAAQ,MAAM,aAAa,SAAS,WAAW,EAAE,SAAS,YAAY,OAAO,aAAa,YAAY,WAAW,IAAI,MAAM,GAAG;GAEpK,SAAS,YAAY,IAAI;EAC3B;EAEA,IAAI,CAAC,QAAQ,OAAO;EAEpB,OAAO,GAAG,IAAI,GAAG,QAAQ,MAAM,OAAO,SAAS,WAAW,EAAE,IAAI,OAAO,UAAU,EAAE,eAAe,OAAO,SAAS,oBAAoB;CACxI;AACF,CAAC;;;;;;;;;AAUD,IAAa,uBAAuB,IAAI,yBAAA,KAAK;CAC3C,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UACH,OAAO,EACP,SAAS,EACT,YAAY,mDAAiD;EAChE,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YAAY,yDAAyD;EACxE,yBAAyB,kBAAA,UACtB,OAAO,EACP,QAAQ,CAAC,EACT,YAAY,mEAAmE;CACpF,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MAAM,SACN,UACA,yBAAyB,eACvB;EAKJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,IAAI;EAEJ,IAAI,QAAQ,YAAY,MAAM,OAC5B,KAAK,MAAA,SAAS,IAAI,EAAE,QAAQ,IAAI;OAC3B;GACL,KAAK,MAAA,SAAS,QAAQ,SAAS,EAAE,KAAK,CAAC;GACvC,IAAI,CAAC,GAAG,SAAS;IACf,MAAM,SAAS,YAAO,UAAU,yBAAS,IAAI,KAAK,CAAC;IACnD,IAAI,CAAC,QAAQ,OAAO,gCAAgC,QAAQ;IAC5D,KAAK,MAAA,SAAS,WAAW,MAAM,EAAE,QAAQ,IAAI;GAC/C;EACF;EAEA,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,CAAC,CAAC;EAEhE,MAAM,kBAAkB,KAAK,KAAK,GAAG,QAAQ,CAAC;EAE9C,MAAM,aAAa,GAAG,QAAQ,UAAU,MAAM;EAC9C,MAAM,gBAAgB,KAAK,MAAM,YAAY,CAAC,IAAI;EAClD,MAAM,aAAa,GAAG,SAAS,UAAU,GAAG,OAAO,GAAG,OAAO;EAE7D,MAAM,eAAe,GAAG,QAAQ,OAAO;EACvC,MAAM,cAAc,KAAK,MAAM,GAAG,MAAM,aAAa,UAAU,KAAK,CAAC;EAErE,MAAM,YAAY,KAAK,MAAM,GAAG,KAAK,GAAG,QAAQ,MAAM,GAAG,MAAM,EAAE,IAAI,IAAI;EAEzE,MAAM,YAAY,GAAG,WAAW;EAehC,OAAO;GAZL,SAAS,GAAG,UAAU,EAAE,IAAI,GAAG,SAAS,oBAAoB,EAAE;GAC9D;GACA,oBAAoB,GAAG,WAAW,cAAc,GAAG,SAAS;GAC5D,gBAAgB,UAAU,KAAK,GAAG;GAClC,gBAAgB,GAAG,QAAQ,IAAI,GAAG,SAAS,MAAM,EAAE;GACnD,kBAAkB;GAClB,YAAY,YAAY,QAAQ;GAChC;GACA,sBAAsB;GACtB,qBAAqB,cAAc,MAAM,aAAa,YAAY,IAAI,kBAAkB,YAAY,GAAG;EAGlG,EAAM,KAAK,IAAI;CACxB;AACF,CAAC;;;;;;;;AASD,IAAa,gBAAgB,IAAI,yBAAA,KAAK;CACpC,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UACH,OAAO,EACP,SAAS,EACT,YAAY,gEAAgE;EAC/E,gBAAgB,kBAAA,UACb,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YACC,8GACF;EACF,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YAAY,wEAAwE;CACzF,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MACA,gBAAgB,eAChB,aACE;EAKJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,IAAI,0BAAU,IAAI,KAAK;EACvB,IAAI,eAAe;GACjB,UAAU,IAAI,KAAK,aAAa;GAChC,IAAI,OAAO,MAAM,QAAQ,QAAQ,CAAC,GAChC,OAAO,kCAAkC,cAAc;EAC3D;EAEA,MAAM,SAAS,YAAO,UAAU,MAAM,OAAO;EAC7C,IAAI,CAAC,QAAQ,OAAO,uCAAuC,KAAK;EAEhE,MAAM,KAAK,MAAA,SAAS,WAAW,MAAM,EAAE,QAAQ,IAAI;EACnD,OAAO,QAAQ,GAAG,MAAM,EAAE,eAAe,GAAG,SAAS,gCAAgC;CACvF;AACF,CAAC;;;;;;;;AASD,IAAa,iBAAiB,IAAI,yBAAA,KAAK;CACrC,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,0BAAwB;EACxE,QAAQ,kBAAA,UACL,OAAO,EACP,MAAM,OAAO,QAAQ,WAAW,SAAS,WAAW,MAAM,EAC1D,SAAS,EACT,YAAY,2CAA2C;EAC1D,UAAU,kBAAA,UACP,OAAO,EACP,MAAM,SAAS,KAAK,EACpB,SAAS,EACT,YAAY,2EAAuE;EACtF,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YAAY,yDAAyD;EACxE,yBAAyB,kBAAA,UACtB,OAAO,EACP,QAAQ,CAAC,EACT,YACC,+FACF;CACJ,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MAAM,SACN,QACA,UACA,UACA,yBAAyB,eACvB;EAOJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,MAAM,KACJ,QAAQ,YAAY,MAAM,QACtB,MAAA,SAAS,IAAI,EAAE,QAAQ,IAAI,IAC3B,MAAA,SAAS,QAAQ,SAAS,EAAE,KAAK,CAAC;EACxC,IAAI,CAAC,GAAG,SAAS,OAAO,wBAAwB,QAAQ;EAExD,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,CAAC,CAAC;EAEhE,IAAI;EAEJ,QAAQ,QAAR;GACE,KAAK;IACH,SAAS,aAAa,UAAU,GAAG,QAAQ,KAAK,IAAI,GAAG,MAAM,KAAK;IAClE;GACF,KAAK;IACH,SAAS,aAAa,UAAU,GAAG,QAAQ,MAAM,IAAI,GAAG,MAAM,MAAM;IACpE;GACF,KAAK;IACH,SACE,aAAa,UACT,GAAG,QAAQ,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,IACrC,GAAG,QAAQ,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,KAAK;IACxD;GACF,KAAK;IACH,SAAS,aAAa,UAAU,GAAG,QAAQ,OAAO,IAAI,GAAG,MAAM,OAAO;IACtE;GACF,KAAK,WAAW;IAOd,MAAM,qBADa,GAAG,QAAQ,UAAU,MAAM,KACR;IACtC,MAAM,SAAS,GAAG,QAAQ,OAAO,EAAE,MAAM,EAAE,QAAQ,kBAAkB,CAAC;IACtE,SACE,aAAa,UAAU,SAAS,OAAO,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAC3F;GACF;GACA,KAAK;IACH,IAAI,YAAY,GACd,SAAS,aAAa,UAAU,GAAG,QAAQ,MAAM,IAAI,GAAG,MAAM,MAAM;SAC/D;KACL,MAAM,cAAc,GAAG,IAAI;MAAE,OAAO;MAAS,KAAK;KAAE,CAAC,EAAE,QAAQ,KAAK;KACpE,MAAM,SAAS,MAAM,cAAc,cAAc,YAAY,MAAM,EAAE,OAAO,EAAE,CAAC;KAC/E,SACE,aAAa,UACT,SACA,OAAO,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAChE;IACA;EACJ;EAEA,OAAO,GAAG,aAAa,UAAU,UAAU,MAAM,MAAM,OAAO,cAAc,QAAQ,IAAI,OAAO,MAAM,EAAE,eAAe,OAAO,SAAS,mCAAmC;CAC3K;AACF,CAAC;;;;;;;;AASD,IAAa,uBAAuB,IAAI,yBAAA,KAAK;CAC3C,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,kCAAgC;EAChF,IAAI,kBAAA,UACD,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YACC,8IACF;EACF,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,YAAY,0EAAwE;EACvF,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,MAAM,EAAE,EACR,YAAY,yDAAyD;CAC1E,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MAAM,SACN,IAAI,OACJ,UAAU,SACV,aACE;EAMJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,MAAM,UACJ,QAAQ,YAAY,MAAM,QAAQ,MAAA,SAAS,IAAI,IAAI,MAAA,SAAS,QAAQ,OAAO,GAC3E,QAAQ,IAAI;EACd,IAAI,CAAC,OAAO,SAAS,OAAO,6BAA6B,QAAQ;EAEjE,IAAI,YAAY,KAAA,GAAW;GACzB,MAAM,IAAI,KAAK,MAAM,OAAO;GAC5B,IAAI,SAAS,OAAO,QAAQ,KAAK;GACjC,IAAI,YAAY,KAAK,IAAI,CAAC;GAC1B,MAAM,MAAM,KAAK,IAAI,IAAI;GACzB,OAAO,YAAY,GAAG;IACpB,SAAS,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;IAClC,IAAI,OAAO,WAAW,GAAG;GAC3B;GACA,OAAO,GAAG,KAAK,IAAI,MAAM,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,GAAG,QAAQ,QAAQ,IAAI,OAAO,UAAU,EAAE,eAAe,OAAO,SAAS,oBAAoB;EACxK;EAEA,IAAI,CAAC,OAAO,OAAO;EAEnB,MAAM,QAAQ,MAAM,YAAY,MAAM,QAAQ,MAAA,SAAS,IAAI,IAAI,MAAA,SAAS,QAAQ,KAAK,GAAG,QACtF,IACF;EACA,IAAI,CAAC,KAAK,SAAS,OAAO,2BAA2B,MAAM;EAG3D,OAAO,sBAAsB,QAAQ,MAAM,MAAM,IADnC,kBAAkB,QAAQ,IACa;CACvD;AACF,CAAC"}