;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Defined in RFC5234

ALPHA          =  %x41-5A / %x61-7A   ; A-Z / a-z

BIT            =  "0" / "1"

CHAR           =  %x01-7F
                       ; any 7-bit US-ASCII character,
                       ;  excluding NUL

CR             =  %x0D
                       ; carriage return

CRLF           =  CR LF
                       ; Internet standard newline

CTL            =  %x00-1F / %x7F
                       ; controls

DIGIT          =  %x30-39
                       ; 0-9

DQUOTE         =  %x22
                       ; " (Double Quote)

HEXDIG         =  DIGIT / "A" / "B" / "C" / "D" / "E" / "F"

HTAB           =  %x09
                       ; horizontal tab

LF             =  %x0A
                       ; linefeed

LWSP           =  *(WSP / CRLF WSP)
                       ; Use of this linear-white-space rule
                       ;  permits lines containing only white
                       ;  space that are no longer legal in
                       ;  mail headers and have caused
                       ;  interoperability problems in other
                       ;  contexts.
                       ; Do not use when defining mail
                       ;  headers and use with caution in
                       ;  other contexts.

OCTET          =  %x00-FF
                       ; 8 bits of data

SP             =  %x20

VCHAR          =  %x21-7E
                       ; visible (printing) characters

WSP            =  SP / HTAB
                       ; white space


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Defined in RFC3629

UTF8-octets = *( UTF8-char )
UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
UTF8-1      = %x00-7F
UTF8-2      = %xC2-DF UTF8-tail
UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
              %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
              %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail   = %x80-BF


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Defined in RFC3986

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

hier-part   = "//" authority path-abempty
            / path-absolute
            / path-rootless
            / path-empty

scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )

authority   = [ userinfo "@" ] host [ ":" port ]

userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )

host        = IP-literal / IPv4address / reg-name

IP-literal = "[" ( IPv6address / IPvFuture  ) "]"

IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

IPv6address =                            6( h16 ":" ) ls32
            /                       "::" 5( h16 ":" ) ls32
            / [               h16 ] "::" 4( h16 ":" ) ls32
            / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
            / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
            / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
            / [ *4( h16 ":" ) h16 ] "::"              ls32
            / [ *5( h16 ":" ) h16 ] "::"              h16
            / [ *6( h16 ":" ) h16 ] "::"

ls32        = ( h16 ":" h16 ) / IPv4address
            ; least-significant 32 bits of address

h16         = 1*4HEXDIG
            ; 16 bits of address represented in hexadecimal

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

dec-octet   = DIGIT                 ; 0-9
            / %x31-39 DIGIT         ; 10-99
            / "1" 2DIGIT            ; 100-199
            / "2" %x30-34 DIGIT     ; 200-249
            / "25" %x30-35          ; 250-255

reg-name    = *( unreserved / pct-encoded / sub-delims )

port        = *DIGIT

path          = path-abempty    ; begins with "/" or is empty
              / path-absolute   ; begins with "/" but not "//"
              / path-noscheme   ; begins with a non-colon segment
              / path-rootless   ; begins with a segment
              / path-empty      ; zero characters

path-abempty  = *( "/" segment )
path-absolute = "/" [ segment-nz *( "/" segment ) ]
path-noscheme = segment-nz-nc *( "/" segment )
path-rootless = segment-nz *( "/" segment )
path-empty    = 0<pchar>

segment       = *pchar
segment-nz    = 1*pchar
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
              ; non-zero-length segment without any colon ":"

pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"

query       = *( pchar / "/" / "?" )

fragment    = *( pchar / "/" / "?" )


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Defined in RFC5545

contentline   = name *(";" param ) ":" value CRLF
; This ABNF is just a general definition for an initial parsing
; of the content line into its property name, parameter list,
; and value string

; When parsing a content line, folded lines MUST first
; be unfolded according to the unfolding procedure
; described above.  When generating a content line, lines
; longer than 75 octets SHOULD be folded according to
; the folding procedure described above.

name          = iana-token / x-name

iana-token    = 1*(ALPHA / DIGIT / "-")
; iCalendar identifier registered with IANA

x-name        = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-")
; Reserved for experimental use.

vendorid      = 3*(ALPHA / DIGIT)
; Vendor identification

param         = param-name "=" param-value *("," param-value)
; Each property defines the specific ABNF for the parameters
; allowed on the property.  Refer to specific properties for
; precise parameter ABNF.

