[{"name":"Ical","comment":" Shared types for the elm-ical package.\n\nTo generate iCal feeds, see [`Ical.Generator`](Ical-Generator).\nTo parse iCal feeds, see [`Ical.Parser`](Ical-Parser).\nFor recurrence rule types, see [`Ical.Recurrence`](Ical-Recurrence).\n\n\n## Event status\n\n@docs Status\n\n\n## Transparency\n\n@docs Transparency\n\n\n## Journal status\n\n@docs JournalStatus\n\n","unions":[{"name":"JournalStatus","comment":" Journal status per\n[RFC 5545 Section 3.8.1.11](https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.1.11).\n\n  - `Draft` — the journal entry is a draft.\n  - `Final` — the journal entry is final.\n  - `CancelledJournal` — the journal entry has been cancelled.\n    (Named `CancelledJournal` to avoid a clash with [`Cancelled`](#Status).)\n\n","args":[],"cases":[["Draft",[]],["Final",[]],["CancelledJournal",[]]]},{"name":"Status","comment":" The scheduling status of an event.\n\n  - `Tentative` — the event is not yet confirmed.\n  - `Confirmed` — the event is definite.\n  - `Cancelled` — the event has been cancelled.\n\nPer [RFC 5545 Section 3.8.1.11](https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.1.11).\n\n","args":[],"cases":[["Tentative",[]],["Confirmed",[]],["Cancelled",[]]]},{"name":"Transparency","comment":" Whether the event blocks time on a calendar for free/busy lookups.\n\n  - `Opaque` — the event blocks time (default in iCal).\n  - `Transparent` — the event does not block time (e.g. reminders, FYI events).\n\nPer [RFC 5545 Section 3.8.2.7](https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.2.7).\n\n","args":[],"cases":[["Opaque",[]],["Transparent",[]]]}],"aliases":[],"values":[],"binops":[]},{"name":"Ical.Generator","comment":" Generate iCal ([RFC 5545](https://datatracker.ietf.org/doc/html/rfc5545)) calendar feeds\nfrom typed Elm values.\n\n    import Date\n    import Ical\n    import Ical.Generator as Generator\n    import Ical.Recurrence as Recurrence\n    import Time\n\n    teamCalendar : Time.Posix -> String\n    teamCalendar now =\n        let\n            weeklySync : Generator.Event\n            weeklySync =\n                Generator.event\n                    { id = \"weekly-sync\"\n                    , stamp = now\n                    , time =\n                        Generator.timedEvent\n                            { start = mar18at10am\n                            , end = mar18at11am\n                            }\n                    , summary = \"Weekly Team Sync\"\n                    }\n                    |> Generator.withRecurrenceRule\n                        (Generator.rule (Recurrence.Weekly { every = 1, weekStart = Time.Mon }))\n\n            offsite : Generator.Event\n            offsite =\n                Generator.event\n                    { id = \"offsite-q2\"\n                    , stamp = now\n                    , time =\n                        Generator.allDayRange\n                            { start = Date.fromCalendarDate 2021 Time.Jun 14\n                            , end = Date.fromCalendarDate 2021 Time.Jun 16\n                            }\n                    , summary = \"Q2 Team Offsite\"\n                    }\n                    |> Generator.withLocation \"Moscone Center, 747 Howard St, San Francisco, CA 94103\"\n        in\n        Generator.generate\n            (Generator.config\n                { id = \"//mycompany//team//EN\"\n                , domain = \"mycompany.com\"\n                }\n                |> Generator.withName \"Engineering Team\"\n            )\n            { events = [ weeklySync, offsite ]\n            , journals = []\n            }\n\n    mar18at10am : Time.Posix\n    mar18at10am =\n        Time.millisToPosix 1616065200000\n\n    mar18at11am : Time.Posix\n    mar18at11am =\n        Time.millisToPosix 1616068800000\n\nAll generation types are opaque with builder functions. Invalid inputs like\nreversed start/end times, negative intervals, or incompatible recurrence\nparts are silently normalized.\n\n\n## Generating output\n\n@docs generate, generateEvent\n\n\n## Calendar configuration\n\n@docs Config, config, withName, withCalendarDescription, withUrl\n\n\n## Events\n\n@docs Event, event, EventTime, allDay, allDayRange, timedEvent, floatingTime, FloatingDateTime, Organizer, Attendee\n@docs withDescription, withLocation, withOrganizer, withHtmlDescription\n@docs withStatus, withTransparency\n@docs withCreated, withLastModified\n@docs withRecurrenceRule, withAttendee\n@docs withAlarm, Alarm, displayAlarm, audioAlarm, AlarmTrigger\n\n\n## Journals\n\n@docs Journal, journal, JournalTime\n@docs withJournalDescription, withJournalDate, withJournalTime, withJournalFloatingTime\n@docs withJournalStatus\n@docs withJournalCreated, withJournalLastModified, withJournalOrganizer\n\n\n## Recurrence rules\n\n@docs Rule, rule, withCount, withUntilDate, withUntilDateTime\n@docs withByDay, withByMonthDay, withByMonth, withBySetPos\n@docs withByHour, withByMinute, withBySecond, withByYearDay, withByWeekNo\n\n","unions":[{"name":"Alarm","comment":" An opaque alarm (VALARM). Create one with [`displayAlarm`](#displayAlarm)\nor [`audioAlarm`](#audioAlarm), then attach to an event with\n[`withAlarm`](#withAlarm).\n\nThe RFC also defines EMAIL alarms, but in practice they are rarely supported\nby modern calendar clients (Google Calendar, Apple Calendar, Outlook all use\npush notifications instead). Only DISPLAY and AUDIO are provided here.\n\n","args":[],"cases":[]},{"name":"AlarmTrigger","comment":" When an alarm fires, as a signed offset in seconds. Negative values mean\nbefore, positive values mean after.\n\n    -- 15 minutes before the event starts\n    SecondsFromStart (-15 * 60)\n\n    -- 1 day before the event ends\n    SecondsFromEnd (-24 * 60 * 60)\n\n    -- at the moment the event starts\n    SecondsFromStart 0\n\n","args":[],"cases":[["SecondsFromStart",["Basics.Int"]],["SecondsFromEnd",["Basics.Int"]]]},{"name":"Config","comment":" An opaque type representing calendar configuration. Create one with\n[`config`](#config) and customize with [`withName`](#withName),\n[`withCalendarDescription`](#withCalendarDescription), and [`withUrl`](#withUrl).\n","args":[],"cases":[]},{"name":"Event","comment":" An opaque type representing a calendar event. Create one with [`event`](#event)\nand customize it with the `with*` functions.\n","args":[],"cases":[]},{"name":"EventTime","comment":" Represents the time span of an event. Create values with [`allDay`](#allDay),\n[`allDayRange`](#allDayRange), [`timedEvent`](#timedEvent), or\n[`floatingTime`](#floatingTime).\n","args":[],"cases":[]},{"name":"Journal","comment":" An opaque type representing a journal entry. Create one with\n[`journal`](#journal) and customize with the `withJournal*` functions.\n","args":[],"cases":[]},{"name":"JournalTime","comment":" The time of a journal entry. Journals have no time span, just an optional\ndate or datetime stamp.\n","args":[],"cases":[["JournalAllDay",["Date.Date"]],["JournalWithTime",["Time.Posix"]],["JournalFloatingTime",["Ical.Generator.FloatingDateTime"]]]},{"name":"Rule","comment":" An opaque recurrence rule. Create one with [`rule`](#rule) and customize\nwith the `with*` builder functions.\n\n    Generator.rule (Recurrence.Weekly { every = 1, weekStart = Time.Mon })\n        |> Generator.withByDay [ Recurrence.every Time.Mon ]\n        |> Generator.withCount 10\n\n","args":[],"cases":[]}],"aliases":[{"name":"Attendee","comment":" A person with a name and email address, used for the ATTENDEE property.\n","args":[],"type":"{ name : String.String, email : String.String }"},{"name":"FloatingDateTime","comment":" A local date-time with no timezone. Used for floating-time events that\nrepresent the same wall-clock time regardless of the viewer's timezone.\n\n    { date = Date.fromCalendarDate 2021 Time.Mar 18\n    , hour = 14\n    , minute = 0\n    , second = 0\n    }\n\nOut-of-range values are clamped: hour to 0–23, minute to 0–59, second to 0–59.\n\n","args":[],"type":"{ date : Date.Date, hour : Basics.Int, minute : Basics.Int, second : Basics.Int }"},{"name":"Organizer","comment":" A person with a name and email address, used for the ORGANIZER property.\n","args":[],"type":"{ name : String.String, email : String.String }"}],"values":[{"name":"allDay","comment":" Create a single-day all-day event.\n\n    Generator.allDay (Date.fromCalendarDate 2021 Time.Mar 18)\n\nThe library automatically adds one day to produce the exclusive DTEND\nrequired by iCal.\n\n","type":"Date.Date -> Ical.Generator.EventTime"},{"name":"allDayRange","comment":" Create a multi-day all-day event time span. The `end` date is **inclusive**.\nThe library automatically adds one day to produce the exclusive DTEND\nrequired by iCal.\n\n    Generator.allDayRange\n        { start = Date.fromCalendarDate 2021 Time.Jun 14\n        , end = Date.fromCalendarDate 2021 Time.Jun 16\n        }\n\nIf `end` is before `start`, the dates are swapped automatically.\n\n","type":"{ start : Date.Date, end : Date.Date } -> Ical.Generator.EventTime"},{"name":"audioAlarm","comment":" Create an audio alarm that plays a sound.\n\n    Generator.audioAlarm\n        { trigger = Generator.SecondsFromStart (-15 * 60)\n        }\n\n","type":"{ trigger : Ical.Generator.AlarmTrigger } -> Ical.Generator.Alarm"},{"name":"config","comment":" Create a calendar configuration with the required fields.\n\n  - `id` — identifies your product in the PRODID property\n    (e.g. `\"//mycompany//myapp//EN\"`).\n  - `domain` — your domain, used to generate globally unique event UIDs\n    (e.g. `\"example.com\"` produces UIDs like `\"event-id@example.com\"`).\n\n```\nGenerator.config { id = \"//mycompany//myapp//EN\", domain = \"example.com\" }\n```\n\n","type":"{ id : String.String, domain : String.String } -> Ical.Generator.Config"},{"name":"displayAlarm","comment":" Create a display alarm that shows a text notification.\n\n    Generator.displayAlarm\n        { description = \"Meeting in 15 minutes\"\n        , trigger = Generator.SecondsFromStart (-15 * 60)\n        }\n\n","type":"{ description : String.String, trigger : Ical.Generator.AlarmTrigger } -> Ical.Generator.Alarm"},{"name":"event","comment":" Create an event with the required fields.\n\n    Generator.event\n        { id = \"unique-id-123\"\n        , stamp = timestamp\n        , time = Generator.timedEvent { start = startTime, end = endTime }\n        , summary = \"Team Meeting\"\n        }\n\n","type":"{ id : String.String, stamp : Time.Posix, time : Ical.Generator.EventTime, summary : String.String } -> Ical.Generator.Event"},{"name":"floatingTime","comment":" Create a floating-time event — a local date-time with no timezone.\nThe event represents the same wall-clock time regardless of the viewer's\ntimezone (e.g. \"meeting at 2pm, wherever you are\").\n\n    Generator.floatingTime\n        { start = { date = Date.fromCalendarDate 2021 Time.Mar 18, hour = 14, minute = 0, second = 0 }\n        , end = { date = Date.fromCalendarDate 2021 Time.Mar 18, hour = 15, minute = 30, second = 0 }\n        }\n\nIf `end` is before `start`, the times are swapped automatically.\nOut-of-range hour/minute/second values are clamped.\n\n","type":"{ start : Ical.Generator.FloatingDateTime, end : Ical.Generator.FloatingDateTime } -> Ical.Generator.EventTime"},{"name":"generate","comment":" Generate a complete iCal calendar string with the given config, events,\nand journals.\n\n    Generator.generate\n        (Generator.config { id = \"//myapp//EN\", domain = \"example.com\" })\n        { events = [ weeklySync ]\n        , journals = [ dailyNotes ]\n        }\n\n","type":"Ical.Generator.Config -> { events : List.List Ical.Generator.Event, journals : List.List Ical.Generator.Journal } -> String.String"},{"name":"generateEvent","comment":" Generate the iCal string for a single VEVENT component, without the\nsurrounding VCALENDAR wrapper. Useful for embedding in a larger calendar\nyou are building up. For a complete iCal document, use [`generate`](#generate).\n","type":"Ical.Generator.Config -> Ical.Generator.Event -> String.String"},{"name":"journal","comment":" Create a journal entry with the required fields.\n\n    Generator.journal\n        { id = \"journal-1\"\n        , stamp = timestamp\n        , summary = \"Daily standup notes\"\n        }\n\n","type":"{ id : String.String, stamp : Time.Posix, summary : String.String } -> Ical.Generator.Journal"},{"name":"rule","comment":" Create a recurrence rule with the given frequency. Negative `every` values\nare clamped to 1.\n\n    Generator.rule (Recurrence.Weekly { every = 1, weekStart = Time.Mon })\n        |> Generator.withByDay [ Recurrence.every Time.Mon ]\n        |> Generator.withCount 10\n\n","type":"Ical.Recurrence.Frequency -> Ical.Generator.Rule"},{"name":"timedEvent","comment":" Create a timed event time span with UTC start and end times.\n\nIf `end` is before `start`, the times are swapped automatically.\n\n","type":"{ start : Time.Posix, end : Time.Posix } -> Ical.Generator.EventTime"},{"name":"withAlarm","comment":" Add an alarm to the event. Multiple alarms can be attached by calling\nthis multiple times.\n\n    Generator.event { ... }\n        |> Generator.withAlarm\n            (Generator.displayAlarm\n                { description = \"Meeting in 15 minutes\"\n                , trigger = Generator.SecondsFromStart (-15 * 60)\n                }\n            )\n\n","type":"Ical.Generator.Alarm -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withAttendee","comment":" Add an attendee to the event.\n\n    Generator.event { ... }\n        |> Generator.withAttendee { name = \"Jane Smith\", email = \"jane@example.com\" }\n\n","type":"Ical.Generator.Attendee -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withByDay","comment":" Set which days of the week the rule applies to.\n\nOrdinal day specs are kept only for monthly rules and yearly rules without\n`BYWEEKNO`. In other frequencies they are dropped.\n\n","type":"List.List Ical.Recurrence.DaySpec -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withByHour","comment":" Set which hours the rule applies to. Valid values are 0–23. Invalid values are dropped.\nThis part is dropped for all-day events when the rule is attached.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withByMinute","comment":" Set which minutes the rule applies to. Valid values are 0–59. Invalid values are dropped.\nThis part is dropped for all-day events when the rule is attached.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withByMonth","comment":" Set which months the rule applies to.\n\n    Generator.rule (Recurrence.Yearly { every = 1 })\n        |> Generator.withByMonth [ Time.Jan, Time.Apr, Time.Jul, Time.Oct ]\n\n","type":"List.List Time.Month -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withByMonthDay","comment":" Set which days of the month the rule applies to. Valid values are\n-31 to -1 and 1 to 31. Negative values count from the end of the month\n(e.g. -1 is the last day). Invalid values are dropped. This part is also\ndropped for weekly rules.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withBySecond","comment":" Set which seconds the rule applies to. Valid values are 0–60 (60 for leap second).\nInvalid values are dropped. This part is dropped for all-day events when the\nrule is attached.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withBySetPos","comment":" Filter to specific positions within each recurrence period. For example,\nwith `BYDAY=MO,TU,WE,TH,FR`, a `bySetPos` of `[ -1 ]` means \"the last weekday.\"\nInvalid values are dropped. If no other `BY*` filters remain, `BYSETPOS` is\ndropped too.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withByWeekNo","comment":" Set which ISO week numbers the rule applies to. Valid values are\n1 to 53 and -53 to -1. Negative values count from the end of the year.\nInvalid values are dropped. This part is dropped unless the rule frequency is\nyearly.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withByYearDay","comment":" Set which days of the year the rule applies to. Valid values are\n1 to 366 and -366 to -1. Negative values count from the end of the year.\nInvalid values are dropped. This part is dropped for daily, weekly, and\nmonthly rules.\n","type":"List.List Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withCalendarDescription","comment":" Set the calendar description.\n","type":"String.String -> Ical.Generator.Config -> Ical.Generator.Config"},{"name":"withCount","comment":" Set a count limit. Values less than 1 are clamped to 1.\n","type":"Basics.Int -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withCreated","comment":" Set the creation timestamp.\n","type":"Time.Posix -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withDescription","comment":" Set a plain-text description for the event.\n","type":"String.String -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withHtmlDescription","comment":" Set an HTML-formatted description. Calendar apps that support rich text\nwill display this instead of the plain-text description.\n","type":"String.String -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withJournalCreated","comment":" Set the journal creation timestamp.\n","type":"Time.Posix -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalDate","comment":" Set the journal date (all-day).\n","type":"Date.Date -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalDescription","comment":" Set a plain-text description for the journal entry.\n","type":"String.String -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalFloatingTime","comment":" Set the journal time as a floating local datetime.\n","type":"Ical.Generator.FloatingDateTime -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalLastModified","comment":" Set the journal last-modified timestamp.\n","type":"Time.Posix -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalOrganizer","comment":" Set the journal organizer.\n","type":"Ical.Generator.Organizer -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalStatus","comment":" Set the journal status. Uses the shared [`JournalStatus`](Ical#JournalStatus) type.\n","type":"Ical.JournalStatus -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withJournalTime","comment":" Set the journal time (UTC).\n","type":"Time.Posix -> Ical.Generator.Journal -> Ical.Generator.Journal"},{"name":"withLastModified","comment":" Set the last-modified timestamp.\n","type":"Time.Posix -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withLocation","comment":" Set the event location (LOCATION property). Use a full, resolved address\nso calendar apps can map it directly:\n\n    Generator.event\n        { id = \"offsite-q2\"\n        , stamp = now\n        , time = Generator.allDayRange { start = jun14, end = jun16 }\n        , summary = \"Q2 Team Offsite\"\n        }\n        |> Generator.withLocation \"Moscone Center, 747 Howard St, San Francisco, CA 94103\"\n\n","type":"String.String -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withName","comment":" Set the calendar display name.\n","type":"String.String -> Ical.Generator.Config -> Ical.Generator.Config"},{"name":"withOrganizer","comment":" Set the event organizer.\n","type":"Ical.Generator.Organizer -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withRecurrenceRule","comment":" Add a recurrence rule to the event.\n\n    Generator.event { ... }\n        |> Generator.withRecurrenceRule\n            (Generator.rule (Recurrence.Weekly { every = 1, weekStart = Time.Mon })\n                |> Generator.withCount 10\n            )\n\nIncompatible rule parts are dropped to match the event time shape. For\nexample, all-day events do not keep `BYHOUR`, `BYMINUTE`, or `BYSECOND`.\n\n","type":"Ical.Generator.Rule -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withStatus","comment":" Set the event status. Uses the shared [`Status`](Ical#Status) type.\n","type":"Ical.Status -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withTransparency","comment":" Set the event transparency. Uses the shared [`Transparency`](Ical#Transparency) type.\n","type":"Ical.Transparency -> Ical.Generator.Event -> Ical.Generator.Event"},{"name":"withUntilDate","comment":" Set the recurrence end to a specific date.\n","type":"Date.Date -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withUntilDateTime","comment":" Set the recurrence end to a specific date-time.\n","type":"Time.Posix -> Ical.Generator.Rule -> Ical.Generator.Rule"},{"name":"withUrl","comment":" Set the calendar URL.\n","type":"String.String -> Ical.Generator.Config -> Ical.Generator.Config"}],"binops":[]},{"name":"Ical.Parser","comment":" Parse iCal ([RFC 5545](https://datatracker.ietf.org/doc/html/rfc5545)) calendar strings\ninto typed Elm data.\n\n    import Date\n    import Ical.Parser as Parser\n\n    holidayFeedToString : String -> String\n    holidayFeedToString icsString =\n        case Parser.parse icsString of\n            Ok cal ->\n                cal.events\n                    |> List.filterMap toHoliday\n                    |> List.sortBy\n                        (.date >> Date.toRataDie)\n                    |> List.map\n                        (\\h ->\n                            Date.format \"EEE, MMM d\" h.date\n                                ++ \" - \"\n                                ++ h.name\n                        )\n                    |> String.join \"\\n\"\n\n            Err err ->\n                \"Parse error: \" ++ err\n\n    toHoliday :\n        Parser.Event\n        -> Maybe { name : String, date : Date.Date }\n    toHoliday event =\n        case ( event.summary, event.time ) of\n            ( Just name, Parser.AllDay { start } ) ->\n                Just { name = name, date = start }\n\n            _ ->\n                Nothing\n\n    -- holidayFeedToString usHolidaysFeed\n    --\n    --   Thu, Jan 1 - New Year's Day\n    --   Mon, Jan 19 - MLK Day\n    --   ...\n\nSee the [`examples/` folder](https://github.com/dillonkearns/elm-ical/tree/main/examples)\nfor a full runnable script that fetches and parses a live Google Calendar feed.\n\nParsing is strict: malformed content lines, invalid dates and times, bad\n`RRULE` values, and a `TZID` without a matching `VTIMEZONE` all return `Err`.\nParsed types are transparent record aliases so you can read fields directly.\n\n\n## Parsing\n\n@docs parse\n@docs Calendar, Event\n\n\n## Event times\n\n@docs EventTime, OccurrenceReference, ResolvedTime, LocalDateTime, TimeZoneContext\n\n\n## Enums and metadata\n\n@docs Organizer, RawProperty\n@docs Attendee, AttendeeRole, ParticipationStatus\n\n\n## Alarms\n\n@docs Alarm, AlarmAction, AlarmTrigger, AlarmTriggerRelative\n\n\n## Journals\n\n@docs Journal, JournalTime\n\n\n## Recurrence expansion\n\n@docs Occurrence, expand, expandNext\n\n","unions":[{"name":"AlarmAction","comment":" The type of alarm.\n","args":[],"cases":[["Display",[]],["Audio",[]]]},{"name":"AlarmTrigger","comment":" When the alarm fires.\n\n  - `TriggerDuration` — a relative offset from the event start or end.\n  - `TriggerAbsolute` — a fixed UTC time (used with `VALUE=DATE-TIME`).\n\n","args":[],"cases":[["TriggerDuration",["Ical.Parser.AlarmTriggerRelative"]],["TriggerAbsolute",["Time.Posix"]]]},{"name":"AlarmTriggerRelative","comment":" A relative alarm trigger as a signed offset in seconds.\nNegative values mean before, positive values mean after.\n\n    -- 15 minutes before start\n    SecondsFromStart (-15 * 60)\n\n    -- at the moment the event ends\n    SecondsFromEnd 0\n\n","args":[],"cases":[["SecondsFromStart",["Basics.Int"]],["SecondsFromEnd",["Basics.Int"]]]},{"name":"AttendeeRole","comment":" Attendee role per\n[RFC 5545 Section 3.2.16](https://datatracker.ietf.org/doc/html/rfc5545#section-3.2.16).\n","args":[],"cases":[["Chair",[]],["Required",[]],["Optional",[]],["NonParticipant",[]]]},{"name":"EventTime","comment":" The time span of an event. The variant determines what type of values\n`start` and `end` carry, enforcing the\n[RFC 5545](https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.2.2)\nrequirement that DTSTART and DTEND share the same value type.\n\nThe `end` is always populated. When neither DTEND nor DURATION is present in\nthe source data, the parser applies the RFC 5545 default: DATE events end on\nthe following day, and DATE-TIME events end at the same instant they start.\n\n  - `AllDay`: `VALUE=DATE`; the event spans whole days.\n  - `WithTime`: a resolved instant in time (UTC or TZID resolved via VTIMEZONE).\n  - `FloatingTime`: a local date-time with no timezone; interpreted in the\n    viewer's local time.\n\n","args":[],"cases":[["AllDay",["{ start : Date.Date, end : Date.Date }"]],["WithTime",["{ start : Ical.Parser.ResolvedTime, end : Ical.Parser.ResolvedTime }"]],["FloatingTime",["{ start : Ical.Parser.LocalDateTime, end : Ical.Parser.LocalDateTime }"]]]},{"name":"JournalTime","comment":" The time of a journal entry. Since journals have no time span (no DTEND\nor DURATION), this is a single point — either a date or a datetime.\n","args":[],"cases":[["JournalDate",["Date.Date"]],["JournalDateTime",["Ical.Parser.ResolvedTime"]],["JournalFloatingTime",["Ical.Parser.LocalDateTime"]]]},{"name":"OccurrenceReference","comment":" A typed reference to a specific recurrence instance as used by `EXDATE`,\n`RDATE`, and `RECURRENCE-ID`.\n\nThe constructor matches the value type from the iCalendar data:\n\n  - `OnDate` for `VALUE=DATE`\n  - `AtTime` for resolved `DATE-TIME` values (UTC or TZID-backed)\n  - `AtFloatingTime` for floating local `DATE-TIME` values\n\n","args":[],"cases":[["OnDate",["Date.Date"]],["AtTime",["Ical.Parser.ResolvedTime"]],["AtFloatingTime",["Ical.Parser.LocalDateTime"]]]},{"name":"ParticipationStatus","comment":" Attendee participation status per\n[RFC 5545 Section 3.2.12](https://datatracker.ietf.org/doc/html/rfc5545#section-3.2.12).\n","args":[],"cases":[["NeedsAction",[]],["Accepted",[]],["Declined",[]],["TentativeParticipation",[]],["Delegated",[]]]},{"name":"TimeZoneContext","comment":" Opaque timezone data retained for parsed TZID date-times so recurrence\nexpansion can resolve future local wall-clock occurrences correctly.\n\nMost code will only need [`ResolvedTime.posix`](#ResolvedTime) and\n[`ResolvedTime.timeZoneName`](#ResolvedTime).\n\n","args":[],"cases":[]}],"aliases":[{"name":"Alarm","comment":" A parsed alarm (VALARM) attached to an event.\n\nEach alarm has an `action` (`Display` or `Audio`), a `trigger` (when the alarm\nfires), and an optional `description`.\n\n    event.alarms\n        |> List.map .trigger\n        -- [ TriggerDuration (SecondsFromStart (-900)), ... ]\n\n","args":[],"type":"{ action : Ical.Parser.AlarmAction, trigger : Ical.Parser.AlarmTrigger, description : Maybe.Maybe String.String }"},{"name":"Attendee","comment":" A parsed ATTENDEE property.\n","args":[],"type":"{ email : String.String, name : Maybe.Maybe String.String, role : Ical.Parser.AttendeeRole, participationStatus : Ical.Parser.ParticipationStatus, rsvp : Basics.Bool }"},{"name":"Calendar","comment":" A parsed iCal calendar. Access fields directly:\n\n    case Parser.parse icsString of\n        Ok cal ->\n            List.length cal.events\n\n        Err err ->\n            0\n\n","args":[],"type":"{ generatorProductId : String.String, specVersion : String.String, events : List.List Ical.Parser.Event, journals : List.List Ical.Parser.Journal, extraProperties : List.List Ical.Parser.RawProperty }"},{"name":"Event","comment":" A parsed iCal event.\n\nThe `uid`, `stamp`, and `time` fields are required by\n[RFC 5545 Section 3.6.1](https://datatracker.ietf.org/doc/html/rfc5545#section-3.6.1).\nParsing will fail if DTSTART is missing from a VEVENT.\n\nThe `end` inside `time` is always populated — from DTEND, DURATION (which are\n[mutually exclusive](https://datatracker.ietf.org/doc/html/rfc5545#section-3.6.1)\nper the spec), or the RFC default when neither is present:\n\n  - DATE events default to ending on the following date\n  - DATE-TIME events default to ending at the same instant they start\n\n","args":[],"type":"{ uid : String.String, stamp : Time.Posix, time : Ical.Parser.EventTime, created : Maybe.Maybe Time.Posix, lastModified : Maybe.Maybe Time.Posix, summary : Maybe.Maybe String.String, description : Maybe.Maybe String.String, location : Maybe.Maybe String.String, organizer : Maybe.Maybe Ical.Parser.Organizer, status : Maybe.Maybe Ical.Status, transparency : Maybe.Maybe Ical.Transparency, recurrenceRules : List.List Ical.Recurrence.RecurrenceRule, exclusions : List.List Ical.Parser.OccurrenceReference, recurrenceDates : List.List Ical.Parser.OccurrenceReference, recurrenceId : Maybe.Maybe Ical.Parser.OccurrenceReference, attendees : List.List Ical.Parser.Attendee, alarms : List.List Ical.Parser.Alarm, extraProperties : List.List Ical.Parser.RawProperty }"},{"name":"Journal","comment":" A parsed iCal journal entry\n([RFC 5545 Section 3.6.3](https://datatracker.ietf.org/doc/html/rfc5545#section-3.6.3)).\nUnlike events, journals have no time span — just an optional date or datetime\nstamp and text content. They represent dated notes or log entries.\n","args":[],"type":"{ uid : String.String, stamp : Time.Posix, time : Maybe.Maybe Ical.Parser.JournalTime, summary : Maybe.Maybe String.String, description : Maybe.Maybe String.String, status : Maybe.Maybe Ical.JournalStatus, created : Maybe.Maybe Time.Posix, lastModified : Maybe.Maybe Time.Posix, organizer : Maybe.Maybe Ical.Parser.Organizer, extraProperties : List.List Ical.Parser.RawProperty }"},{"name":"LocalDateTime","comment":" A date-time without timezone information. Represents a \"floating\" local\ndate-time that is interpreted in the viewer's local time.\n","args":[],"type":"{ year : Basics.Int, month : Time.Month, day : Basics.Int, hour : Basics.Int, minute : Basics.Int, second : Basics.Int }"},{"name":"Occurrence","comment":" A single occurrence of an event. For non-recurring events, there is one\noccurrence whose `time` matches `event.time`. For recurring events, each\noccurrence has its own `time` shifted to the recurrence date while preserving\nthe original event's duration.\n","args":[],"type":"{ event : Ical.Parser.Event, time : Ical.Parser.EventTime }"},{"name":"Organizer","comment":" A parsed ORGANIZER property.\n","args":[],"type":"{ email : String.String, name : Maybe.Maybe String.String }"},{"name":"RawProperty","comment":" An uninterpreted property: name, parameters, and raw value string.\nUnknown properties and extension properties (`X-*`) are preserved here.\n","args":[],"type":"{ name : String.String, parameters : List.List ( String.String, String.String ), value : String.String }"},{"name":"ResolvedTime","comment":" A resolved date-time instant.\n\nThe `timeZoneName` is `Nothing` for UTC datetimes, or a\n[IANA Time Zone Database](https://www.iana.org/time-zones) name\n(e.g. `Just \"America/New_York\"`) for TZID-resolved datetimes.\n\nFor TZID values, `localDateTime` retains the original wall-clock datetime and\n`timeZoneContext` keeps the parsed timezone definition so recurrence expansion\ncan stay in local calendar dates. Most consumers can ignore those fields and\njust use `posix`.\n\n","args":[],"type":"{ posix : Time.Posix, timeZoneName : Maybe.Maybe String.String, localDateTime : Maybe.Maybe Ical.Parser.LocalDateTime, timeZoneContext : Maybe.Maybe Ical.Parser.TimeZoneContext }"}],"values":[{"name":"expand","comment":" Expand events into concrete occurrences within a date range, merging\nRECURRENCE-ID overrides automatically. Override events (those with a\n`recurrenceId`) replace the matching occurrence from the master event that\nshares their `uid`.\n\n    case Parser.parse icsString of\n        Ok cal ->\n            Parser.expand { start = jan1, end = dec31 } cal.events\n\n        Err err ->\n            []\n\nFor a single event, wrap it in a list:\n\n    Parser.expand { start = jan1, end = dec31 } [ event ]\n\n","type":"{ start : Date.Date, end : Date.Date } -> List.List Ical.Parser.Event -> List.List Ical.Parser.Occurrence"},{"name":"expandNext","comment":" Get the next N occurrences starting from a given date, merging\nRECURRENCE-ID overrides automatically.\n\n    case Parser.parse icsString of\n        Ok cal ->\n            Parser.expandNext 10 today cal.events\n\n        Err err ->\n            []\n\nFor a single event, wrap it in a list:\n\n    Parser.expandNext 5 today [ event ]\n\n","type":"Basics.Int -> Date.Date -> List.List Ical.Parser.Event -> List.List Ical.Parser.Occurrence"},{"name":"parse","comment":" Parse an iCal string into a Calendar.\n\n    Ical.Parser.parse icsString\n    --> Ok { generatorProductId = \"-//My App//EN\", specVersion = \"2.0\", events = [...], ... }\n\n","type":"String.String -> Result.Result String.String Ical.Parser.Calendar"}],"binops":[]},{"name":"Ical.Recurrence","comment":" Types for iCal recurrence rules\n([RFC 5545 Section 3.3.10](https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10)).\n\n[`RecurrenceRule`](#RecurrenceRule) is the transparent record returned by\n[`Ical.Parser`](Ical-Parser) for reading parsed recurrence data.\n[`Frequency`](#Frequency) and [`DaySpec`](#DaySpec) are also used when\nbuilding rules for generation via [`Ical.Generator.Rule`](Ical-Generator#Rule).\n\n\n## Parsed rule data\n\n@docs RecurrenceRule, RecurrenceEnd\n\n\n## Shared types\n\n@docs Frequency, DaySpec, every, nth, weekday, ordinal\n@docs first, second, third, fourth, fifth\n@docs last, secondToLast, thirdToLast, fourthToLast, fifthToLast\n\n","unions":[{"name":"DaySpec","comment":" A day-of-week specifier for recurrence rules.\n\nCreate one with [`every`](#every), [`nth`](#nth), or the convenience helpers\nlike [`second`](#second) and [`last`](#last).\n\n    -- every Monday\n    every Time.Mon\n\n    -- the 2nd Sunday of the month\n    second Time.Sun\n\n    -- the last Friday\n    last Time.Fri\n\nPositive ordinals count from the start of the period. Negative ordinals count\nfrom the end. `nth` accepts `-53..-1` and `1..53`, matching the RFC grammar\nfor numeric `BYDAY` values.\n\n","args":[],"cases":[]},{"name":"Frequency","comment":" How often the event recurs. Each variant carries its own configuration:\n\n  - `every` — the interval between occurrences (e.g. `every = 2` with `Weekly`\n    means every other week). Must be at least 1.\n  - `weekStart` — which day begins the week (only meaningful for `Weekly`).\n\n","args":[],"cases":[["Secondly",["{ every : Basics.Int }"]],["Minutely",["{ every : Basics.Int }"]],["Hourly",["{ every : Basics.Int }"]],["Daily",["{ every : Basics.Int }"]],["Weekly",["{ every : Basics.Int, weekStart : Time.Weekday }"]],["Monthly",["{ every : Basics.Int }"]],["Yearly",["{ every : Basics.Int }"]]]},{"name":"RecurrenceEnd","comment":" When the recurrence stops. `Count` and `Until*` are mutually exclusive per\n[RFC 5545 Section 3.3.10](https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10).\n","args":[],"cases":[["Forever",[]],["Count",["Basics.Int"]],["UntilDate",["Date.Date"]],["UntilDateTime",["Time.Posix"]]]}],"aliases":[{"name":"RecurrenceRule","comment":" A parsed recurrence rule (RRULE). This is the transparent record returned\nby [`Ical.Parser`](Ical-Parser) for reading parsed rule data. For constructing\nrules for generation, use [`Ical.Generator.Rule`](Ical-Generator#Rule) and its builder functions.\n\n    { frequency = Weekly { every = 1, weekStart = Time.Mon }\n    , end = Forever\n    , byDay = [ every Time.Mon ]\n    , byMonthDay = []\n    , byMonth = []\n    , bySetPos = []\n    , byHour = []\n    , byMinute = []\n    , bySecond = []\n    , byYearDay = []\n    , byWeekNo = []\n    }\n\n  - `byDay` — which days of the week (with optional ordinals for monthly/yearly).\n  - `byMonthDay` — which days of the month (1–31, or -31 to -1 from month end).\n  - `byMonth` — which months.\n  - `bySetPos` — pick the Nth result from the set produced by the other `by*`\n    parts within each frequency period. Positive counts from the start, negative\n    from the end. For example, `BYDAY=MO,TU,WE,TH,FR` with `bySetPos = [ -1 ]`\n    means \"the last weekday\" of each period.\n  - `byHour` — which hours (0–23).\n  - `byMinute` — which minutes (0–59).\n  - `bySecond` — which seconds (0–60, 60 for leap second).\n  - `byYearDay` — which days of the year (1–366, or -366 to -1 from year end).\n  - `byWeekNo` — which ISO week numbers (1–53, or -53 to -1 from year end).\n\n","args":[],"type":"{ frequency : Ical.Recurrence.Frequency, end : Ical.Recurrence.RecurrenceEnd, byDay : List.List Ical.Recurrence.DaySpec, byMonthDay : List.List Basics.Int, byMonth : List.List Time.Month, bySetPos : List.List Basics.Int, byHour : List.List Basics.Int, byMinute : List.List Basics.Int, bySecond : List.List Basics.Int, byYearDay : List.List Basics.Int, byWeekNo : List.List Basics.Int }"}],"values":[{"name":"every","comment":" Match every instance of the given weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"fifth","comment":" The 5th instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"fifthToLast","comment":" The 5th-to-last instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"first","comment":" The 1st instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"fourth","comment":" The 4th instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"fourthToLast","comment":" The 4th-to-last instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"last","comment":" The last instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"nth","comment":" Match the `n`th instance of a weekday.\n\nPositive values count from the start, negative values count from the end, and\n`0` is invalid.\n\n    nth 20 Time.Mon\n\n    nth -1 Time.Fri\n\n","type":"Basics.Int -> Time.Weekday -> Maybe.Maybe Ical.Recurrence.DaySpec"},{"name":"ordinal","comment":" Extract the ordinal from a `DaySpec`, if present.\n","type":"Ical.Recurrence.DaySpec -> Maybe.Maybe Basics.Int"},{"name":"second","comment":" The 2nd instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"secondToLast","comment":" The 2nd-to-last instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"third","comment":" The 3rd instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"thirdToLast","comment":" The 3rd-to-last instance of a weekday.\n","type":"Time.Weekday -> Ical.Recurrence.DaySpec"},{"name":"weekday","comment":" Extract the weekday from a `DaySpec`.\n","type":"Ical.Recurrence.DaySpec -> Time.Weekday"}],"binops":[]}]