param-name    = iana-token / x-name

param-value   = paramtext / quoted-string

paramtext     = *SAFE-CHAR

value         = *VALUE-CHAR

quoted-string = DQUOTE *QSAFE-CHAR DQUOTE

QSAFE-CHAR    = WSP / %x21 / %x23-7E / NON-US-ASCII
; Any character except CONTROL and DQUOTE

SAFE-CHAR     = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E
              / NON-US-ASCII
; Any character except CONTROL, DQUOTE, ";", ":", ","

VALUE-CHAR    = WSP / %x21-7E / NON-US-ASCII
; Any textual character

NON-US-ASCII  = UTF8-2 / UTF8-3 / UTF8-4
; UTF8-2, UTF8-3, and UTF8-4 are defined in [RFC3629]

CONTROL       = %x00-08 / %x0A-1F / %x7F
; All the controls except HTAB

icalparameter = altrepparam       ; Alternate text representation
              / cnparam           ; Common name
              / cutypeparam       ; Calendar user type
              / delfromparam      ; Delegator
              / deltoparam        ; Delegatee
              / dirparam          ; Directory entry
              / encodingparam     ; Inline encoding
              / fmttypeparam      ; Format type
              / fbtypeparam       ; Free/busy time type
              / languageparam     ; Language for text
              / memberparam       ; Group or list membership
              / partstatparam     ; Participation status
              / rangeparam        ; Recurrence identifier range
              / trigrelparam      ; Alarm trigger relationship
              / reltypeparam      ; Relationship type
              / roleparam         ; Participation role
              / rsvpparam         ; RSVP expectation
              / sentbyparam       ; Sent by
              / tzidparam         ; Reference to time zone object
              / valuetypeparam    ; Property value data type
              / other-param

other-param   = (iana-param / x-param)

iana-param  = iana-token "=" param-value *("," param-value)
; Some other IANA-registered iCalendar parameter.

x-param     = x-name "=" param-value *("," param-value)
; A non-standard, experimental parameter.

altrepparam = "ALTREP" "=" DQUOTE uri DQUOTE

cnparam    = "CN" "=" param-value

cutypeparam        = "CUTYPE" "="
                   ("INDIVIDUAL"   ; An individual
                  / "GROUP"        ; A group of individuals
                  / "RESOURCE"     ; A physical resource
                  / "ROOM"         ; A room resource
                  / "UNKNOWN"      ; Otherwise not known
                  / x-name         ; Experimental type
                  / iana-token)    ; Other IANA-registered
                                   ; type
; Default is INDIVIDUAL

delfromparam       = "DELEGATED-FROM" "=" DQUOTE cal-address
                      DQUOTE *("," DQUOTE cal-address DQUOTE)

deltoparam = "DELEGATED-TO" "=" DQUOTE cal-address DQUOTE
             *("," DQUOTE cal-address DQUOTE)

dirparam   = "DIR" "=" DQUOTE uri DQUOTE

encodingparam      = "ENCODING" "="
                   ( "8BIT"
   ; "8bit" text encoding is defined in [RFC2045]
                   / "BASE64"
   ; "BASE64" binary encoding format is defined in [RFC4648]
                   )

fmttypeparam = "FMTTYPE" "=" type-name "/" subtype-name
               ; Where "type-name" and "subtype-name" are
               ; defined in Section 4.2 of [RFC4288].

fbtypeparam        = "FBTYPE" "=" ("FREE" / "BUSY"
                   / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE"
                   / x-name
         ; Some experimental iCalendar free/busy type.
                   / iana-token)
         ; Some other IANA-registered iCalendar free/busy type.

languageparam = "LANGUAGE" "=" language

language = Language-Tag
           ; As defined in [RFC5646].

memberparam        = "MEMBER" "=" DQUOTE cal-address DQUOTE
                     *("," DQUOTE cal-address DQUOTE)

partstatparam    = "PARTSTAT" "="
                  (partstat-event
                 / partstat-todo
                 / partstat-jour)

partstat-event   = ("NEEDS-ACTION"    ; Event needs action
                 / "ACCEPTED"         ; Event accepted
                 / "DECLINED"         ; Event declined
                 / "TENTATIVE"        ; Event tentatively
                                      ; accepted
                 / "DELEGATED"        ; Event delegated
                 / x-name             ; Experimental status
                 / iana-token)        ; Other IANA-registered
                                      ; status
; These are the participation statuses for a "VEVENT".
; Default is NEEDS-ACTION.

partstat-todo    = ("NEEDS-ACTION"    ; To-do needs action
                 / "ACCEPTED"         ; To-do accepted
                 / "DECLINED"         ; To-do declined
                 / "TENTATIVE"        ; To-do tentatively
                                      ; accepted
                 / "DELEGATED"        ; To-do delegated
                 / "COMPLETED"        ; To-do completed
                                      ; COMPLETED property has
                                      ; DATE-TIME completed
                 / "IN-PROCESS"       ; To-do in process of
                                      ; being completed
                 / x-name             ; Experimental status
                 / iana-token)        ; Other IANA-registered
                                      ; status
; These are the participation statuses for a "VTODO".
; Default is NEEDS-ACTION.

partstat-jour    = ("NEEDS-ACTION"    ; Journal needs action
                 / "ACCEPTED"         ; Journal accepted
                 / "DECLINED"         ; Journal declined
                 / x-name             ; Experimental status
                 / iana-token)        ; Other IANA-registered
                                      ; status
; These are the participation statuses for a "VJOURNAL".
; Default is NEEDS-ACTION.

rangeparam = "RANGE" "=" "THISANDFUTURE"
; To specify the instance specified by the recurrence identifier
; and all subsequent recurrence instances.

trigrelparam       = "RELATED" "="
                    ("START"       ; Trigger off of start
                   / "END")        ; Trigger off of end

reltypeparam       = "RELTYPE" "="
                    ("PARENT"    ; Parent relationship - Default
                   / "CHILD"     ; Child relationship
                   / "SIBLING"   ; Sibling relationship
                   / iana-token  ; Some other IANA-registered
                                 ; iCalendar relationship type
                   / x-name)     ; A non-standard, experimental
                                 ; relationship type

roleparam  = "ROLE" "="
            ("CHAIR"             ; Indicates chair of the
                                 ; calendar entity
           / "REQ-PARTICIPANT"   ; Indicates a participant whose
                                 ; participation is required
           / "OPT-PARTICIPANT"   ; Indicates a participant whose
                                 ; participation is optional
           / "NON-PARTICIPANT"   ; Indicates a participant who
                                 ; is copied for information
                                 ; purposes only
           / x-name              ; Experimental role
           / iana-token)         ; Other IANA role
; Default is REQ-PARTICIPANT

rsvpparam = "RSVP" "=" ("TRUE" / "FALSE")
; Default is FALSE

sentbyparam        = "SENT-BY" "=" DQUOTE cal-address DQUOTE

tzidparam  = "TZID" "=" [tzidprefix] paramtext

tzidprefix = "/"

valuetypeparam = "VALUE" "=" valuetype

valuetype  = ("BINARY"
           / "BOOLEAN"
           / "CAL-ADDRESS"
           / "DATE"
           / "DATE-TIME"
           / "DURATION"
           / "FLOAT"
           / "INTEGER"
           / "PERIOD"
           / "RECUR"
           / "TEXT"
           / "TIME"
           / "URI"
           / "UTC-OFFSET"
           / x-name
           ; Some experimental iCalendar value type.
           / iana-token)
           ; Some other IANA-registered iCalendar value type.

binary     = *(4b-char) [b-end]
; A "BASE64" encoded character string, as defined by [RFC4648].

b-end      = (2b-char "==") / (3b-char "=")

b-char = ALPHA / DIGIT / "+" / "/"

boolean    = "TRUE" / "FALSE"

cal-address        = uri

date               = date-value

date-value         = date-fullyear date-month date-mday
date-fullyear      = 4DIGIT
date-month         = 2DIGIT        ;01-12
date-mday          = 2DIGIT        ;01-28, 01-29, 01-30, 01-31
                                   ;based on month/year

date-time  = date "T" time ;As specified in the DATE and TIME
                           ;value definitions

dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)

dur-date   = dur-day [dur-time]
dur-time   = "T" (dur-hour / dur-minute / dur-second)
dur-week   = 1*DIGIT "W"
dur-hour   = 1*DIGIT "H" [dur-minute]
dur-minute = 1*DIGIT "M" [dur-second]
dur-second = 1*DIGIT "S"
dur-day    = 1*DIGIT "D"

float      = (["+"] / "-") 1*DIGIT ["." 1*DIGIT]

integer    = (["+"] / "-") 1*DIGIT

period     = period-explicit / period-start

period-explicit = date-time "/" date-time
; [ISO.8601.2004] complete representation basic format for a
; period of time consisting of a start and end.  The start MUST
; be before the end.

period-start = date-time "/" dur-value
; [ISO.8601.2004] complete representation basic format for a
; period of time consisting of a start and positive duration
; of time.

recur           = recur-rule-part *( ";" recur-rule-part )
                ;
                ; The rule parts are not ordered in any
                ; particular sequence.
                ;
                ; The FREQ rule part is REQUIRED,
                ; but MUST NOT occur more than once.
                ;
                ; The UNTIL or COUNT rule parts are OPTIONAL,
                ; but they MUST NOT occur in the same 'recur'.
                ;
                ; The other rule parts are OPTIONAL,
                ; but MUST NOT occur more than once.

recur-rule-part = ( "FREQ" "=" freq )
                / ( "UNTIL" "=" enddate )
                / ( "COUNT" "=" 1*DIGIT )
                / ( "INTERVAL" "=" 1*DIGIT )
                / ( "BYSECOND" "=" byseclist )
                / ( "BYMINUTE" "=" byminlist )
                / ( "BYHOUR" "=" byhrlist )
                / ( "BYDAY" "=" bywdaylist )
                / ( "BYMONTHDAY" "=" bymodaylist )
                / ( "BYYEARDAY" "=" byyrdaylist )
                / ( "BYWEEKNO" "=" bywknolist )
                / ( "BYMONTH" "=" bymolist )
                / ( "BYSETPOS" "=" bysplist )
                / ( "WKST" "=" weekday )

freq        = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY"
            / "WEEKLY" / "MONTHLY" / "YEARLY"

enddate     = date / date-time

byseclist   = ( seconds *("," seconds) )

seconds     = 1*2DIGIT       ;0 to 60

byminlist   = ( minutes *("," minutes) )

minutes     = 1*2DIGIT       ;0 to 59

byhrlist    = ( hour *("," hour) )

hour        = 1*2DIGIT       ;0 to 23

bywdaylist  = ( weekdaynum *("," weekdaynum) )

weekdaynum  = [[plus / minus] ordwk] weekday

plus        = "+"

minus       = "-"

ordwk       = 1*2DIGIT       ;1 to 53

weekday     = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
;FRIDAY, and SATURDAY days of the week.

bymodaylist = ( monthdaynum *("," monthdaynum) )

monthdaynum = [plus / minus] ordmoday

ordmoday    = 1*2DIGIT       ;1 to 31

byyrdaylist = ( yeardaynum *("," yeardaynum) )

yeardaynum  = [plus / minus] ordyrday

ordyrday    = 1*3DIGIT      ;1 to 366

bywknolist  = ( weeknum *("," weeknum) )

weeknum     = [plus / minus] ordwk

bymolist    = ( monthnum *("," monthnum) )

monthnum    = 1*2DIGIT       ;1 to 12

bysplist    = ( setposday *("," setposday) )

setposday   = yeardaynum

text       = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR)
   ; Folded according to description above

ESCAPED-CHAR = ("\\" / "\;" / "\," / "\N" / "\n")
   ; \\ encodes \, \N or \n encodes newline
   ; \; encodes ;, \, encodes ,

TSAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-5B /
             %x5D-7E / NON-US-ASCII
   ; Any character except CONTROLs not needed by the current
   ; character set, DQUOTE, ";", ":", "\", ","

time         = time-hour time-minute time-second [time-utc]

time-hour    = 2DIGIT        ;00-23
time-minute  = 2DIGIT        ;00-59
time-second  = 2DIGIT        ;00-60
;The "60" value is used to account for positive "leap" seconds.

time-utc     = "Z"

;; FIXME: Was a placeholder in specification
;; uri = <As defined in Section 3 of [RFC3986]>
uri = URI

utc-offset = time-numzone

time-numzone = ("+" / "-") time-hour time-minute [time-second]

icalstream = 1*icalobject

icalobject = "BEGIN" ":" "VCALENDAR" CRLF
             icalbody
;            "END" ":" "VCALENDAR" CRLF

icalbody   = calprops ; component

calprops   = *(
           ;
           ; The following are REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           prodid / version /
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           calscale / method /
           ;
           ; The following are OPTIONAL,
           ; and MAY occur more than once.
           ;
           x-prop / iana-prop
           ;
           )

component  = 1*(eventc / todoc / journalc / freebusyc /
             timezonec / iana-comp / x-comp)

iana-comp  = "BEGIN" ":" iana-token CRLF
             1*contentline
             "END" ":" iana-token CRLF

x-comp     = "BEGIN" ":" x-name CRLF
             1*contentline
             "END" ":" x-name CRLF

eventc     = "BEGIN" ":" "VEVENT" CRLF
             eventprop *alarmc
             "END" ":" "VEVENT" CRLF

eventprop  = *(
           ;
           ; The following are REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           dtstamp / uid /
           ;
           ; The following is REQUIRED if the component
           ; appears in an iCalendar object that doesn't
           ; specify the "METHOD" property; otherwise, it
           ; is OPTIONAL; in any case, it MUST NOT occur
           ; more than once.
           ;
           dtstart /
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           class / created / description / geo /
           last-mod / location / organizer / priority /
           seq / status / summary / transp /
           url / recurid /
           ;
           ; The following is OPTIONAL,
           ; but SHOULD NOT occur more than once.
           ;
           rrule /
           ;
           ; Either 'dtend' or 'duration' MAY appear in
           ; a 'eventprop', but 'dtend' and 'duration'
           ; MUST NOT occur in the same 'eventprop'.
           ;
           dtend / duration /
           ;
           ; The following are OPTIONAL,
           ; and MAY occur more than once.
           ;
           attach / attendee / categories / comment /
           contact / exdate / rstatus / related /
           resources / rdate / x-prop / iana-prop
           ;
           )

todoc      = "BEGIN" ":" "VTODO" CRLF
             todoprop *alarmc
             "END" ":" "VTODO" CRLF

todoprop   = *(
           ;
           ; The following are REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           dtstamp / uid /
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           class / completed / created / description /
           dtstart / geo / last-mod / location / organizer /
           percent / priority / recurid / seq / status /
           summary / url /
           ;
           ; The following is OPTIONAL,
           ; but SHOULD NOT occur more than once.
           ;
           rrule /
           ;
           ; Either 'due' or 'duration' MAY appear in
           ; a 'todoprop', but 'due' and 'duration'
           ; MUST NOT occur in the same 'todoprop'.
           ; If 'duration' appear in a 'todoprop',
           ; then 'dtstart' MUST also appear in
           ; the same 'todoprop'.
           ;
           due / duration /
           ;
           ; The following are OPTIONAL,
           ; and MAY occur more than once.
           ;
           attach / attendee / categories / comment / contact /
           exdate / rstatus / related / resources /
           rdate / x-prop / iana-prop
           ;
           )

journalc   = "BEGIN" ":" "VJOURNAL" CRLF
             jourprop
             "END" ":" "VJOURNAL" CRLF

jourprop   = *(
           ;
           ; The following are REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           dtstamp / uid /
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           class / created / dtstart /
           last-mod / organizer / recurid / seq /
           status / summary / url /
           ;
           ; The following is OPTIONAL,
           ; but SHOULD NOT occur more than once.
           ;
           rrule /
           ;
           ; The following are OPTIONAL,
           ; and MAY occur more than once.
           ;
           attach / attendee / categories / comment /
           contact / description / exdate / related / rdate /
           rstatus / x-prop / iana-prop
           ;
           )

freebusyc  = "BEGIN" ":" "VFREEBUSY" CRLF
             fbprop
             "END" ":" "VFREEBUSY" CRLF

fbprop     = *(
           ;
           ; The following are REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           dtstamp / uid /
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           contact / dtstart / dtend /
           organizer / url /
           ;
           ; The following are OPTIONAL,
           ; and MAY occur more than once.
           ;
           attendee / comment / freebusy / rstatus / x-prop /
           iana-prop
           ;
           )

timezonec  = "BEGIN" ":" "VTIMEZONE" CRLF
             *(
             ;
             ; 'tzid' is REQUIRED, but MUST NOT occur more
             ; than once.
             ;
             tzid /
             ;
             ; 'last-mod' and 'tzurl' are OPTIONAL,
             ; but MUST NOT occur more than once.
             ;
             last-mod / tzurl /
             ;
             ; One of 'standardc' or 'daylightc' MUST occur
             ; and each MAY occur more than once.
             ;
             standardc / daylightc /
             ;
             ; The following are OPTIONAL,
             ; and MAY occur more than once.
             ;
             x-prop / iana-prop
             ;
             )
             "END" ":" "VTIMEZONE" CRLF

standardc  = "BEGIN" ":" "STANDARD" CRLF
             tzprop
             "END" ":" "STANDARD" CRLF

daylightc  = "BEGIN" ":" "DAYLIGHT" CRLF
             tzprop
             "END" ":" "DAYLIGHT" CRLF

tzprop     = *(
             ;
             ; The following are REQUIRED,
             ; but MUST NOT occur more than once.
             ;
             dtstart / tzoffsetto / tzoffsetfrom /
             ;
             ; The following is OPTIONAL,
             ; but SHOULD NOT occur more than once.
             ;
             rrule /
             ;
             ; The following are OPTIONAL,
             ; and MAY occur more than once.
             ;
             comment / rdate / tzname / x-prop / iana-prop
             ;
             )

alarmc     = "BEGIN" ":" "VALARM" CRLF
             (audioprop / dispprop / emailprop)
             "END" ":" "VALARM" CRLF

audioprop  = *(
           ;
           ; 'action' and 'trigger' are both REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           action / trigger /
           ;
           ; 'duration' and 'repeat' are both OPTIONAL,
           ; and MUST NOT occur more than once each;
           ; but if one occurs, so MUST the other.
           ;
           duration / repeat /
           ;
           ; The following is OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           attach /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           x-prop / iana-prop
           ;
           )

dispprop   = *(
           ;
           ; The following are REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           action / description / trigger /
           ;
           ; 'duration' and 'repeat' are both OPTIONAL,
           ; and MUST NOT occur more than once each;
           ; but if one occurs, so MUST the other.
           ;
           duration / repeat /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           x-prop / iana-prop
           ;
           )

emailprop  = *(
           ;
           ; The following are all REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           action / description / trigger / summary /
           ;
           ; The following is REQUIRED,
           ; and MAY occur more than once.
           ;
           attendee /
           ;
           ; 'duration' and 'repeat' are both OPTIONAL,
           ; and MUST NOT occur more than once each;
           ; but if one occurs, so MUST the other.
           ;
           duration / repeat /
           ;
           ; The following are OPTIONAL,
           ; and MAY occur more than once.
           ;
           attach / x-prop / iana-prop
           ;
           )

calscale   = "CALSCALE" calparam ":" calvalue CRLF

calparam   = *(";" other-param)

calvalue   = "GREGORIAN"

method     = "METHOD" metparam ":" metvalue CRLF

metparam   = *(";" other-param)

metvalue   = iana-token

prodid     = "PRODID" pidparam ":" pidvalue CRLF

pidparam   = *(";" other-param)

pidvalue   = text
;Any text that describes the product and version
;and that is generally assured of being unique.

version    = "VERSION" verparam ":" vervalue CRLF

verparam   = *(";" other-param)

;; FIXME: Not sure what minver or maxver we can use
;;
;;  vervalue   = "2.0"         ;This memo
;;             / maxver
;;             / (minver ";" maxver)
;;
;;  minver     = <A IANA-registered iCalendar version identifier>
;;  ;Minimum iCalendar version needed to parse the iCalendar object.
;;
;;  maxver     = <A IANA-registered iCalendar version identifier>
;;  ;Maximum iCalendar version needed to parse the iCalendar object.
vervalue   = "2.0"

attach     = "ATTACH" attachparam ( ":" uri ) /
             (
               ";" "ENCODING" "=" "BASE64"
               ";" "VALUE" "=" "BINARY"
               ":" binary
             )
             CRLF

attachparam = *(
            ;
            ; The following is OPTIONAL for a URI value,
            ; RECOMMENDED for a BINARY value,
            ; and MUST NOT occur more than once.
            ;
            (";" fmttypeparam) /
            ;
            ; The following is OPTIONAL,
            ; and MAY occur more than once.
            ;
            (";" other-param)
            ;
            )

categories = "CATEGORIES" catparam ":" text *("," text)
             CRLF

catparam   = *(
           ;
           ; The following is OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" languageparam ) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

class      = "CLASS" classparam ":" classvalue CRLF

classparam = *(";" other-param)

classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token
           / x-name
;Default is PUBLIC

comment    = "COMMENT" commparam ":" text CRLF

commparam  = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" altrepparam) / (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

description = "DESCRIPTION" descparam ":" text CRLF

descparam   = *(
            ;
            ; The following are OPTIONAL,
            ; but MUST NOT occur more than once.
            ;
            (";" altrepparam) / (";" languageparam) /
            ;
            ; The following is OPTIONAL,
            ; and MAY occur more than once.
            ;
            (";" other-param)
            ;
            )

geo        = "GEO" geoparam ":" geovalue CRLF

geoparam   = *(";" other-param)

geovalue   = float ";" float
;Latitude and Longitude components

location   = "LOCATION"  locparam ":" text CRLF

locparam   = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" altrepparam) / (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

percent = "PERCENT-COMPLETE" pctparam ":" integer CRLF

pctparam   = *(";" other-param)

priority   = "PRIORITY" prioparam ":" priovalue CRLF
;Default is zero (i.e., undefined).

prioparam  = *(";" other-param)

priovalue   = integer       ;Must be in the range [0..9]
   ; All other values are reserved for future use.

resources  = "RESOURCES" resrcparam ":" text *("," text) CRLF

resrcparam = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" altrepparam) / (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

status          = "STATUS" statparam ":" statvalue CRLF

statparam       = *(";" other-param)

statvalue       = (statvalue-event
                /  statvalue-todo
                /  statvalue-jour)

statvalue-event = "TENTATIVE"    ;Indicates event is tentative.
                / "CONFIRMED"    ;Indicates event is definite.
                / "CANCELLED"    ;Indicates event was cancelled.
;Status values for a "VEVENT"

statvalue-todo  = "NEEDS-ACTION" ;Indicates to-do needs action.
                / "COMPLETED"    ;Indicates to-do completed.
                / "IN-PROCESS"   ;Indicates to-do in process of.
                / "CANCELLED"    ;Indicates to-do was cancelled.
;Status values for "VTODO".

statvalue-jour  = "DRAFT"        ;Indicates journal is draft.
                / "FINAL"        ;Indicates journal is final.
                / "CANCELLED"    ;Indicates journal is removed.
;Status values for "VJOURNAL".

summary    = "SUMMARY" summparam ":" text CRLF

summparam  = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" altrepparam) / (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

completed  = "COMPLETED" compparam ":" date-time CRLF

compparam  = *(";" other-param)

dtend      = "DTEND" dtendparam ":" dtendval CRLF

dtendparam = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
           (";" tzidparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

dtendval   = date-time / date
;Value MUST match value type

due        = "DUE" dueparam ":" dueval CRLF

dueparam   = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
           (";" tzidparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

dueval     = date-time / date
;Value MUST match value type

dtstart    = "DTSTART" dtstparam ":" dtstval CRLF

dtstparam  = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
           (";" tzidparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

dtstval    = date-time / date
;Value MUST match value type

duration   = "DURATION" durparam ":" dur-value CRLF
             ;consisting of a positive duration of time.

durparam   = *(";" other-param)

freebusy   = "FREEBUSY" fbparam ":" fbvalue CRLF

fbparam    = *(
           ;
           ; The following is OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" fbtypeparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

fbvalue    = period *("," period)
;Time value MUST be in the UTC time format.

transp     = "TRANSP" transparam ":" transvalue CRLF

transparam = *(";" other-param)

transvalue = "OPAQUE"
            ;Blocks or opaque on busy time searches.
            / "TRANSPARENT"
            ;Transparent on busy time searches.
;Default value is OPAQUE

tzid       = "TZID" tzidpropparam ":" [tzidprefix] text CRLF

tzidpropparam      = *(";" other-param)

;tzidprefix        = "/"
; Defined previously. Just listed here for reader convenience.

tzname     = "TZNAME" tznparam ":" text CRLF

tznparam   = *(
           ;
           ; The following is OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

tzoffsetfrom       = "TZOFFSETFROM" frmparam ":" utc-offset
                     CRLF

frmparam   = *(";" other-param)

tzoffsetto = "TZOFFSETTO" toparam ":" utc-offset CRLF

toparam    = *(";" other-param)

tzurl      = "TZURL" tzurlparam ":" uri CRLF

tzurlparam = *(";" other-param)

attendee   = "ATTENDEE" attparam ":" cal-address CRLF

attparam   = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" cutypeparam) / (";" memberparam) /
           (";" roleparam) / (";" partstatparam) /
           (";" rsvpparam) / (";" deltoparam) /
           (";" delfromparam) / (";" sentbyparam) /
           (";" cnparam) / (";" dirparam) /
           (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

contact    = "CONTACT" contparam ":" text CRLF

contparam  = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" altrepparam) / (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

organizer  = "ORGANIZER" orgparam ":"
             cal-address CRLF

orgparam   = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" cnparam) / (";" dirparam) / (";" sentbyparam) /
           (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

recurid    = "RECURRENCE-ID" ridparam ":" ridval CRLF

ridparam   = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
           (";" tzidparam) / (";" rangeparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

ridval     = date-time / date
;Value MUST match value type

related    = "RELATED-TO" relparam ":" text CRLF

relparam   = *(
           ;
           ; The following is OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" reltypeparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

url        = "URL" urlparam ":" uri CRLF

urlparam   = *(";" other-param)

uid        = "UID" uidparam ":" text CRLF

uidparam   = *(";" other-param)

exdate     = "EXDATE" exdtparam ":" exdtval *("," exdtval) CRLF

exdtparam  = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
           ;
           (";" tzidparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

exdtval    = date-time / date
;Value MUST match value type

rdate      = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF

rdtparam   = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" ("DATE-TIME" / "DATE" / "PERIOD")) /
           (";" tzidparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

rdtval     = date-time / date / period
;Value MUST match value type

rrule      = "RRULE" rrulparam ":" recur CRLF

rrulparam  = *(";" other-param)

action      = "ACTION" actionparam ":" actionvalue CRLF

actionparam = *(";" other-param)


actionvalue = "AUDIO" / "DISPLAY" / "EMAIL"
            / iana-token / x-name

repeat  = "REPEAT" repparam ":" integer CRLF
;Default is "0", zero.

repparam   = *(";" other-param)

trigger    = "TRIGGER" (trigrel / trigabs) CRLF

trigrel    = *(
           ;
           ; The following are OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" "DURATION") /
           (";" trigrelparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           ) ":"  dur-value

trigabs    = *(
           ;
           ; The following is REQUIRED,
           ; but MUST NOT occur more than once.
           ;
           (";" "VALUE" "=" "DATE-TIME") /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           ) ":" date-time

created    = "CREATED" creaparam ":" date-time CRLF

creaparam  = *(";" other-param)

dtstamp    = "DTSTAMP" stmparam ":" date-time CRLF

stmparam   = *(";" other-param)

last-mod   = "LAST-MODIFIED" lstparam ":" date-time CRLF

lstparam   = *(";" other-param)

seq = "SEQUENCE" seqparam ":" integer CRLF
; Default is "0"

seqparam   = *(";" other-param)

iana-prop = iana-token *(";" icalparameter) ":" value CRLF

x-prop = x-name *(";" icalparameter) ":" value CRLF

rstatus    = "REQUEST-STATUS" rstatparam ":"
             statcode ";" statdesc [";" extdata]

rstatparam = *(
           ;
           ; The following is OPTIONAL,
           ; but MUST NOT occur more than once.
           ;
           (";" languageparam) /
           ;
           ; The following is OPTIONAL,
           ; and MAY occur more than once.
           ;
           (";" other-param)
           ;
           )

statcode   = 1*DIGIT 1*2("." 1*DIGIT)
;Hierarchical, numeric return status code

statdesc   = text
;Textual status description

extdata    = text
;Textual exception data.  For example, the offending property
;name and value or complete property line.

;; FIXME: Defined in section 8.x, but conflicts with some definitions from earlier.
;;  method  = 1*(ALPHA / DIGIT / "-")
;;  ; IANA-registered iCalendar object method
;;
;;  component = "VEVENT"
;;            / "VTODO"
;;            / "VJOURNAL"
;;            / "VFREEBUSY"
;;            / "VTIMEZONE"
;;            / iana-token
;;            / x-name
;;
;;  optinfo    = infovalue / qinfovalue
;;
;;  infovalue  = iana-token / x-name
;;
;;  qinfovalue = DQUOTE (infovalue) DQUOTE
