From df7add59ee9bf684849d08f222e267ca7ed205a9 Mon Sep 17 00:00:00 2001 From: xengi Date: Fri, 21 Aug 2026 22:32:15 +0200 Subject: [PATCH 01/18] Add .forgejo/workflows/test.yaml --- .forgejo/workflows/test.yaml | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .forgejo/workflows/test.yaml diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml new file mode 100644 index 0000000..363d3a4 --- /dev/null +++ b/.forgejo/workflows/test.yaml @@ -0,0 +1,37 @@ +name: Test setup + +on: + workflow_dispatch: + +env: + TEST_URL: berlin.ccc.de + +jobs: + build: + runs-on: debian-stable + name: Test setup + steps: + - name: Check env + run: env + - name: Install tools + run: | + apt-get update + apt-get install -y --no-install-recommends curl ca-certificates inetutils-ping iproute2 git + - name: Check resolv.conf + run: cat /etc/resolv.conf + - name: Check IP config + run: ip address + - name: Check IPv4 route + run: ip -4 route + - name: Check IPv6 route + run: ip -6 route + - name: Check IPv4 internet + run: ping -c4 1.1.1.1 + - name: Check IPv6 internet + run: ping6 -c4 2606:4700:4700::1111 + - name: Check IPv4 HTTP + run: curl -4 -vLo /dev/null ${{ env.TEST_URL }} + - name: Check IPv6 HTTP + run: curl -6 -vLo /dev/null ${{ env.TEST_URL }} + - name: Check out the repository + run: git clone ${{ env.FORGEJO_SERVER_URL }}/${{ env.FORGEJO_REPOSITORY }} . \ No newline at end of file From 9be6287a6810c293a5bc21632f79feb30c442bf5 Mon Sep 17 00:00:00 2001 From: xengi Date: Sat, 22 Aug 2026 15:22:52 +0200 Subject: [PATCH 02/18] Delete .forgejo/workflows/test.yaml --- .forgejo/workflows/test.yaml | 37 ------------------------------------ 1 file changed, 37 deletions(-) delete mode 100644 .forgejo/workflows/test.yaml diff --git a/.forgejo/workflows/test.yaml b/.forgejo/workflows/test.yaml deleted file mode 100644 index 363d3a4..0000000 --- a/.forgejo/workflows/test.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Test setup - -on: - workflow_dispatch: - -env: - TEST_URL: berlin.ccc.de - -jobs: - build: - runs-on: debian-stable - name: Test setup - steps: - - name: Check env - run: env - - name: Install tools - run: | - apt-get update - apt-get install -y --no-install-recommends curl ca-certificates inetutils-ping iproute2 git - - name: Check resolv.conf - run: cat /etc/resolv.conf - - name: Check IP config - run: ip address - - name: Check IPv4 route - run: ip -4 route - - name: Check IPv6 route - run: ip -6 route - - name: Check IPv4 internet - run: ping -c4 1.1.1.1 - - name: Check IPv6 internet - run: ping6 -c4 2606:4700:4700::1111 - - name: Check IPv4 HTTP - run: curl -4 -vLo /dev/null ${{ env.TEST_URL }} - - name: Check IPv6 HTTP - run: curl -6 -vLo /dev/null ${{ env.TEST_URL }} - - name: Check out the repository - run: git clone ${{ env.FORGEJO_SERVER_URL }}/${{ env.FORGEJO_REPOSITORY }} . \ No newline at end of file From b11d80aac295edc81254b450854eee3df40d896b Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:39:36 +0200 Subject: [PATCH 03/18] README: describe the calendar as it is built today MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `build.sh` no longer post-processes anything: since the switch to ICS files it just deletes `public/` and runs `hugo`. The `CALENDAR` placeholder, the Python dependency on `icalendar`, `python-dateutil` and `pytz`, and the `de_DE.UTF-8` locale requirement are all gone, and nothing in `packages.nix`, `devShells.nix` or `flake.nix` pulls in Python any more. Drop those claims. Describe instead where the two calendar views actually come from: the "Nächste Veranstaltungen" table and the calendar page are rendered in the browser from `/calendars/all.ics`, which is published next to the site and is not built from this repository. That also replaces the old advice to preview them via `./build.sh` plus a local HTTP server, which no longer helps. Without that file the two of them stay empty. Hugo serves everything below `static/` from the root of the site, so it can simply be put there, and the command that downloads it is worth writing down. Checked from an empty state: afterwards the file is served under `/calendars/all.ics` by `hugo serve` and the table on the start page fills with the upcoming events. It is a copy of published data and has no business in the repository, so ignore it. Mention the per-section `.ics` feeds Hugo does generate, so the ICS templates under `layouts/` are not mistaken for the source of `all.ics`. Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- .gitignore | 5 +++++ README.md | 32 +++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 008e122..03d9a0a 100644 --- a/.gitignore +++ b/.gitignore @@ -202,3 +202,8 @@ $RECYCLE.BIN/ *.lnk # End of https://www.toptal.com/developers/gitignore/api/windows,linux,macos,hugo,pycharm+all,vim,direnv + +### CCCB ### +# The calendar the site reads its events from is published next to the site and +# only downloaded here to look at the site locally, see the README. +/static/calendars/ diff --git a/README.md b/README.md index 5f72bd0..c14ea17 100644 --- a/README.md +++ b/README.md @@ -29,20 +29,31 @@ This is the website of the CCCB. Every change you make on the project will be reflected in your browser as long as `hugo serve` is running. -The *"Nächste Veranstaltungen"* table on the home page is generated by post-processing in `./build.sh`, not by Hugo, so -it is **not** visible under `hugo serve`. To preview the fully built site (including the home-page calendar), or to -ready the site for upload, run: +The *"Nächste Veranstaltungen"* table on the home page and the calendar under `/verein/calendar/` are rendered in the +browser by `static/js/upcoming.js` and `assets/js/calendar.js`. Both fetch `/calendars/all.ics`, which is **not** +generated by Hugo and is not part of this repo — it is published separately on the web server. Without it both tables +stay empty. Download the published calendar into `static/`, which Hugo serves under the same path, and they work +locally, under `hugo serve` as well as in a built site: + +```shell +mkdir -p static/calendars +curl -o static/calendars/all.ics https://berlin.ccc.de/calendars/all.ics +``` + +The file is only there to look at the site, it is not checked in. Download it again whenever you want the events that +are currently published. + +Hugo does generate an `.ics` feed per section (for example `/veranstaltungen/index.ics`) from the `dtstart`, `dtend` +and `rrule` front matter of the pages in `content/veranstaltungen/`, using the `.ics` templates under `layouts/`. + +To build the site for upload, run: ```shell ./build.sh -python3 -m http.server -d public 1313 ``` -`build.sh` replaces the `CALENDAR` placeholder in `index.html` with the upcoming-events table. It depends on Python -with the `icalendar`, `python-dateutil`, and `pytz` packages, plus a `de_DE.UTF-8` locale (used to format weekday -names). Inside `nix develop` these are provided automatically. - -To build with *nix*: `nix build '.?submodules=1#production-content'` +This deletes `public/` and runs `hugo` with the parameters from `.hugo-params`. To build with *nix* instead: +`nix build '.?submodules=1#production-content'` ## Making a change @@ -59,8 +70,7 @@ To build with *nix*: `nix build '.?submodules=1#production-content'` ## Nix stuff -- After entering the shell with `nix develop`, hugo is available and `hugo serve` should work -- Python including required packages will be available, so the `build.sh` should work without a venv +- After entering the shell with `nix develop`, hugo is available and `hugo serve` and `./build.sh` should work - You can build the staging and production builds with `nix build .#staging-content` and `nix build .#production-content` - Do not update the nixpkgs branch - 25.05 contains a newer hugo version that is incompatible with the theme (last From b8ec4578185b5aa794bfbea41f4e099aa5a86359 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:37:37 +0200 Subject: [PATCH 04/18] Link upcoming events to their ICS URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Nächste Veranstaltungen" table read the event URL via `ICAL.Event.url`, but ical.js does not expose a `url` getter on `ICAL.Event` (it only has uid, summary, description, color, location, sequence, the dates, organizer and attendees). `event.url` was therefore always `undefined` and the `?? ""` fallback turned it into an empty string, so every row rendered as ``, a dead link that just reloads the start page. Read the URL from the VEVENT component instead. This also picks up the `URL;VALUE=URI:` form used by most events in the published calendar, which is exported from a CalDAV client and does not use a bare `URL:` property. Not every event has a URL, so only wrap the name in a link when one is present and emit plain text otherwise. Checked against https://berlin.ccc.de/calendars/all.ics (31 events, 1 of them without a URL): before: CCCB Plenum after: CCCB Plenum after: Aktionstag gegen Überwachung im Chaos Computer Club Berlin Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- static/js/upcoming.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/static/js/upcoming.js b/static/js/upcoming.js index 6b7a711..cc8ad0b 100644 --- a/static/js/upcoming.js +++ b/static/js/upcoming.js @@ -7,7 +7,7 @@ import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js"; * @param {Date} now Events must start after this date * @param {number} maxEvents Maximum number of events to return * @param {number} maxDays Maximum number of days into the future - * @returns {{start: Date, name: string, url: string}[]} + * @returns {{start: Date, name: string, url: string}[]} url is empty when the event has no URL */ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { const jcal = ICAL.parse(icsText); @@ -25,6 +25,9 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { continue; } + // ICAL.Event does not expose the URL property, so read it from the component. + const url = component.getFirstPropertyValue("url") ?? ""; + if (event.isRecurring()) { const iterator = event.iterator(); @@ -47,7 +50,7 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { events.push({ start, name: event.summary ?? "", - url: event.url ?? "", + url, }); } } @@ -58,7 +61,7 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { events.push({ start, name: event.summary ?? "", - url: event.url ?? "", + url, }); } } @@ -100,11 +103,16 @@ document.addEventListener("DOMContentLoaded", () => { const colName = document.createElement("td"); - const a = document.createElement("a"); - a.href = event.url; - a.text = event.name; + if (event.url) { + const a = document.createElement("a"); + a.href = event.url; + a.text = event.name; + + colName.appendChild(a); + } else { + colName.innerText = event.name; + } - colName.appendChild(a); row.appendChild(colName); table.appendChild(row); From 8b692a2e881239d7c2f02cf6e40d0976a12fc799 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:43:35 +0200 Subject: [PATCH 05/18] Keep running events in the upcoming list until they end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Nächste Veranstaltungen" table selected events with `start > now`, so an event disappeared from the list the moment it began. Someone looking at the start page at 20:30 no longer saw the Plenum that had started at 20:00 and ran until 22:00, which is exactly when that information is most useful. Select on the end of the event instead, so an event stays listed for as long as it is still running. A currently running event sorts first, because the list is ordered by start time. For recurring events the end of the individual occurrence is needed, not the end of the series, so go through `getOccurrenceDetails()`. That also resolves occurrences overridden via RECURRENCE-ID. The chronological break out of the iteration keeps using the raw occurrence time, which stays monotonic even when an override moves a single occurrence. `ICAL.Event.endDate` falls back to DURATION and, for all-day events, to the following day, so events without an explicit DTEND keep working. The `maxDays` window still applies to the start of an event, so a long running event does not extend the window. This is not a regression from the commit below, the Python generator it replaced filtered on `dtstart >= start` in the same way. Checked against https://berlin.ccc.de/calendars/all.ics: the Plenum (20:00 to 22:00) is now listed at 20:30 and 21:59 and gone at 22:01, and the multi-day Amateurfunk trip (30.10. 12:00 to 01.11. 18:00) stays listed throughout. Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- static/js/upcoming.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/static/js/upcoming.js b/static/js/upcoming.js index cc8ad0b..f031b4d 100644 --- a/static/js/upcoming.js +++ b/static/js/upcoming.js @@ -4,7 +4,7 @@ import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js"; * Parse an ICS calendar and return upcoming event occurrences. * * @param {string} icsText The contents of the .ics file - * @param {Date} now Events must start after this date + * @param {Date} now Events must still be running at this date * @param {number} maxEvents Maximum number of events to return * @param {number} maxDays Maximum number of days into the future * @returns {{start: Date, name: string, url: string}[]} url is empty when the event has no URL @@ -38,17 +38,19 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { break; } - const start = occurrence.toJSDate(); - // Recurrences are chronological, so we're done // once we pass the end of our search window. - if (start > end) { + if (occurrence.toJSDate() > end) { break; } - if (start > now) { + // Details resolve the times of occurrences overridden by RECURRENCE-ID. + const details = event.getOccurrenceDetails(occurrence); + + // A running event stays listed until it is over, so filter on its end. + if (details.endDate.toJSDate() > now) { events.push({ - start, + start: details.startDate.toJSDate(), name: event.summary ?? "", url, }); @@ -57,7 +59,7 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { } else { const start = event.startDate.toJSDate(); - if (start > now && start <= end) { + if (start <= end && event.endDate.toJSDate() > now) { events.push({ start, name: event.summary ?? "", From 6d99a39190abb1b1ba2ea1df68990db773326bfb Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:56:48 +0200 Subject: [PATCH 06/18] Do not list a moved event occurrence twice An occurrence of a recurring event that was changed on its own carries a RECURRENCE-ID and is stored as an additional VEVENT next to the event it belongs to. `getAllSubcomponents("vevent")` returns those components as well, and since they have no RRULE of their own they were handled as separate single events. The occurrence therefore ended up in the list twice: once from expanding the recurring event, which resolves the modified time through the exception, and once more from the extra VEVENT. To make it worse the two rows disagreed, because name and URL were taken from the recurring event while the time came from the modification, so the first row showed the new time under the old name. Skip components that are a recurrence exception, they are already covered by the event they modify, and take name and URL from the occurrence details, which point at the modification where there is one and at the event itself otherwise. Events whose RECURRENCE-ID refers to an event that is not in the file are dropped by this, which cannot happen in a full calendar export. With a recurring Plenum whose 25.08. occurrence is moved two hours earlier and renamed: before: 25.08. 18:00 CCCB Plenum 25.08. 18:00 CCCB Plenum (verschoben) after: 25.08. 18:00 CCCB Plenum (verschoben) Leaning on the resolution ical.js does here needs two more things to be right. The first is which modifications an event is asked to resolve. Unless it is told, `ICAL.Event` relates every VEVENT with a RECURRENCE-ID in the file to every recurring event and keys them by the recurrence id alone; the UID is only compared with `strictExceptions`, which then throws instead of skipping. A modification would therefore also override the occurrence another series holds at the same instant, so the wrong entry is shown and the modified one twice over. Group the modifications by the UID of the event they belong to and hand each event its own, which also turns the relating off for events that have none. Recognise a modification on the component instead of on the event, because relating exceptions to an exception throws. With two unrelated weekly series that both meet on Thursday at 19:00, of which only A has its occurrence of 03.09. moved to 17:00: before: 27.08. 19:00 Serie A after: 27.08. 19:00 Serie A 27.08. 19:00 Serie B 27.08. 19:00 Serie B 03.09. 17:00 Serie A (versch.) 03.09. 17:00 Serie A (versch.) 03.09. 17:00 Serie A (versch.) 03.09. 19:00 Serie B The second is how far the expansion has to run. It walks the unmodified recurrence times and stopped at the end of the window, but the occurrence handed to `getOccurrenceDetails()` may have been moved somewhere else entirely. Both directions were wrong: an occurrence pulled forward from beyond the window was never reached, because the walk had already stopped at its original time, and one pushed out of the window was still listed, because only its original time was ever compared against the window. Iterate far enough that the largest move towards the past can still reach the window, and decide by the time the occurrence really takes place at. The stop condition keeps using the raw recurrence time, which stays monotonic, so the iteration still terminates. With a weekly series whose occurrence of 05.10. is pulled forward to 25.08. and whose occurrence of 31.08. is pushed to 02.11., seen from 23.08. through the 20 day window: before: 24.08. Serie after: 24.08. Serie 31.08. Serie 25.08. Serie (vorgezogen) 07.09. Serie 07.09. Serie Reading the URL becomes a function of its own while name and URL move to the occurrence details, and it now looks at what it reads. The calendar is exported from a CalDAV server, so whoever may write to it decides what ends up in the href of the link, and `URL:javascript:alert(1)` on an event would run that script when a visitor clicks the entry. Pass on nothing but http and https; a value that is not a URL at all no longer reaches the href either. The published calendar contains no RECURRENCE-ID at all today, so nothing about the modifications changes for it. It is exported from a CalDAV server though, and moving a single Club Discordia or Plenum out of the way of a holiday is exactly what creates such a modification. Checked against https://berlin.ccc.de/calendars/all.ics: the list and the links of the 30 events that carry a URL are unchanged. Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- static/js/upcoming.js | 125 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 11 deletions(-) diff --git a/static/js/upcoming.js b/static/js/upcoming.js index f031b4d..dde5f1f 100644 --- a/static/js/upcoming.js +++ b/static/js/upcoming.js @@ -1,5 +1,96 @@ import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js"; +/** + * Read the URL of an event. + * + * ICAL.Event does not expose the URL property, so read it from the component. + * + * The value ends up in the href of a link, and the calendar is exported from a + * CalDAV server, so whoever may write to it decides what that value is. A + * "javascript:" URL there would run on our page as soon as a visitor clicks + * the event, so hand on nothing but http and https. + * + * @param {ICAL.Event} event The event to read the URL of + * @returns {string} The URL, empty when the event has none or it is not http(s) + */ +function eventUrl(event) { + const url = event.component.getFirstPropertyValue("url") ?? ""; + + if (!url) { + return ""; + } + + try { + // A relative URL is resolved against the page and keeps its scheme. + const { protocol } = new URL(url, document.baseURI); + + return protocol === "http:" || protocol === "https:" ? url : ""; + } catch { + // Not a URL at all. + return ""; + } +} + +/** + * Group the occurrences that were modified on their own by the UID of the event + * they belong to. + * + * Unless it is told which exceptions belong to an event, ICAL.Event relates + * every VEVENT with a RECURRENCE-ID in the file to every recurring event, and + * it keys them by the recurrence id alone. Two series that meet at the same + * time would therefore take over each other's modifications. + * + * @param {ICAL.Component[]} components The VEVENTs of the calendar + * @returns {Map} The exceptions per UID + */ +function exceptionsByUid(components) { + const exceptions = new Map(); + + for (const component of components) { + if (!component.hasProperty("recurrence-id")) { + continue; + } + + const uid = component.getFirstPropertyValue("uid"); + const ofEvent = exceptions.get(uid); + + if (ofEvent) { + ofEvent.push(component); + } else { + exceptions.set(uid, [component]); + } + } + + return exceptions; +} + +/** + * How far the recurrences of an event have to be iterated. + * + * The iteration walks the unmodified recurrence times, so an occurrence that + * was moved to an earlier time is only reached through the time it originally + * had, which can lie past the end of the window. Keep going for as long as the + * largest move towards the past can still carry an occurrence into it. + * + * @param {ICAL.Event} event The event whose recurrences are iterated + * @param {Date} end End of the window + * @returns {Date} The recurrence time to stop at + */ +function iterationEnd(event, end) { + let last = end.getTime(); + + for (const exception of Object.values(event.exceptions)) { + const movedBy = exception.recurrenceId.toJSDate().getTime() + - exception.startDate.toJSDate().getTime(); + + if (movedBy > 0) { + last = Math.max(last, end.getTime() + movedBy); + } + } + + return new Date(last); +} + /** * Parse an ICS calendar and return upcoming event occurrences. * @@ -18,18 +109,27 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { const events = []; - for (const component of calendar.getAllSubcomponents("vevent")) { - const event = new ICAL.Event(component); + const components = calendar.getAllSubcomponents("vevent"); + const exceptions = exceptionsByUid(components); + + for (const component of components) { + // Occurrences modified via RECURRENCE-ID are reached through the event they + // belong to, listing them here as well would show them twice. + if (component.hasProperty("recurrence-id")) { + continue; + } + + const event = new ICAL.Event(component, { + exceptions: exceptions.get(component.getFirstPropertyValue("uid")) ?? [], + }); if (!event.startDate) { continue; } - // ICAL.Event does not expose the URL property, so read it from the component. - const url = component.getFirstPropertyValue("url") ?? ""; - if (event.isRecurring()) { const iterator = event.iterator(); + const iterateUntil = iterationEnd(event, end); while (true) { const occurrence = iterator.next(); @@ -40,19 +140,22 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { // Recurrences are chronological, so we're done // once we pass the end of our search window. - if (occurrence.toJSDate() > end) { + if (occurrence.toJSDate() > iterateUntil) { break; } - // Details resolve the times of occurrences overridden by RECURRENCE-ID. + // Details resolve time, name and URL of an occurrence that was + // modified via RECURRENCE-ID. const details = event.getOccurrenceDetails(occurrence); // A running event stays listed until it is over, so filter on its end. - if (details.endDate.toJSDate() > now) { + // A modification may have moved the occurrence out of the window, so + // judge it by the time it really takes place at. + if (details.startDate.toJSDate() <= end && details.endDate.toJSDate() > now) { events.push({ start: details.startDate.toJSDate(), - name: event.summary ?? "", - url, + name: details.item.summary ?? "", + url: eventUrl(details.item), }); } } @@ -63,7 +166,7 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { events.push({ start, name: event.summary ?? "", - url, + url: eventUrl(event), }); } } From cd39842ac0fdf556796ee9d0c1b746585448c615 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:57:14 +0200 Subject: [PATCH 07/18] Show event times in Berlin time `toLocaleString()` was given the German locale but no time zone, so it printed the time in whatever zone the browser of the visitor is set to. The events happen in Berlin, so this is only correct for visitors who are in Berlin. Somebody reading the start page from Sydney was told the Plenum of Tuesday 20:00 takes place on Wednesday at 04:00. Format in Europe/Berlin explicitly. For an event that names a point in time only the printing was wrong, picking and sorting work on absolute points in time and were not affected. An all day event carries a date, and a date has neither a time nor a zone: its digits are the day itself. `toJSDate()` reads them as midnight in the zone of the browser, so the point in time that is then printed in Berlin time is off by the offset between the two, which puts a bogus time of day on the entry and, far enough east or west, the wrong day. An event on 30.08. was announced as: Berlin Sonntag, 30.08., 00:00 Uhr Los Angeles Sonntag, 30.08., 09:00 Uhr Tokio Samstag, 29.08., 17:00 Uhr Keep the digits of the date and read them as UTC, which no browser setting moves, and print an all day event in UTC and without a time of day. Berlin, Tokyo, Los Angeles and Kiritimati all say "Sonntag, 30.08." now, while a timed event keeps saying "Sonntag, 30.08., 19:00 Uhr" everywhere. Sorting improves with it, an all day event no longer changes its place in the list depending on where the visitor sits. The published calendar has no all day events today, they can be created in the CalDAV calendar the export comes from. Drop the two replacements around the formatted date while touching it. The first removes the comma after the weekday and the second puts it back, so they cancel each other out: "Samstag, 22.08., 17:00" -> "Samstag 22.08., 17:00" -> "Samstag, 22.08., 17:00" Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- static/js/upcoming.js | 56 ++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/static/js/upcoming.js b/static/js/upcoming.js index dde5f1f..64daf96 100644 --- a/static/js/upcoming.js +++ b/static/js/upcoming.js @@ -64,6 +64,26 @@ function exceptionsByUid(components) { return exceptions; } +/** + * When an occurrence starts, as a point in time. + * + * A date has no time and no zone, its digits are the day itself. toJSDate() + * reads them as midnight in the zone of the browser, which moves an all day + * event by the offset that zone has to Berlin and, far enough east or west, + * onto the day before or after. Keep the digits and read them as UTC instead, + * the table prints an all day event in UTC as well. + * + * @param {ICAL.Time} time Start of the occurrence + * @returns {Date} The point in time to sort and print by + */ +function startOf(time) { + if (time.isDate) { + return new Date(Date.UTC(time.year, time.month - 1, time.day)); + } + + return time.toJSDate(); +} + /** * How far the recurrences of an event have to be iterated. * @@ -98,7 +118,7 @@ function iterationEnd(event, end) { * @param {Date} now Events must still be running at this date * @param {number} maxEvents Maximum number of events to return * @param {number} maxDays Maximum number of days into the future - * @returns {{start: Date, name: string, url: string}[]} url is empty when the event has no URL + * @returns {{start: Date, allDay: boolean, name: string, url: string}[]} url is empty when the event has no URL */ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { const jcal = ICAL.parse(icsText); @@ -153,22 +173,20 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { // judge it by the time it really takes place at. if (details.startDate.toJSDate() <= end && details.endDate.toJSDate() > now) { events.push({ - start: details.startDate.toJSDate(), + start: startOf(details.startDate), + allDay: details.startDate.isDate, name: details.item.summary ?? "", url: eventUrl(details.item), }); } } - } else { - const start = event.startDate.toJSDate(); - - if (start <= end && event.endDate.toJSDate() > now) { - events.push({ - start, - name: event.summary ?? "", - url: eventUrl(event), - }); - } + } else if (event.startDate.toJSDate() <= end && event.endDate.toJSDate() > now) { + events.push({ + start: startOf(event.startDate), + allDay: event.startDate.isDate, + name: event.summary ?? "", + url: eventUrl(event), + }); } } @@ -195,15 +213,21 @@ document.addEventListener("DOMContentLoaded", () => { const colBegin = document.createElement("td"); + // The events take place in Berlin, so name their time in Berlin time + // instead of in the time zone the visitor happens to be in. An all day + // event has no time of day and carries its date in UTC, see startOf(). + const whenFormat = event.allDay + ? { timeZone: "UTC" } + : { timeZone: "Europe/Berlin", hour: "2-digit", minute: "2-digit" }; + const formattedStart = event.start.toLocaleString("de-DE", { weekday: "long", day: "2-digit", month: "2-digit", - hour: "2-digit", - minute: "2-digit", - }).replace(",", ""); + ...whenFormat, + }); - colBegin.innerText = `${formattedStart.replace(" ", ", ")} Uhr`; + colBegin.innerText = event.allDay ? formattedStart : `${formattedStart} Uhr`; row.appendChild(colBegin); const colName = document.createElement("td"); From 45458523271871c3b02ae16b9a850f559b6735c9 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:58:02 +0200 Subject: [PATCH 08/18] Report errors while loading the calendar The response of the fetch went to the parser without ever looking at it. When the calendar could not be loaded the error page of the web server was parsed as a calendar, which threw inside a promise nobody was waiting on. The result was an empty table, an unhandled rejection in the console and an error message about broken calendar syntax that says nothing about the actual problem, a calendar that is not there. Refuse a response that is not ok, naming the status, and log failures in the chain, like the calendar page already does. before: Uncaught (in promise) Error: invalid line (no token ";" or ":") "404 Not Found" after: Fehler beim Laden der Termine: Error: /calendars/all.ics: 404 Not Found The table stays empty either way, there is nothing to show without a calendar. Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- static/js/upcoming.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/static/js/upcoming.js b/static/js/upcoming.js index 64daf96..d978c7e 100644 --- a/static/js/upcoming.js +++ b/static/js/upcoming.js @@ -206,7 +206,15 @@ document.addEventListener("DOMContentLoaded", () => { const table = document.getElementById("upcoming"); fetch(ics) - .then(response => response.text()) + .then(response => { + // Without this an error page would be handed to the parser below, which + // then fails with a confusing complaint about the calendar syntax. + if (!response.ok) { + throw new Error(`${ics}: ${response.status} ${response.statusText}`); + } + + return response.text(); + }) .then(icsText => { getUpcomingEvents(icsText, now, max_items, max_days).forEach(event => { const row = document.createElement("tr"); @@ -246,5 +254,6 @@ document.addEventListener("DOMContentLoaded", () => { table.appendChild(row); }); - }); + }) + .catch(err => console.error("Fehler beim Laden der Termine:", err)); }); From a0e1ef046a59f6e897e694a043ca833aa010f49e Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 19:48:49 +0200 Subject: [PATCH 09/18] Vendor ical.js instead of loading it from unpkg.com The upcoming events table pulled its ICS parser straight from a CDN with `import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js"`. That sends every visitor of the start page to unpkg.com, which hands their IP address and user agent to a third party before any of our own code runs. The URL is not even pinned to a version, so whatever ical.js publishes next is executed on our site without anybody looking at it, and the start page silently breaks when the CDN is unreachable. Check the parser into `assets/js/vendor/` and let Hugo bundle it. This is what `js.Build` is for: it runs the esbuild that is built into Hugo, so it resolves the import at build time and needs no node_modules and no extra tooling in the build environment. The result is minified and fingerprinted like the other scripts of the site, and the script tag carries a subresource integrity hash. Since the bundle now has a content hash in its name, its URL cannot be written by hand in the markdown any more. Move the table and the script tag into an `upcoming` shortcode, which is the same pattern `calendar.html` already uses, and move `upcoming.js` from `static/` to `assets/` so Hugo can process it. The vendored file is the unminified `dist/ical.js` of the pinned release: it carries the MPL-2.0 header and is the source form of what we ship, and Hugo minifies it for delivery anyway. `assets/js/vendor/README.md` records the version, where it came from and how to update it. The built bundle renders the same table as before, checked against https://berlin.ccc.de/calendars/all.ics. Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- README.md | 5 +- {static => assets}/js/upcoming.js | 2 +- assets/js/vendor/README.md | 19 + assets/js/vendor/ical.js | 9732 +++++++++++++++++++++++++++++ content/_index.md | 5 +- layouts/shortcodes/upcoming.html | 3 + 6 files changed, 9760 insertions(+), 6 deletions(-) rename {static => assets}/js/upcoming.js (99%) create mode 100644 assets/js/vendor/README.md create mode 100644 assets/js/vendor/ical.js create mode 100644 layouts/shortcodes/upcoming.html diff --git a/README.md b/README.md index c14ea17..977dbb3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This is the website of the CCCB. Every change you make on the project will be reflected in your browser as long as `hugo serve` is running. The *"Nächste Veranstaltungen"* table on the home page and the calendar under `/verein/calendar/` are rendered in the -browser by `static/js/upcoming.js` and `assets/js/calendar.js`. Both fetch `/calendars/all.ics`, which is **not** +browser by `assets/js/upcoming.js` and `assets/js/calendar.js`. Both fetch `/calendars/all.ics`, which is **not** generated by Hugo and is not part of this repo — it is published separately on the web server. Without it both tables stay empty. Download the published calendar into `static/`, which Hugo serves under the same path, and they work locally, under `hugo serve` as well as in a built site: @@ -46,6 +46,9 @@ are currently published. Hugo does generate an `.ics` feed per section (for example `/veranstaltungen/index.ics`) from the `dtstart`, `dtend` and `rrule` front matter of the pages in `content/veranstaltungen/`, using the `.ics` templates under `layouts/`. +The site must not make the browser load anything from an external server, so third party JavaScript is checked into +`assets/js/vendor/` and bundled in by Hugo instead of being pulled from a CDN. See the README there before updating it. + To build the site for upload, run: ```shell diff --git a/static/js/upcoming.js b/assets/js/upcoming.js similarity index 99% rename from static/js/upcoming.js rename to assets/js/upcoming.js index d978c7e..c55a2e3 100644 --- a/static/js/upcoming.js +++ b/assets/js/upcoming.js @@ -1,4 +1,4 @@ -import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js"; +import ICAL from "./vendor/ical.js"; /** * Read the URL of an event. diff --git a/assets/js/vendor/README.md b/assets/js/vendor/README.md new file mode 100644 index 0000000..be1a059 --- /dev/null +++ b/assets/js/vendor/README.md @@ -0,0 +1,19 @@ +# Vendored JavaScript + +Third party code is checked in here instead of being loaded from a CDN, so that the website does not make the visitor's +browser fetch anything from an external server. + +Hugo bundles and minifies these files into the scripts that reference them, so the unminified source is checked in. + +## ical.js + +- Version: 2.2.1 +- Source: +- Upstream: +- License: MPL-2.0 (see the header of `ical.js`) + +To update, download the `dist/ical.js` of the wanted release and replace the file, keeping the version above in sync: + +```shell +curl -o assets/js/vendor/ical.js https://unpkg.com/ical.js@/dist/ical.js +``` diff --git a/assets/js/vendor/ical.js b/assets/js/vendor/ical.js new file mode 100644 index 0000000..be2228f --- /dev/null +++ b/assets/js/vendor/ical.js @@ -0,0 +1,9732 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + +/** + * Represents the BINARY value type, which contains extra methods for encoding and decoding. + * + * @memberof ICAL + */ +class Binary { + /** + * Creates a binary value from the given string. + * + * @param {String} aString The binary value string + * @return {Binary} The binary value instance + */ + static fromString(aString) { + return new Binary(aString); + } + + /** + * Creates a new ICAL.Binary instance + * + * @param {String} aValue The binary data for this value + */ + constructor(aValue) { + this.value = aValue; + } + + /** + * The type name, to be used in the jCal object. + * @default "binary" + * @constant + */ + icaltype = "binary"; + + /** + * Base64 decode the current value + * + * @return {String} The base64-decoded value + */ + decodeValue() { + return this._b64_decode(this.value); + } + + /** + * Encodes the passed parameter with base64 and sets the internal + * value to the result. + * + * @param {String} aValue The raw binary value to encode + */ + setEncodedValue(aValue) { + this.value = this._b64_encode(aValue); + } + + _b64_encode(data) { + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Bayron Guevara + // + improved by: Thunder.m + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: Rafał Kukawski (http://kukawski.pl) + // * example 1: base64_encode('Kevin van Zonneveld'); + // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window['atob'] == 'function') { + // return atob(data); + //} + let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz0123456789+/="; + let o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + enc = "", + tmp_arr = []; + + if (!data) { + return data; + } + + do { // pack three octets into four hexets + o1 = data.charCodeAt(i++); + o2 = data.charCodeAt(i++); + o3 = data.charCodeAt(i++); + + bits = o1 << 16 | o2 << 8 | o3; + + h1 = bits >> 18 & 0x3f; + h2 = bits >> 12 & 0x3f; + h3 = bits >> 6 & 0x3f; + h4 = bits & 0x3f; + + // use hexets to index into b64, and append result to encoded string + tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < data.length); + + enc = tmp_arr.join(''); + + let r = data.length % 3; + + return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); + + } + + _b64_decode(data) { + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Thunder.m + // + input by: Aman Gupta + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); + // * returns 1: 'Kevin van Zonneveld' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window['btoa'] == 'function') { + // return btoa(data); + //} + let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz0123456789+/="; + let o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + dec = "", + tmp_arr = []; + + if (!data) { + return data; + } + + data += ''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(data.charAt(i++)); + h2 = b64.indexOf(data.charAt(i++)); + h3 = b64.indexOf(data.charAt(i++)); + h4 = b64.indexOf(data.charAt(i++)); + + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; + + o1 = bits >> 16 & 0xff; + o2 = bits >> 8 & 0xff; + o3 = bits & 0xff; + + if (h3 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1); + } else if (h4 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1, o2); + } else { + tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); + } + } while (i < data.length); + + dec = tmp_arr.join(''); + + return dec; + } + + /** + * The string representation of this value + * @return {String} + */ + toString() { + return this.value; + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +const DURATION_LETTERS = /([PDWHMTS]{1,1})/; +const DATA_PROPS_TO_COPY = ["weeks", "days", "hours", "minutes", "seconds", "isNegative"]; + +/** + * This class represents the "duration" value type, with various calculation + * and manipulation methods. + * + * @memberof ICAL + */ +class Duration { + /** + * Returns a new ICAL.Duration instance from the passed seconds value. + * + * @param {Number} aSeconds The seconds to create the instance from + * @return {Duration} The newly created duration instance + */ + static fromSeconds(aSeconds) { + return (new Duration()).fromSeconds(aSeconds); + } + + /** + * Checks if the given string is an iCalendar duration value. + * + * @param {String} value The raw ical value + * @return {Boolean} True, if the given value is of the + * duration ical type + */ + static isValueString(string) { + return (string[0] === 'P' || string[1] === 'P'); + } + + /** + * Creates a new {@link ICAL.Duration} instance from the passed string. + * + * @param {String} aStr The string to parse + * @return {Duration} The created duration instance + */ + static fromString(aStr) { + let pos = 0; + let dict = Object.create(null); + let chunks = 0; + + while ((pos = aStr.search(DURATION_LETTERS)) !== -1) { + let type = aStr[pos]; + let numeric = aStr.slice(0, Math.max(0, pos)); + aStr = aStr.slice(pos + 1); + + chunks += parseDurationChunk(type, numeric, dict); + } + + if (chunks < 2) { + // There must be at least a chunk with "P" and some unit chunk + throw new Error( + 'invalid duration value: Not enough duration components in "' + aStr + '"' + ); + } + + return new Duration(dict); + } + + /** + * Creates a new ICAL.Duration instance from the given data object. + * + * @param {Object} aData An object with members of the duration + * @param {Number=} aData.weeks Duration in weeks + * @param {Number=} aData.days Duration in days + * @param {Number=} aData.hours Duration in hours + * @param {Number=} aData.minutes Duration in minutes + * @param {Number=} aData.seconds Duration in seconds + * @param {Boolean=} aData.isNegative If true, the duration is negative + * @return {Duration} The createad duration instance + */ + static fromData(aData) { + return new Duration(aData); + } + + /** + * Creates a new ICAL.Duration instance. + * + * @param {Object} data An object with members of the duration + * @param {Number=} data.weeks Duration in weeks + * @param {Number=} data.days Duration in days + * @param {Number=} data.hours Duration in hours + * @param {Number=} data.minutes Duration in minutes + * @param {Number=} data.seconds Duration in seconds + * @param {Boolean=} data.isNegative If true, the duration is negative + */ + constructor(data) { + this.wrappedJSObject = this; + this.fromData(data); + } + + /** + * The weeks in this duration + * @type {Number} + * @default 0 + */ + weeks = 0; + + /** + * The days in this duration + * @type {Number} + * @default 0 + */ + days = 0; + + /** + * The days in this duration + * @type {Number} + * @default 0 + */ + hours = 0; + + /** + * The minutes in this duration + * @type {Number} + * @default 0 + */ + minutes = 0; + + /** + * The seconds in this duration + * @type {Number} + * @default 0 + */ + seconds = 0; + + /** + * The seconds in this duration + * @type {Boolean} + * @default false + */ + isNegative = false; + + /** + * The class identifier. + * @constant + * @type {String} + * @default "icalduration" + */ + icalclass = "icalduration"; + + /** + * The type name, to be used in the jCal object. + * @constant + * @type {String} + * @default "duration" + */ + icaltype = "duration"; + + /** + * Returns a clone of the duration object. + * + * @return {Duration} The cloned object + */ + clone() { + return Duration.fromData(this); + } + + /** + * The duration value expressed as a number of seconds. + * + * @return {Number} The duration value in seconds + */ + toSeconds() { + let seconds = this.seconds + 60 * this.minutes + 3600 * this.hours + + 86400 * this.days + 7 * 86400 * this.weeks; + return (this.isNegative ? -seconds : seconds); + } + + /** + * Reads the passed seconds value into this duration object. Afterwards, + * members like {@link ICAL.Duration#days days} and {@link ICAL.Duration#weeks weeks} will be set up + * accordingly. + * + * @param {Number} aSeconds The duration value in seconds + * @return {Duration} Returns this instance + */ + fromSeconds(aSeconds) { + let secs = Math.abs(aSeconds); + + this.isNegative = (aSeconds < 0); + this.days = trunc(secs / 86400); + + // If we have a flat number of weeks, use them. + if (this.days % 7 == 0) { + this.weeks = this.days / 7; + this.days = 0; + } else { + this.weeks = 0; + } + + secs -= (this.days + 7 * this.weeks) * 86400; + + this.hours = trunc(secs / 3600); + secs -= this.hours * 3600; + + this.minutes = trunc(secs / 60); + secs -= this.minutes * 60; + + this.seconds = secs; + return this; + } + + /** + * Sets up the current instance using members from the passed data object. + * + * @param {Object} aData An object with members of the duration + * @param {Number=} aData.weeks Duration in weeks + * @param {Number=} aData.days Duration in days + * @param {Number=} aData.hours Duration in hours + * @param {Number=} aData.minutes Duration in minutes + * @param {Number=} aData.seconds Duration in seconds + * @param {Boolean=} aData.isNegative If true, the duration is negative + */ + fromData(aData) { + for (let prop of DATA_PROPS_TO_COPY) { + if (aData && prop in aData) { + this[prop] = aData[prop]; + } else { + this[prop] = 0; + } + } + } + + /** + * Resets the duration instance to the default values, i.e. PT0S + */ + reset() { + this.isNegative = false; + this.weeks = 0; + this.days = 0; + this.hours = 0; + this.minutes = 0; + this.seconds = 0; + } + + /** + * Compares the duration instance with another one. + * + * @param {Duration} aOther The instance to compare with + * @return {Number} -1, 0 or 1 for less/equal/greater + */ + compare(aOther) { + let thisSeconds = this.toSeconds(); + let otherSeconds = aOther.toSeconds(); + return (thisSeconds > otherSeconds) - (thisSeconds < otherSeconds); + } + + /** + * Normalizes the duration instance. For example, a duration with a value + * of 61 seconds will be normalized to 1 minute and 1 second. + */ + normalize() { + this.fromSeconds(this.toSeconds()); + } + + /** + * The string representation of this duration. + * @return {String} + */ + toString() { + if (this.toSeconds() == 0) { + return "PT0S"; + } else { + let str = ""; + if (this.isNegative) str += "-"; + str += "P"; + let hasWeeks = false; + if (this.weeks) { + if (this.days || this.hours || this.minutes || this.seconds) { + str += (this.weeks * 7 + this.days) + "D"; + } else { + str += (this.weeks + "W"); + hasWeeks = true; + } + } else if (this.days) { + str += (this.days + "D"); + } + + if (!hasWeeks) { + if (this.hours || this.minutes || this.seconds) { + str += "T"; + if (this.hours) { + str += this.hours + "H"; + } + + if (this.minutes) { + str += this.minutes + "M"; + } + + if (this.seconds) { + str += this.seconds + "S"; + } + } + } + + return str; + } + } + + /** + * The iCalendar string representation of this duration. + * @return {String} + */ + toICALString() { + return this.toString(); + } +} + +/** + * Internal helper function to handle a chunk of a duration. + * + * @private + * @param {String} letter type of duration chunk + * @param {String} number numeric value or -/+ + * @param {Object} dict target to assign values to + */ +function parseDurationChunk(letter, number, object) { + let type; + switch (letter) { + case 'P': + if (number && number === '-') { + object.isNegative = true; + } else { + object.isNegative = false; + } + // period + break; + case 'D': + type = 'days'; + break; + case 'W': + type = 'weeks'; + break; + case 'H': + type = 'hours'; + break; + case 'M': + type = 'minutes'; + break; + case 'S': + type = 'seconds'; + break; + default: + // Not a valid chunk + return 0; + } + + if (type) { + if (!number && number !== 0) { + throw new Error( + 'invalid duration value: Missing number before "' + letter + '"' + ); + } + let num = parseInt(number, 10); + if (isStrictlyNaN(num)) { + throw new Error( + 'invalid duration value: Invalid number "' + number + '" before "' + letter + '"' + ); + } + object[type] = num; + } + + return 1; +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * @ignore + * @typedef {import("./types.js").jCalComponent} jCalComponent + * Imports the 'occurrenceDetails' type from the "types.js" module + */ + +/** + * This class represents the "period" value type, with various calculation and manipulation methods. + * + * @memberof ICAL + */ +class Period { + /** + * Creates a new {@link ICAL.Period} instance from the passed string. + * + * @param {String} str The string to parse + * @param {Property} prop The property this period will be on + * @return {Period} The created period instance + */ + static fromString(str, prop) { + let parts = str.split('/'); + + if (parts.length !== 2) { + throw new Error( + 'Invalid string value: "' + str + '" must contain a "/" char.' + ); + } + + let options = { + start: Time.fromDateTimeString(parts[0], prop) + }; + + let end = parts[1]; + + if (Duration.isValueString(end)) { + options.duration = Duration.fromString(end); + } else { + options.end = Time.fromDateTimeString(end, prop); + } + + return new Period(options); + } + + /** + * Creates a new {@link ICAL.Period} instance from the given data object. + * The passed data object cannot contain both and end date and a duration. + * + * @param {Object} aData An object with members of the period + * @param {Time=} aData.start The start of the period + * @param {Time=} aData.end The end of the period + * @param {Duration=} aData.duration The duration of the period + * @return {Period} The period instance + */ + static fromData(aData) { + return new Period(aData); + } + + /** + * Returns a new period instance from the given jCal data array. The first + * member is always the start date string, the second member is either a + * duration or end date string. + * + * @param {jCalComponent} aData The jCal data array + * @param {Property} aProp The property this jCal data is on + * @param {Boolean} aLenient If true, data value can be both date and date-time + * @return {Period} The period instance + */ + static fromJSON(aData, aProp, aLenient) { + function fromDateOrDateTimeString(aValue, dateProp) { + if (aLenient) { + return Time.fromString(aValue, dateProp); + } else { + return Time.fromDateTimeString(aValue, dateProp); + } + } + + if (Duration.isValueString(aData[1])) { + return Period.fromData({ + start: fromDateOrDateTimeString(aData[0], aProp), + duration: Duration.fromString(aData[1]) + }); + } else { + return Period.fromData({ + start: fromDateOrDateTimeString(aData[0], aProp), + end: fromDateOrDateTimeString(aData[1], aProp) + }); + } + } + + /** + * Creates a new ICAL.Period instance. The passed data object cannot contain both and end date and + * a duration. + * + * @param {Object} aData An object with members of the period + * @param {Time=} aData.start The start of the period + * @param {Time=} aData.end The end of the period + * @param {Duration=} aData.duration The duration of the period + */ + constructor(aData) { + this.wrappedJSObject = this; + + if (aData && 'start' in aData) { + if (aData.start && !(aData.start instanceof Time)) { + throw new TypeError('.start must be an instance of ICAL.Time'); + } + this.start = aData.start; + } + + if (aData && aData.end && aData.duration) { + throw new Error('cannot accept both end and duration'); + } + + if (aData && 'end' in aData) { + if (aData.end && !(aData.end instanceof Time)) { + throw new TypeError('.end must be an instance of ICAL.Time'); + } + this.end = aData.end; + } + + if (aData && 'duration' in aData) { + if (aData.duration && !(aData.duration instanceof Duration)) { + throw new TypeError('.duration must be an instance of ICAL.Duration'); + } + this.duration = aData.duration; + } + } + + + /** + * The start of the period + * @type {Time} + */ + start = null; + + /** + * The end of the period + * @type {Time} + */ + end = null; + + /** + * The duration of the period + * @type {Duration} + */ + duration = null; + + /** + * The class identifier. + * @constant + * @type {String} + * @default "icalperiod" + */ + icalclass = "icalperiod"; + + /** + * The type name, to be used in the jCal object. + * @constant + * @type {String} + * @default "period" + */ + icaltype = "period"; + + /** + * Returns a clone of the duration object. + * + * @return {Period} The cloned object + */ + clone() { + return Period.fromData({ + start: this.start ? this.start.clone() : null, + end: this.end ? this.end.clone() : null, + duration: this.duration ? this.duration.clone() : null + }); + } + + /** + * Calculates the duration of the period, either directly or by subtracting + * start from end date. + * + * @return {Duration} The calculated duration + */ + getDuration() { + if (this.duration) { + return this.duration; + } else { + return this.end.subtractDate(this.start); + } + } + + /** + * Calculates the end date of the period, either directly or by adding + * duration to start date. + * + * @return {Time} The calculated end date + */ + getEnd() { + if (this.end) { + return this.end; + } else { + let end = this.start.clone(); + end.addDuration(this.duration); + return end; + } + } + + /** + * Compare this period with a date or other period. To maintain the logic where a.compare(b) + * returns 1 when a > b, this function will return 1 when the period is after the date, 0 when the + * date is within the period, and -1 when the period is before the date. When comparing two + * periods, as soon as they overlap in any way this will return 0. + * + * @param {Time|Period} dt The date or other period to compare with + */ + compare(dt) { + if (dt.compare(this.start) < 0) { + return 1; + } else if (dt.compare(this.getEnd()) > 0) { + return -1; + } else { + return 0; + } + } + + /** + * The string representation of this period. + * @return {String} + */ + toString() { + return this.start + "/" + (this.end || this.duration); + } + + /** + * The jCal representation of this period type. + * @return {Object} + */ + toJSON() { + return [this.start.toString(), (this.end || this.duration).toString()]; + } + + /** + * The iCalendar string representation of this period. + * @return {String} + */ + toICALString() { + return this.start.toICALString() + "/" + + (this.end || this.duration).toICALString(); + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * + * @ignore + * @typedef {import("./types.js").weekDay} weekDay + * Imports the 'weekDay' type from the "types.js" module + * + * @ignore + * @typedef {import("./types.js").timeInit} timeInit + * Imports the 'timeInit' type from the "types.js" module + */ + +/** + * @classdesc + * iCalendar Time representation (similar to JS Date object). Fully + * independent of system (OS) timezone / time. Unlike JS Date, the month + * January is 1, not zero. + * + * @example + * var time = new ICAL.Time({ + * year: 2012, + * month: 10, + * day: 11 + * minute: 0, + * second: 0, + * isDate: false + * }); + * + * + * @memberof ICAL +*/ +class Time { + static _dowCache = {}; + static _wnCache = {}; + + /** + * Returns the days in the given month + * + * @param {Number} month The month to check + * @param {Number} year The year to check + * @return {Number} The number of days in the month + */ + static daysInMonth(month, year) { + let _daysInMonth = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + let days = 30; + + if (month < 1 || month > 12) return days; + + days = _daysInMonth[month]; + + if (month == 2) { + days += Time.isLeapYear(year); + } + + return days; + } + + /** + * Checks if the year is a leap year + * + * @param {Number} year The year to check + * @return {Boolean} True, if the year is a leap year + */ + static isLeapYear(year) { + if (year <= 1752) { + return ((year % 4) == 0); + } else { + return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)); + } + } + + /** + * Create a new ICAL.Time from the day of year and year. The date is returned + * in floating timezone. + * + * @param {Number} aDayOfYear The day of year + * @param {Number} aYear The year to create the instance in + * @return {Time} The created instance with the calculated date + */ + static fromDayOfYear(aDayOfYear, aYear) { + let year = aYear; + let doy = aDayOfYear; + let tt = new Time(); + tt.auto_normalize = false; + let is_leap = (Time.isLeapYear(year) ? 1 : 0); + + if (doy < 1) { + year--; + is_leap = (Time.isLeapYear(year) ? 1 : 0); + doy += Time.daysInYearPassedMonth[is_leap][12]; + return Time.fromDayOfYear(doy, year); + } else if (doy > Time.daysInYearPassedMonth[is_leap][12]) { + is_leap = (Time.isLeapYear(year) ? 1 : 0); + doy -= Time.daysInYearPassedMonth[is_leap][12]; + year++; + return Time.fromDayOfYear(doy, year); + } + + tt.year = year; + tt.isDate = true; + + for (let month = 11; month >= 0; month--) { + if (doy > Time.daysInYearPassedMonth[is_leap][month]) { + tt.month = month + 1; + tt.day = doy - Time.daysInYearPassedMonth[is_leap][month]; + break; + } + } + + tt.auto_normalize = true; + return tt; + } + + /** + * Returns a new ICAL.Time instance from a date string, e.g 2015-01-02. + * + * @deprecated Use {@link ICAL.Time.fromDateString} instead + * @param {String} str The string to create from + * @return {Time} The date/time instance + */ + static fromStringv2(str) { + return new Time({ + year: parseInt(str.slice(0, 4), 10), + month: parseInt(str.slice(5, 7), 10), + day: parseInt(str.slice(8, 10), 10), + isDate: true + }); + } + + /** + * Returns a new ICAL.Time instance from a date string, e.g 2015-01-02. + * + * @param {String} aValue The string to create from + * @return {Time} The date/time instance + */ + static fromDateString(aValue) { + // Dates should have no timezone. + // Google likes to sometimes specify Z on dates + // we specifically ignore that to avoid issues. + + // YYYY-MM-DD + // 2012-10-10 + return new Time({ + year: strictParseInt(aValue.slice(0, 4)), + month: strictParseInt(aValue.slice(5, 7)), + day: strictParseInt(aValue.slice(8, 10)), + isDate: true + }); + } + + /** + * Returns a new ICAL.Time instance from a date-time string, e.g + * 2015-01-02T03:04:05. If a property is specified, the timezone is set up + * from the property's TZID parameter. + * + * @param {String} aValue The string to create from + * @param {Property=} prop The property the date belongs to + * @return {Time} The date/time instance + */ + static fromDateTimeString(aValue, prop) { + if (aValue.length < 19) { + throw new Error( + 'invalid date-time value: "' + aValue + '"' + ); + } + + let zone; + let zoneId; + + if (aValue.slice(-1) === 'Z') { + zone = Timezone.utcTimezone; + } else if (prop) { + zoneId = prop.getParameter('tzid'); + + if (prop.parent) { + if (prop.parent.name === 'standard' || prop.parent.name === 'daylight') { + // Per RFC 5545 3.8.2.4 and 3.8.2.2, start/end date-times within + // these components MUST be specified in local time. + zone = Timezone.localTimezone; + } else if (zoneId) { + // If the desired time zone is defined within the component tree, + // fetch its definition and prefer that. + zone = prop.parent.getTimeZoneByID(zoneId); + } + } + } + + const timeData = { + year: strictParseInt(aValue.slice(0, 4)), + month: strictParseInt(aValue.slice(5, 7)), + day: strictParseInt(aValue.slice(8, 10)), + hour: strictParseInt(aValue.slice(11, 13)), + minute: strictParseInt(aValue.slice(14, 16)), + second: strictParseInt(aValue.slice(17, 19)), + }; + + // Although RFC 5545 requires that all TZIDs used within a file have a + // corresponding time zone definition, we may not be parsing the full file + // or we may be dealing with a non-compliant file; in either case, we can + // check our own time zone service for the TZID in a last-ditch effort. + if (zoneId && !zone) { + timeData.timezone = zoneId; + } + + // 2012-10-10T10:10:10(Z)? + return new Time(timeData, zone); + } + + /** + * Returns a new ICAL.Time instance from a date or date-time string, + * + * @param {String} aValue The string to create from + * @param {Property=} prop The property the date belongs to + * @return {Time} The date/time instance + */ + static fromString(aValue, aProperty) { + if (aValue.length > 10) { + return Time.fromDateTimeString(aValue, aProperty); + } else { + return Time.fromDateString(aValue); + } + } + + /** + * Creates a new ICAL.Time instance from the given Javascript Date. + * + * @param {?Date} aDate The Javascript Date to read, or null to reset + * @param {Boolean} [useUTC=false] If true, the UTC values of the date will be used + */ + static fromJSDate(aDate, useUTC) { + let tt = new Time(); + return tt.fromJSDate(aDate, useUTC); + } + + /** + * Creates a new ICAL.Time instance from the the passed data object. + * + * @param {timeInit} aData Time initialization + * @param {Timezone=} aZone Timezone this position occurs in + */ + static fromData = function fromData(aData, aZone) { + let t = new Time(); + return t.fromData(aData, aZone); + }; + + /** + * Creates a new ICAL.Time instance from the current moment. + * The instance is “floating” - has no timezone relation. + * To create an instance considering the time zone, call + * ICAL.Time.fromJSDate(new Date(), true) + * @return {Time} + */ + static now() { + return Time.fromJSDate(new Date(), false); + } + + /** + * Returns the date on which ISO week number 1 starts. + * + * @see Time#weekNumber + * @param {Number} aYear The year to search in + * @param {weekDay=} aWeekStart The week start weekday, used for calculation. + * @return {Time} The date on which week number 1 starts + */ + static weekOneStarts(aYear, aWeekStart) { + let t = Time.fromData({ + year: aYear, + month: 1, + day: 1, + isDate: true + }); + + let dow = t.dayOfWeek(); + let wkst = aWeekStart || Time.DEFAULT_WEEK_START; + if (dow > Time.THURSDAY) { + t.day += 7; + } + if (wkst > Time.THURSDAY) { + t.day -= 7; + } + + t.day -= dow - wkst; + + return t; + } + + /** + * Get the dominical letter for the given year. Letters range from A - G for + * common years, and AG to GF for leap years. + * + * @param {Number} yr The year to retrieve the letter for + * @return {String} The dominical letter. + */ + static getDominicalLetter(yr) { + let LTRS = "GFEDCBA"; + let dom = (yr + (yr / 4 | 0) + (yr / 400 | 0) - (yr / 100 | 0) - 1) % 7; + let isLeap = Time.isLeapYear(yr); + if (isLeap) { + return LTRS[(dom + 6) % 7] + LTRS[dom]; + } else { + return LTRS[dom]; + } + } + + static #epochTime = null; + /** + * January 1st, 1970 as an ICAL.Time. + * @type {Time} + * @constant + * @instance + */ + static get epochTime() { + if (!this.#epochTime) { + this.#epochTime = Time.fromData({ + year: 1970, + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + isDate: false, + timezone: "Z" + }); + } + return this.#epochTime; + } + + static _cmp_attr(a, b, attr) { + if (a[attr] > b[attr]) return 1; + if (a[attr] < b[attr]) return -1; + return 0; + } + + /** + * The days that have passed in the year after a given month. The array has + * two members, one being an array of passed days for non-leap years, the + * other analog for leap years. + * @example + * var isLeapYear = ICAL.Time.isLeapYear(year); + * var passedDays = ICAL.Time.daysInYearPassedMonth[isLeapYear][month]; + * @type {Array.>} + */ + static daysInYearPassedMonth = [ + [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365], + [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366] + ]; + + static SUNDAY = 1; + static MONDAY = 2; + static TUESDAY = 3; + static WEDNESDAY = 4; + static THURSDAY = 5; + static FRIDAY = 6; + static SATURDAY = 7; + + /** + * The default weekday for the WKST part. + * @constant + * @default ICAL.Time.MONDAY + */ + static DEFAULT_WEEK_START = 2; // MONDAY + + /** + * Creates a new ICAL.Time instance. + * + * @param {timeInit} data Time initialization + * @param {Timezone} zone timezone this position occurs in + */ + constructor(data, zone) { + this.wrappedJSObject = this; + + /** + * @type {timeInit} + * @private + */ + this._time = Object.create(null); + + /* time defaults */ + this._time.year = 0; + this._time.month = 1; + this._time.day = 1; + this._time.hour = 0; + this._time.minute = 0; + this._time.second = 0; + this._time.isDate = false; + + this.fromData(data, zone); + } + + /** + * The class identifier. + * @constant + * @type {String} + * @default "icaltime" + */ + icalclass = "icaltime"; + _cachedUnixTime = null; + + /** + * The type name, to be used in the jCal object. This value may change and + * is strictly defined by the {@link ICAL.Time#isDate isDate} member. + * @type {String} + * @default "date-time" + */ + get icaltype() { + return this.isDate ? 'date' : 'date-time'; + } + + /** + * The timezone for this time. + * @type {Timezone} + */ + zone = null; + + /** + * Internal uses to indicate that a change has been made and the next read + * operation must attempt to normalize the value (for example changing the + * day to 33). + * + * @type {Boolean} + * @private + */ + _pendingNormalization = false; + + /** + * The year of this date. + * @type {Number} + */ + get year() { + return this._getTimeAttr('year'); + } + + set year(val) { + this._setTimeAttr('year', val); + } + + /** + * The month of this date. + * @type {Number} + */ + get month() { + return this._getTimeAttr('month'); + } + + set month(val) { + this._setTimeAttr('month', val); + } + + /** + * The day of this date. + * @type {Number} + */ + get day() { + return this._getTimeAttr('day'); + } + + set day(val) { + this._setTimeAttr('day', val); + } + + /** + * The hour of this date-time. + * @type {Number} + */ + get hour() { + return this._getTimeAttr('hour'); + } + + set hour(val) { + this._setTimeAttr('hour', val); + } + + /** + * The minute of this date-time. + * @type {Number} + */ + get minute() { + return this._getTimeAttr('minute'); + } + + set minute(val) { + this._setTimeAttr('minute', val); + } + + /** + * The second of this date-time. + * @type {Number} + */ + get second() { + return this._getTimeAttr('second'); + } + + set second(val) { + this._setTimeAttr('second', val); + } + + /** + * If true, the instance represents a date (as opposed to a date-time) + * @type {Boolean} + */ + get isDate() { + return this._getTimeAttr('isDate'); + } + + set isDate(val) { + this._setTimeAttr('isDate', val); + } + + /** + * @private + * @param {String} attr Attribute to get (one of: year, month, + * day, hour, minute, second, isDate) + * @return {Number|Boolean} Current value for the attribute + */ + _getTimeAttr(attr) { + if (this._pendingNormalization) { + this._normalize(); + this._pendingNormalization = false; + } + + return this._time[attr]; + } + + /** + * @private + * @param {String} attr Attribute to set (one of: year, month, + * day, hour, minute, second, isDate) + * @param {Number|Boolean} val New value for the attribute + */ + _setTimeAttr(attr, val) { + // Check if isDate will be set and if was not set to normalize date. + // This avoids losing days when seconds, minutes and hours are zeroed + // what normalize will do when time is a date. + if (attr === "isDate" && val && !this._time.isDate) { + this.adjust(0, 0, 0, 0); + } + this._cachedUnixTime = null; + this._pendingNormalization = true; + this._time[attr] = val; + } + + /** + * Returns a clone of the time object. + * + * @return {Time} The cloned object + */ + clone() { + return new Time(this._time, this.zone); + } + + /** + * Reset the time instance to epoch time + */ + reset() { + this.fromData(Time.epochTime); + this.zone = Timezone.utcTimezone; + } + + /** + * Reset the time instance to the given date/time values. + * + * @param {Number} year The year to set + * @param {Number} month The month to set + * @param {Number} day The day to set + * @param {Number} hour The hour to set + * @param {Number} minute The minute to set + * @param {Number} second The second to set + * @param {Timezone} timezone The timezone to set + */ + resetTo(year, month, day, hour, minute, second, timezone) { + this.fromData({ + year: year, + month: month, + day: day, + hour: hour, + minute: minute, + second: second, + zone: timezone + }); + } + + /** + * Set up the current instance from the Javascript date value. + * + * @param {?Date} aDate The Javascript Date to read, or null to reset + * @param {Boolean} [useUTC=false] If true, the UTC values of the date will be used + */ + fromJSDate(aDate, useUTC) { + if (!aDate) { + this.reset(); + } else { + if (useUTC) { + this.zone = Timezone.utcTimezone; + this.year = aDate.getUTCFullYear(); + this.month = aDate.getUTCMonth() + 1; + this.day = aDate.getUTCDate(); + this.hour = aDate.getUTCHours(); + this.minute = aDate.getUTCMinutes(); + this.second = aDate.getUTCSeconds(); + } else { + this.zone = Timezone.localTimezone; + this.year = aDate.getFullYear(); + this.month = aDate.getMonth() + 1; + this.day = aDate.getDate(); + this.hour = aDate.getHours(); + this.minute = aDate.getMinutes(); + this.second = aDate.getSeconds(); + } + } + this._cachedUnixTime = null; + return this; + } + + /** + * Sets up the current instance using members from the passed data object. + * + * @param {timeInit} aData Time initialization + * @param {Timezone=} aZone Timezone this position occurs in + */ + fromData(aData, aZone) { + if (aData) { + for (let [key, value] of Object.entries(aData)) { + // ical type cannot be set + if (key === 'icaltype') continue; + this[key] = value; + } + } + + if (aZone) { + this.zone = aZone; + } + + if (aData && !("isDate" in aData)) { + this.isDate = !("hour" in aData); + } else if (aData && ("isDate" in aData)) { + this.isDate = aData.isDate; + } + + if (aData && "timezone" in aData) { + let zone = TimezoneService.get( + aData.timezone + ); + + this.zone = zone || Timezone.localTimezone; + } + + if (aData && "zone" in aData) { + this.zone = aData.zone; + } + + if (!this.zone) { + this.zone = Timezone.localTimezone; + } + + this._cachedUnixTime = null; + return this; + } + + /** + * Calculate the day of week. + * @param {weekDay=} aWeekStart + * The week start weekday, defaults to SUNDAY + * @return {weekDay} + */ + dayOfWeek(aWeekStart) { + let firstDow = aWeekStart || Time.SUNDAY; + let dowCacheKey = (this.year << 12) + (this.month << 8) + (this.day << 3) + firstDow; + if (dowCacheKey in Time._dowCache) { + return Time._dowCache[dowCacheKey]; + } + + // Using Zeller's algorithm + let q = this.day; + let m = this.month + (this.month < 3 ? 12 : 0); + let Y = this.year - (this.month < 3 ? 1 : 0); + + let h = (q + Y + trunc(((m + 1) * 26) / 10) + trunc(Y / 4)); + { // eslint-disable-line no-constant-condition + h += trunc(Y / 100) * 6 + trunc(Y / 400); + } + + // Normalize to 1 = wkst + h = ((h + 7 - firstDow) % 7) + 1; + Time._dowCache[dowCacheKey] = h; + return h; + } + + /** + * Calculate the day of year. + * @return {Number} + */ + dayOfYear() { + let is_leap = (Time.isLeapYear(this.year) ? 1 : 0); + let diypm = Time.daysInYearPassedMonth; + return diypm[is_leap][this.month - 1] + this.day; + } + + /** + * Returns a copy of the current date/time, rewound to the start of the + * week. The resulting ICAL.Time instance is of icaltype date, even if this + * is a date-time. + * + * @param {weekDay=} aWeekStart + * The week start weekday, defaults to SUNDAY + * @return {Time} The start of the week (cloned) + */ + startOfWeek(aWeekStart) { + let firstDow = aWeekStart || Time.SUNDAY; + let result = this.clone(); + result.day -= ((this.dayOfWeek() + 7 - firstDow) % 7); + result.isDate = true; + result.hour = 0; + result.minute = 0; + result.second = 0; + return result; + } + + /** + * Returns a copy of the current date/time, shifted to the end of the week. + * The resulting ICAL.Time instance is of icaltype date, even if this is a + * date-time. + * + * @param {weekDay=} aWeekStart + * The week start weekday, defaults to SUNDAY + * @return {Time} The end of the week (cloned) + */ + endOfWeek(aWeekStart) { + let firstDow = aWeekStart || Time.SUNDAY; + let result = this.clone(); + result.day += (7 - this.dayOfWeek() + firstDow - Time.SUNDAY) % 7; + result.isDate = true; + result.hour = 0; + result.minute = 0; + result.second = 0; + return result; + } + + /** + * Returns a copy of the current date/time, rewound to the start of the + * month. The resulting ICAL.Time instance is of icaltype date, even if + * this is a date-time. + * + * @return {Time} The start of the month (cloned) + */ + startOfMonth() { + let result = this.clone(); + result.day = 1; + result.isDate = true; + result.hour = 0; + result.minute = 0; + result.second = 0; + return result; + } + + /** + * Returns a copy of the current date/time, shifted to the end of the + * month. The resulting ICAL.Time instance is of icaltype date, even if + * this is a date-time. + * + * @return {Time} The end of the month (cloned) + */ + endOfMonth() { + let result = this.clone(); + result.day = Time.daysInMonth(result.month, result.year); + result.isDate = true; + result.hour = 0; + result.minute = 0; + result.second = 0; + return result; + } + + /** + * Returns a copy of the current date/time, rewound to the start of the + * year. The resulting ICAL.Time instance is of icaltype date, even if + * this is a date-time. + * + * @return {Time} The start of the year (cloned) + */ + startOfYear() { + let result = this.clone(); + result.day = 1; + result.month = 1; + result.isDate = true; + result.hour = 0; + result.minute = 0; + result.second = 0; + return result; + } + + /** + * Returns a copy of the current date/time, shifted to the end of the + * year. The resulting ICAL.Time instance is of icaltype date, even if + * this is a date-time. + * + * @return {Time} The end of the year (cloned) + */ + endOfYear() { + let result = this.clone(); + result.day = 31; + result.month = 12; + result.isDate = true; + result.hour = 0; + result.minute = 0; + result.second = 0; + return result; + } + + /** + * First calculates the start of the week, then returns the day of year for + * this date. If the day falls into the previous year, the day is zero or negative. + * + * @param {weekDay=} aFirstDayOfWeek + * The week start weekday, defaults to SUNDAY + * @return {Number} The calculated day of year + */ + startDoyWeek(aFirstDayOfWeek) { + let firstDow = aFirstDayOfWeek || Time.SUNDAY; + let delta = this.dayOfWeek() - firstDow; + if (delta < 0) delta += 7; + return this.dayOfYear() - delta; + } + + /** + * Get the dominical letter for the current year. Letters range from A - G + * for common years, and AG to GF for leap years. + * + * @param {Number} yr The year to retrieve the letter for + * @return {String} The dominical letter. + */ + getDominicalLetter() { + return Time.getDominicalLetter(this.year); + } + + /** + * Finds the nthWeekDay relative to the current month (not day). The + * returned value is a day relative the month that this month belongs to so + * 1 would indicate the first of the month and 40 would indicate a day in + * the following month. + * + * @param {Number} aDayOfWeek Day of the week see the day name constants + * @param {Number} aPos Nth occurrence of a given week day values + * of 1 and 0 both indicate the first weekday of that type. aPos may + * be either positive or negative + * + * @return {Number} numeric value indicating a day relative + * to the current month of this time object + */ + nthWeekDay(aDayOfWeek, aPos) { + let daysInMonth = Time.daysInMonth(this.month, this.year); + let weekday; + let pos = aPos; + + let start = 0; + + let otherDay = this.clone(); + + if (pos >= 0) { + otherDay.day = 1; + + // because 0 means no position has been given + // 1 and 0 indicate the same day. + if (pos != 0) { + // remove the extra numeric value + pos--; + } + + // set current start offset to current day. + start = otherDay.day; + + // find the current day of week + let startDow = otherDay.dayOfWeek(); + + // calculate the difference between current + // day of the week and desired day of the week + let offset = aDayOfWeek - startDow; + + + // if the offset goes into the past + // week we add 7 so it goes into the next + // week. We only want to go forward in time here. + if (offset < 0) + // this is really important otherwise we would + // end up with dates from in the past. + offset += 7; + + // add offset to start so start is the same + // day of the week as the desired day of week. + start += offset; + + // because we are going to add (and multiply) + // the numeric value of the day we subtract it + // from the start position so not to add it twice. + start -= aDayOfWeek; + + // set week day + weekday = aDayOfWeek; + } else { + + // then we set it to the last day in the current month + otherDay.day = daysInMonth; + + // find the ends weekday + let endDow = otherDay.dayOfWeek(); + + pos++; + + weekday = (endDow - aDayOfWeek); + + if (weekday < 0) { + weekday += 7; + } + + weekday = daysInMonth - weekday; + } + + weekday += pos * 7; + + return start + weekday; + } + + /** + * Checks if current time is the nth weekday, relative to the current + * month. Will always return false when rule resolves outside of current + * month. + * + * @param {weekDay} aDayOfWeek Day of week to check + * @param {Number} aPos Relative position + * @return {Boolean} True, if it is the nth weekday + */ + isNthWeekDay(aDayOfWeek, aPos) { + let dow = this.dayOfWeek(); + + if (aPos === 0 && dow === aDayOfWeek) { + return true; + } + + // get pos + let day = this.nthWeekDay(aDayOfWeek, aPos); + + if (day === this.day) { + return true; + } + + return false; + } + + /** + * Calculates the ISO 8601 week number. The first week of a year is the + * week that contains the first Thursday. The year can have 53 weeks, if + * January 1st is a Friday. + * + * Note there are regions where the first week of the year is the one that + * starts on January 1st, which may offset the week number. Also, if a + * different week start is specified, this will also affect the week + * number. + * + * @see Time.weekOneStarts + * @param {weekDay} aWeekStart The weekday the week starts with + * @return {Number} The ISO week number + */ + weekNumber(aWeekStart) { + let wnCacheKey = (this.year << 12) + (this.month << 8) + (this.day << 3) + aWeekStart; + if (wnCacheKey in Time._wnCache) { + return Time._wnCache[wnCacheKey]; + } + // This function courtesty of Julian Bucknall, published under the MIT license + // http://www.boyet.com/articles/publishedarticles/calculatingtheisoweeknumb.html + // plus some fixes to be able to use different week starts. + let week1; + + let dt = this.clone(); + dt.isDate = true; + let isoyear = this.year; + + if (dt.month == 12 && dt.day > 25) { + week1 = Time.weekOneStarts(isoyear + 1, aWeekStart); + if (dt.compare(week1) < 0) { + week1 = Time.weekOneStarts(isoyear, aWeekStart); + } else { + isoyear++; + } + } else { + week1 = Time.weekOneStarts(isoyear, aWeekStart); + if (dt.compare(week1) < 0) { + week1 = Time.weekOneStarts(--isoyear, aWeekStart); + } + } + + let daysBetween = (dt.subtractDate(week1).toSeconds() / 86400); + let answer = trunc(daysBetween / 7) + 1; + Time._wnCache[wnCacheKey] = answer; + return answer; + } + + /** + * Adds the duration to the current time. The instance is modified in + * place. + * + * @param {Duration} aDuration The duration to add + */ + addDuration(aDuration) { + let mult = (aDuration.isNegative ? -1 : 1); + + // because of the duration optimizations it is much + // more efficient to grab all the values up front + // then set them directly (which will avoid a normalization call). + // So we don't actually normalize until we need it. + let second = this.second; + let minute = this.minute; + let hour = this.hour; + let day = this.day; + + second += mult * aDuration.seconds; + minute += mult * aDuration.minutes; + hour += mult * aDuration.hours; + day += mult * aDuration.days; + day += mult * 7 * aDuration.weeks; + + this.second = second; + this.minute = minute; + this.hour = hour; + this.day = day; + + this._cachedUnixTime = null; + } + + /** + * Subtract the date details (_excluding_ timezone). Useful for finding + * the relative difference between two time objects excluding their + * timezone differences. + * + * @param {Time} aDate The date to subtract + * @return {Duration} The difference as a duration + */ + subtractDate(aDate) { + let unixTime = this.toUnixTime() + this.utcOffset(); + let other = aDate.toUnixTime() + aDate.utcOffset(); + return Duration.fromSeconds(unixTime - other); + } + + /** + * Subtract the date details, taking timezones into account. + * + * @param {Time} aDate The date to subtract + * @return {Duration} The difference in duration + */ + subtractDateTz(aDate) { + let unixTime = this.toUnixTime(); + let other = aDate.toUnixTime(); + return Duration.fromSeconds(unixTime - other); + } + + /** + * Compares the ICAL.Time instance with another one, or a period. + * + * @param {Time|Period} aOther The instance to compare with + * @return {Number} -1, 0 or 1 for less/equal/greater + */ + compare(other) { + if (other instanceof Period) { + return -1 * other.compare(this); + } else { + let a = this.toUnixTime(); + let b = other.toUnixTime(); + + if (a > b) return 1; + if (b > a) return -1; + return 0; + } + } + + /** + * Compares only the date part of this instance with another one. + * + * @param {Time} other The instance to compare with + * @param {Timezone} tz The timezone to compare in + * @return {Number} -1, 0 or 1 for less/equal/greater + */ + compareDateOnlyTz(other, tz) { + let a = this.convertToZone(tz); + let b = other.convertToZone(tz); + let rc = 0; + + if ((rc = Time._cmp_attr(a, b, "year")) != 0) return rc; + if ((rc = Time._cmp_attr(a, b, "month")) != 0) return rc; + if ((rc = Time._cmp_attr(a, b, "day")) != 0) return rc; + + return rc; + } + + /** + * Convert the instance into another timezone. The returned ICAL.Time + * instance is always a copy. + * + * @param {Timezone} zone The zone to convert to + * @return {Time} The copy, converted to the zone + */ + convertToZone(zone) { + let copy = this.clone(); + let zone_equals = (this.zone.tzid == zone.tzid); + + if (!this.isDate && !zone_equals) { + Timezone.convert_time(copy, this.zone, zone); + } + + copy.zone = zone; + return copy; + } + + /** + * Calculates the UTC offset of the current date/time in the timezone it is + * in. + * + * @return {Number} UTC offset in seconds + */ + utcOffset() { + if (this.zone == Timezone.localTimezone || + this.zone == Timezone.utcTimezone) { + return 0; + } else { + return this.zone.utcOffset(this); + } + } + + /** + * Returns an RFC 5545 compliant ical representation of this object. + * + * @return {String} ical date/date-time + */ + toICALString() { + let string = this.toString(); + + if (string.length > 10) { + return design.icalendar.value['date-time'].toICAL(string); + } else { + return design.icalendar.value.date.toICAL(string); + } + } + + /** + * The string representation of this date/time, in jCal form + * (including : and - separators). + * @return {String} + */ + toString() { + let result = this.year + '-' + + pad2(this.month) + '-' + + pad2(this.day); + + if (!this.isDate) { + result += 'T' + pad2(this.hour) + ':' + + pad2(this.minute) + ':' + + pad2(this.second); + + if (this.zone === Timezone.utcTimezone) { + result += 'Z'; + } + } + + return result; + } + + /** + * Converts the current instance to a Javascript date + * @return {Date} + */ + toJSDate() { + if (this.zone == Timezone.localTimezone) { + if (this.isDate) { + return new Date(this.year, this.month - 1, this.day); + } else { + return new Date(this.year, this.month - 1, this.day, + this.hour, this.minute, this.second, 0); + } + } else { + return new Date(this.toUnixTime() * 1000); + } + } + + _normalize() { + if (this._time.isDate) { + this._time.hour = 0; + this._time.minute = 0; + this._time.second = 0; + } + this.adjust(0, 0, 0, 0); + + return this; + } + + /** + * Adjust the date/time by the given offset + * + * @param {Number} aExtraDays The extra amount of days + * @param {Number} aExtraHours The extra amount of hours + * @param {Number} aExtraMinutes The extra amount of minutes + * @param {Number} aExtraSeconds The extra amount of seconds + * @param {Number=} aTime The time to adjust, defaults to the + * current instance. + */ + adjust(aExtraDays, aExtraHours, aExtraMinutes, aExtraSeconds, aTime) { + + let minutesOverflow, hoursOverflow, + daysOverflow = 0, yearsOverflow = 0; + + let second, minute, hour, day; + let daysInMonth; + + let time = aTime || this._time; + + if (!time.isDate) { + second = time.second + aExtraSeconds; + time.second = second % 60; + minutesOverflow = trunc(second / 60); + if (time.second < 0) { + time.second += 60; + minutesOverflow--; + } + + minute = time.minute + aExtraMinutes + minutesOverflow; + time.minute = minute % 60; + hoursOverflow = trunc(minute / 60); + if (time.minute < 0) { + time.minute += 60; + hoursOverflow--; + } + + hour = time.hour + aExtraHours + hoursOverflow; + + time.hour = hour % 24; + daysOverflow = trunc(hour / 24); + if (time.hour < 0) { + time.hour += 24; + daysOverflow--; + } + } + + + // Adjust month and year first, because we need to know what month the day + // is in before adjusting it. + if (time.month > 12) { + yearsOverflow = trunc((time.month - 1) / 12); + } else if (time.month < 1) { + yearsOverflow = trunc(time.month / 12) - 1; + } + + time.year += yearsOverflow; + time.month -= 12 * yearsOverflow; + + // Now take care of the days (and adjust month if needed) + day = time.day + aExtraDays + daysOverflow; + + if (day > 0) { + for (;;) { + daysInMonth = Time.daysInMonth(time.month, time.year); + if (day <= daysInMonth) { + break; + } + + time.month++; + if (time.month > 12) { + time.year++; + time.month = 1; + } + + day -= daysInMonth; + } + } else { + while (day <= 0) { + if (time.month == 1) { + time.year--; + time.month = 12; + } else { + time.month--; + } + + day += Time.daysInMonth(time.month, time.year); + } + } + + time.day = day; + + this._cachedUnixTime = null; + return this; + } + + /** + * Sets up the current instance from unix time, the number of seconds since + * January 1st, 1970. + * + * @param {Number} seconds The seconds to set up with + */ + fromUnixTime(seconds) { + this.zone = Timezone.utcTimezone; + // We could use `fromJSDate` here, but this is about twice as fast. + // We could also clone `epochTime` and use `adjust` for a more + // ical.js-centric approach, but this is about 100 times as fast. + let date = new Date(seconds * 1000); + this.year = date.getUTCFullYear(); + this.month = date.getUTCMonth() + 1; + this.day = date.getUTCDate(); + if (this._time.isDate) { + this.hour = 0; + this.minute = 0; + this.second = 0; + } else { + this.hour = date.getUTCHours(); + this.minute = date.getUTCMinutes(); + this.second = date.getUTCSeconds(); + } + + this._cachedUnixTime = null; + } + + /** + * Converts the current instance to seconds since January 1st 1970. + * + * @return {Number} Seconds since 1970 + */ + toUnixTime() { + if (this._cachedUnixTime !== null) { + return this._cachedUnixTime; + } + let offset = this.utcOffset(); + + // we use the offset trick to ensure + // that we are getting the actual UTC time + let ms = Date.UTC( + this.year, + this.month - 1, + this.day, + this.hour, + this.minute, + this.second - offset + ); + + // seconds + this._cachedUnixTime = ms / 1000; + return this._cachedUnixTime; + } + + /** + * Converts time to into Object which can be serialized then re-created + * using the constructor. + * + * @example + * // toJSON will automatically be called + * var json = JSON.stringify(mytime); + * + * var deserialized = JSON.parse(json); + * + * var time = new ICAL.Time(deserialized); + * + * @return {Object} + */ + toJSON() { + let copy = [ + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'isDate' + ]; + + let result = Object.create(null); + + let i = 0; + let len = copy.length; + let prop; + + for (; i < len; i++) { + prop = copy[i]; + result[prop] = this[prop]; + } + + if (this.zone) { + result.timezone = this.zone.tzid; + } + + return result; + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * + * @ignore + * @typedef {import("./types.js").parserState} parserState + * Imports the 'parserState' type from the "types.js" module + * @typedef {import("./types.js").designSet} designSet + * Imports the 'designSet' type from the "types.js" module + */ + +const CHAR = /[^ \t]/; +const VALUE_DELIMITER = ':'; +const PARAM_DELIMITER = ';'; +const PARAM_NAME_DELIMITER = '='; +const DEFAULT_VALUE_TYPE$1 = 'unknown'; +const DEFAULT_PARAM_TYPE = 'text'; +const RFC6868_REPLACE_MAP$1 = { "^'": '"', "^n": "\n", "^^": "^" }; + +/** + * Parses iCalendar or vCard data into a raw jCal object. Consult + * documentation on the {@tutorial layers|layers of parsing} for more + * details. + * + * @function ICAL.parse + * @memberof ICAL + * @variation function + * @todo Fix the API to be more clear on the return type + * @param {String} input The string data to parse + * @return {Object|Object[]} A single jCal object, or an array thereof + */ +function parse(input) { + let state = {}; + let root = state.component = []; + + state.stack = [root]; + + parse._eachLine(input, function(err, line) { + parse._handleContentLine(line, state); + }); + + + // when there are still items on the stack + // throw a fatal error, a component was not closed + // correctly in that case. + if (state.stack.length > 1) { + throw new ParserError( + 'invalid ical body. component began but did not end' + ); + } + + state = null; + + return (root.length == 1 ? root[0] : root); +} + +/** + * Parse an iCalendar property value into the jCal for a single property + * + * @function ICAL.parse.property + * @param {String} str + * The iCalendar property string to parse + * @param {designSet=} designSet + * The design data to use for this property + * @return {Object} + * The jCal Object containing the property + */ +parse.property = function(str, designSet) { + let state = { + component: [[], []], + designSet: designSet || design.defaultSet + }; + parse._handleContentLine(str, state); + return state.component[1][0]; +}; + +/** + * Convenience method to parse a component. You can use ICAL.parse() directly + * instead. + * + * @function ICAL.parse.component + * @see ICAL.parse(function) + * @param {String} str The iCalendar component string to parse + * @return {Object} The jCal Object containing the component + */ +parse.component = function(str) { + return parse(str); +}; + + +/** + * An error that occurred during parsing. + * + * @param {String} message The error message + * @memberof ICAL.parse + * @extends {Error} + */ +class ParserError extends Error { + name = this.constructor.name; +} + +// classes & constants +parse.ParserError = ParserError; + + +/** + * Handles a single line of iCalendar/vCard, updating the state. + * + * @private + * @function ICAL.parse._handleContentLine + * @param {String} line The content line to process + * @param {parserState} state The current state of the line parsing + */ +parse._handleContentLine = function(line, state) { + // break up the parts of the line + let valuePos = line.indexOf(VALUE_DELIMITER); + let paramPos = line.indexOf(PARAM_DELIMITER); + + let lastParamIndex; + let lastValuePos; + + // name of property or begin/end + let name; + let value; + // params is only overridden if paramPos !== -1. + // we can't do params = params || {} later on + // because it sacrifices ops. + let params = {}; + + /** + * Different property cases + * + * + * 1. RRULE:FREQ=foo + * // FREQ= is not a param but the value + * + * 2. ATTENDEE;ROLE=REQ-PARTICIPANT; + * // ROLE= is a param because : has not happened yet + */ + // when the parameter delimiter is after the + // value delimiter then it is not a parameter. + + if ((paramPos !== -1 && valuePos !== -1)) { + // when the parameter delimiter is after the + // value delimiter then it is not a parameter. + if (paramPos > valuePos) { + paramPos = -1; + } + } + + let parsedParams; + if (paramPos !== -1) { + name = line.slice(0, Math.max(0, paramPos)).toLowerCase(); + parsedParams = parse._parseParameters(line.slice(Math.max(0, paramPos)), 0, state.designSet); + if (parsedParams[2] == -1) { + throw new ParserError("Invalid parameters in '" + line + "'"); + } + params = parsedParams[0]; + // Handle parameter values with multiple entries + let parsedParamLength; + if (typeof parsedParams[1] === 'string') { + parsedParamLength = parsedParams[1].length; + } else { + parsedParamLength = parsedParams[1].reduce((accumulator, currentValue) => { + return accumulator + currentValue.length; + }, 0); + } + lastParamIndex = parsedParamLength + parsedParams[2] + paramPos; + if ((lastValuePos = + line.slice(Math.max(0, lastParamIndex)).indexOf(VALUE_DELIMITER)) !== -1) { + value = line.slice(Math.max(0, lastParamIndex + lastValuePos + 1)); + } else { + throw new ParserError("Missing parameter value in '" + line + "'"); + } + } else if (valuePos !== -1) { + // without parmeters (BEGIN:VCAENDAR, CLASS:PUBLIC) + name = line.slice(0, Math.max(0, valuePos)).toLowerCase(); + value = line.slice(Math.max(0, valuePos + 1)); + + if (name === 'begin') { + let newComponent = [value.toLowerCase(), [], []]; + if (state.stack.length === 1) { + state.component.push(newComponent); + } else { + state.component[2].push(newComponent); + } + state.stack.push(state.component); + state.component = newComponent; + if (!state.designSet) { + state.designSet = design.getDesignSet(state.component[0]); + } + return; + } else if (name === 'end') { + state.component = state.stack.pop(); + return; + } + // If it is not begin/end, then this is a property with an empty value, + // which should be considered valid. + } else { + /** + * Invalid line. + * The rational to throw an error is we will + * never be certain that the rest of the file + * is sane and it is unlikely that we can serialize + * the result correctly either. + */ + throw new ParserError( + 'invalid line (no token ";" or ":") "' + line + '"' + ); + } + + let valueType; + let multiValue = false; + let structuredValue = false; + let propertyDetails; + let splitName; + let ungroupedName; + + // fetch the ungrouped part of the name + if (state.designSet.propertyGroups && name.indexOf('.') !== -1) { + splitName = name.split('.'); + params.group = splitName[0]; + ungroupedName = splitName[1]; + } else { + ungroupedName = name; + } + + if (ungroupedName in state.designSet.property) { + propertyDetails = state.designSet.property[ungroupedName]; + + if ('multiValue' in propertyDetails) { + multiValue = propertyDetails.multiValue; + } + + if ('structuredValue' in propertyDetails) { + structuredValue = propertyDetails.structuredValue; + } + + if (value && 'detectType' in propertyDetails) { + valueType = propertyDetails.detectType(value); + } + } + + // attempt to determine value + if (!valueType) { + if (!('value' in params)) { + if (propertyDetails) { + valueType = propertyDetails.defaultType; + } else { + valueType = DEFAULT_VALUE_TYPE$1; + } + } else { + // possible to avoid this? + valueType = params.value.toLowerCase(); + } + } + + delete params.value; + + /** + * Note on `var result` juggling: + * + * I observed that building the array in pieces has adverse + * effects on performance, so where possible we inline the creation. + * It is a little ugly but resulted in ~2000 additional ops/sec. + */ + + let result; + if (multiValue && structuredValue) { + value = parse._parseMultiValue(value, structuredValue, valueType, [], multiValue, state.designSet, structuredValue); + result = [ungroupedName, params, valueType, value]; + } else if (multiValue) { + result = [ungroupedName, params, valueType]; + parse._parseMultiValue(value, multiValue, valueType, result, null, state.designSet, false); + } else if (structuredValue) { + value = parse._parseMultiValue(value, structuredValue, valueType, [], null, state.designSet, structuredValue); + result = [ungroupedName, params, valueType, value]; + } else { + value = parse._parseValue(value, valueType, state.designSet, false); + result = [ungroupedName, params, valueType, value]; + } + // rfc6350 requires that in vCard 4.0 the first component is the VERSION + // component with as value 4.0, note that 3.0 does not have this requirement. + if (state.component[0] === 'vcard' && state.component[1].length === 0 && + !(name === 'version' && value === '4.0')) { + state.designSet = design.getDesignSet("vcard3"); + } + state.component[1].push(result); +}; + +/** + * Parse a value from the raw value into the jCard/jCal value. + * + * @private + * @function ICAL.parse._parseValue + * @param {String} value Original value + * @param {String} type Type of value + * @param {Object} designSet The design data to use for this value + * @return {Object} varies on type + */ +parse._parseValue = function(value, type, designSet, structuredValue) { + if (type in designSet.value && 'fromICAL' in designSet.value[type]) { + return designSet.value[type].fromICAL(value, structuredValue); + } + return value; +}; + +/** + * Parse parameters from a string to object. + * + * @function ICAL.parse._parseParameters + * @private + * @param {String} line A single unfolded line + * @param {Number} start Position to start looking for properties + * @param {Object} designSet The design data to use for this property + * @return {Array} Array containing key/valye pairs of parsed parameters, the + * parsed value, and the position of the last parameter found + */ +parse._parseParameters = function(line, start, designSet) { + let lastParam = start; + let pos = 0; + let delim = PARAM_NAME_DELIMITER; + let result = {}; + let name, lcname; + let value, valuePos = -1; + let type, multiValue, mvdelim; + + // find the next '=' sign + // use lastParam and pos to find name + // check if " is used if so get value from "->" + // then increment pos to find next ; + + while ((pos !== false) && + (pos = line.indexOf(delim, pos + 1)) !== -1) { + + name = line.slice(lastParam + 1, pos); + if (name.length == 0) { + throw new ParserError("Empty parameter name in '" + line + "'"); + } + lcname = name.toLowerCase(); + mvdelim = false; + multiValue = false; + + if (lcname in designSet.param && designSet.param[lcname].valueType) { + type = designSet.param[lcname].valueType; + } else { + type = DEFAULT_PARAM_TYPE; + } + + if (lcname in designSet.param) { + multiValue = designSet.param[lcname].multiValue; + if (designSet.param[lcname].multiValueSeparateDQuote) { + mvdelim = parse._rfc6868Escape('"' + multiValue + '"'); + } + } + + let nextChar = line[pos + 1]; + if (nextChar === '"') { + valuePos = pos + 2; + pos = line.indexOf('"', valuePos); + if (multiValue && pos != -1) { + let extendedValue = true; + while (extendedValue) { + if (line[pos + 1] == multiValue && line[pos + 2] == '"') { + pos = line.indexOf('"', pos + 3); + } else { + extendedValue = false; + } + } + } + if (pos === -1) { + throw new ParserError( + 'invalid line (no matching double quote) "' + line + '"' + ); + } + value = line.slice(valuePos, pos); + lastParam = line.indexOf(PARAM_DELIMITER, pos); + let propValuePos = line.indexOf(VALUE_DELIMITER, pos); + // if either no next parameter or delimeter in property value, let's stop here + if (lastParam === -1 || (propValuePos !== -1 && lastParam > propValuePos)) { + pos = false; + } + } else { + valuePos = pos + 1; + + // move to next ";" + let nextPos = line.indexOf(PARAM_DELIMITER, valuePos); + let propValuePos = line.indexOf(VALUE_DELIMITER, valuePos); + if (propValuePos !== -1 && nextPos > propValuePos) { + // this is a delimiter in the property value, let's stop here + nextPos = propValuePos; + pos = false; + } else if (nextPos === -1) { + // no ";" + if (propValuePos === -1) { + nextPos = line.length; + } else { + nextPos = propValuePos; + } + pos = false; + } else { + lastParam = nextPos; + pos = nextPos; + } + + value = line.slice(valuePos, nextPos); + } + + const length_before = value.length; + value = parse._rfc6868Escape(value); + valuePos += length_before - value.length; + if (multiValue) { + let delimiter = mvdelim || multiValue; + value = parse._parseMultiValue(value, delimiter, type, [], null, designSet); + } else { + value = parse._parseValue(value, type, designSet); + } + + if (multiValue && (lcname in result)) { + if (Array.isArray(result[lcname])) { + result[lcname].push(value); + } else { + result[lcname] = [ + result[lcname], + value + ]; + } + } else { + result[lcname] = value; + } + } + return [result, value, valuePos]; +}; + +/** + * Internal helper for rfc6868. Exposing this on ICAL.parse so that + * hackers can disable the rfc6868 parsing if the really need to. + * + * @function ICAL.parse._rfc6868Escape + * @param {String} val The value to escape + * @return {String} The escaped value + */ +parse._rfc6868Escape = function(val) { + return val.replace(/\^['n^]/g, function(x) { + return RFC6868_REPLACE_MAP$1[x]; + }); +}; + +/** + * Parse a multi value string. This function is used either for parsing + * actual multi-value property's values, or for handling parameter values. It + * can be used for both multi-value properties and structured value properties. + * + * @private + * @function ICAL.parse._parseMultiValue + * @param {String} buffer The buffer containing the full value + * @param {String} delim The multi-value delimiter + * @param {String} type The value type to be parsed + * @param {Array.} result The array to append results to, varies on value type + * @param {String} innerMulti The inner delimiter to split each value with + * @param {designSet} designSet The design data for this value + * @return {?|Array.} Either an array of results, or the first result + */ +parse._parseMultiValue = function(buffer, delim, type, result, innerMulti, designSet, structuredValue) { + let pos = 0; + let lastPos = 0; + let value; + if (delim.length === 0) { + return buffer; + } + + // split each piece + while ((pos = unescapedIndexOf(buffer, delim, lastPos)) !== -1) { + value = buffer.slice(lastPos, pos); + if (innerMulti) { + value = parse._parseMultiValue(value, innerMulti, type, [], null, designSet, structuredValue); + } else { + value = parse._parseValue(value, type, designSet, structuredValue); + } + result.push(value); + lastPos = pos + delim.length; + } + + // on the last piece take the rest of string + value = buffer.slice(lastPos); + if (innerMulti) { + value = parse._parseMultiValue(value, innerMulti, type, [], null, designSet, structuredValue); + } else { + value = parse._parseValue(value, type, designSet, structuredValue); + } + result.push(value); + + return result.length == 1 ? result[0] : result; +}; + +/** + * Process a complete buffer of iCalendar/vCard data line by line, correctly + * unfolding content. Each line will be processed with the given callback + * + * @private + * @function ICAL.parse._eachLine + * @param {String} buffer The buffer to process + * @param {function(?String, String)} callback The callback for each line + */ +parse._eachLine = function(buffer, callback) { + let len = buffer.length; + let lastPos = buffer.search(CHAR); + let pos = lastPos; + let line; + let firstChar; + + let newlineOffset; + + do { + pos = buffer.indexOf('\n', lastPos) + 1; + + if (pos > 1 && buffer[pos - 2] === '\r') { + newlineOffset = 2; + } else { + newlineOffset = 1; + } + + if (pos === 0) { + pos = len; + newlineOffset = 0; + } + + firstChar = buffer[lastPos]; + + if (firstChar === ' ' || firstChar === '\t') { + // add to line + line += buffer.slice(lastPos + 1, pos - newlineOffset); + } else { + if (line) + callback(null, line); + // push line + line = buffer.slice(lastPos, pos - newlineOffset); + } + + lastPos = pos; + } while (pos !== len); + + // extra ending line + line = line.trim(); + + if (line.length) + callback(null, line); +}; + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +const OPTIONS = ["tzid", "location", "tznames", "latitude", "longitude"]; + +/** + * Timezone representation. + * + * @example + * var vcalendar; + * var timezoneComp = vcalendar.getFirstSubcomponent('vtimezone'); + * var tzid = timezoneComp.getFirstPropertyValue('tzid'); + * + * var timezone = new ICAL.Timezone({ + * component: timezoneComp, + * tzid + * }); + * + * @memberof ICAL + */ +class Timezone { + static _compare_change_fn(a, b) { + if (a.year < b.year) return -1; + else if (a.year > b.year) return 1; + + if (a.month < b.month) return -1; + else if (a.month > b.month) return 1; + + if (a.day < b.day) return -1; + else if (a.day > b.day) return 1; + + if (a.hour < b.hour) return -1; + else if (a.hour > b.hour) return 1; + + if (a.minute < b.minute) return -1; + else if (a.minute > b.minute) return 1; + + if (a.second < b.second) return -1; + else if (a.second > b.second) return 1; + + return 0; + } + + /** + * Convert the date/time from one zone to the next. + * + * @param {Time} tt The time to convert + * @param {Timezone} from_zone The source zone to convert from + * @param {Timezone} to_zone The target zone to convert to + * @return {Time} The converted date/time object + */ + static convert_time(tt, from_zone, to_zone) { + if (tt.isDate || + from_zone.tzid == to_zone.tzid || + from_zone == Timezone.localTimezone || + to_zone == Timezone.localTimezone) { + tt.zone = to_zone; + return tt; + } + + let utcOffset = from_zone.utcOffset(tt); + tt.adjust(0, 0, 0, - utcOffset); + + utcOffset = to_zone.utcOffset(tt); + tt.adjust(0, 0, 0, utcOffset); + + return null; + } + + /** + * Creates a new ICAL.Timezone instance from the passed data object. + * + * @param {Component|Object} aData options for class + * @param {String|Component} aData.component + * If aData is a simple object, then this member can be set to either a + * string containing the component data, or an already parsed + * ICAL.Component + * @param {String} aData.tzid The timezone identifier + * @param {String} aData.location The timezone locationw + * @param {String} aData.tznames An alternative string representation of the + * timezone + * @param {Number} aData.latitude The latitude of the timezone + * @param {Number} aData.longitude The longitude of the timezone + */ + static fromData(aData) { + let tt = new Timezone(); + return tt.fromData(aData); + } + + /** + * The instance describing the UTC timezone + * @type {Timezone} + * @constant + * @instance + */ + static #utcTimezone = null; + static get utcTimezone() { + if (!this.#utcTimezone) { + this.#utcTimezone = Timezone.fromData({ + tzid: "UTC" + }); + } + return this.#utcTimezone; + } + + /** + * The instance describing the local timezone + * @type {Timezone} + * @constant + * @instance + */ + static #localTimezone = null; + static get localTimezone() { + if (!this.#localTimezone) { + this.#localTimezone = Timezone.fromData({ + tzid: "floating" + }); + } + return this.#localTimezone; + } + + /** + * Adjust a timezone change object. + * @private + * @param {Object} change The timezone change object + * @param {Number} days The extra amount of days + * @param {Number} hours The extra amount of hours + * @param {Number} minutes The extra amount of minutes + * @param {Number} seconds The extra amount of seconds + */ + static adjust_change(change, days, hours, minutes, seconds) { + return Time.prototype.adjust.call( + change, + days, + hours, + minutes, + seconds, + change + ); + } + + static _minimumExpansionYear = -1; + static EXTRA_COVERAGE = 5; + + /** + * Creates a new ICAL.Timezone instance, by passing in a tzid and component. + * + * @param {Component|Object} data options for class + * @param {String|Component} data.component + * If data is a simple object, then this member can be set to either a + * string containing the component data, or an already parsed + * ICAL.Component + * @param {String} data.tzid The timezone identifier + * @param {String} data.location The timezone locationw + * @param {String} data.tznames An alternative string representation of the + * timezone + * @param {Number} data.latitude The latitude of the timezone + * @param {Number} data.longitude The longitude of the timezone + */ + constructor(data) { + this.wrappedJSObject = this; + this.fromData(data); + } + + + /** + * Timezone identifier + * @type {String} + */ + tzid = ""; + + /** + * Timezone location + * @type {String} + */ + location = ""; + + /** + * Alternative timezone name, for the string representation + * @type {String} + */ + tznames = ""; + + /** + * The primary latitude for the timezone. + * @type {Number} + */ + latitude = 0.0; + + /** + * The primary longitude for the timezone. + * @type {Number} + */ + longitude = 0.0; + + /** + * The vtimezone component for this timezone. + * @type {Component} + */ + component = null; + + /** + * The year this timezone has been expanded to. All timezone transition + * dates until this year are known and can be used for calculation + * + * @private + * @type {Number} + */ + expandedUntilYear = 0; + + /** + * The class identifier. + * @constant + * @type {String} + * @default "icaltimezone" + */ + icalclass = "icaltimezone"; + + /** + * Sets up the current instance using members from the passed data object. + * + * @param {Component|Object} aData options for class + * @param {String|Component} aData.component + * If aData is a simple object, then this member can be set to either a + * string containing the component data, or an already parsed + * ICAL.Component + * @param {String} aData.tzid The timezone identifier + * @param {String} aData.location The timezone locationw + * @param {String} aData.tznames An alternative string representation of the + * timezone + * @param {Number} aData.latitude The latitude of the timezone + * @param {Number} aData.longitude The longitude of the timezone + */ + fromData(aData) { + this.expandedUntilYear = 0; + this.changes = []; + + if (aData instanceof Component) { + // Either a component is passed directly + this.component = aData; + } else { + // Otherwise the component may be in the data object + if (aData && "component" in aData) { + if (typeof aData.component == "string") { + // If a string was passed, parse it as a component + let jCal = parse(aData.component); + this.component = new Component(jCal); + } else if (aData.component instanceof Component) { + // If it was a component already, then just set it + this.component = aData.component; + } else { + // Otherwise just null out the component + this.component = null; + } + } + + // Copy remaining passed properties + for (let prop of OPTIONS) { + if (aData && prop in aData) { + this[prop] = aData[prop]; + } + } + } + + // If we have a component but no TZID, attempt to get it from the + // component's properties. + if (this.component instanceof Component && !this.tzid) { + this.tzid = this.component.getFirstPropertyValue('tzid'); + } + + return this; + } + + /** + * Finds the utcOffset the given time would occur in this timezone. + * + * @param {Time} tt The time to check for + * @return {Number} utc offset in seconds + */ + utcOffset(tt) { + if (this == Timezone.utcTimezone || this == Timezone.localTimezone) { + return 0; + } + + this._ensureCoverage(tt.year); + + if (!this.changes.length) { + return 0; + } + + let tt_change = { + year: tt.year, + month: tt.month, + day: tt.day, + hour: tt.hour, + minute: tt.minute, + second: tt.second + }; + + let change_num = this._findNearbyChange(tt_change); + let change_num_to_use = -1; + let step = 1; + + // TODO: replace with bin search? + for (;;) { + let change = clone(this.changes[change_num], true); + if (change.utcOffset < change.prevUtcOffset) { + Timezone.adjust_change(change, 0, 0, 0, change.utcOffset); + } else { + Timezone.adjust_change(change, 0, 0, 0, + change.prevUtcOffset); + } + + let cmp = Timezone._compare_change_fn(tt_change, change); + + if (cmp >= 0) { + change_num_to_use = change_num; + } else { + step = -1; + } + + if (step == -1 && change_num_to_use != -1) { + break; + } + + change_num += step; + + if (change_num < 0) { + return 0; + } + + if (change_num >= this.changes.length) { + break; + } + } + + let zone_change = this.changes[change_num_to_use]; + let utcOffset_change = zone_change.utcOffset - zone_change.prevUtcOffset; + + if (utcOffset_change < 0 && change_num_to_use > 0) { + let tmp_change = clone(zone_change, true); + Timezone.adjust_change(tmp_change, 0, 0, 0, tmp_change.prevUtcOffset); + + if (Timezone._compare_change_fn(tt_change, tmp_change) < 0) { + let prev_zone_change = this.changes[change_num_to_use - 1]; + + let want_daylight = false; // TODO + + if (zone_change.is_daylight != want_daylight && + prev_zone_change.is_daylight == want_daylight) { + zone_change = prev_zone_change; + } + } + } + + // TODO return is_daylight? + return zone_change.utcOffset; + } + + _findNearbyChange(change) { + // find the closest match + let idx = binsearchInsert( + this.changes, + change, + Timezone._compare_change_fn + ); + + if (idx >= this.changes.length) { + return this.changes.length - 1; + } + + return idx; + } + + _ensureCoverage(aYear) { + if (Timezone._minimumExpansionYear == -1) { + let today = Time.now(); + Timezone._minimumExpansionYear = today.year; + } + + let changesEndYear = aYear; + if (changesEndYear < Timezone._minimumExpansionYear) { + changesEndYear = Timezone._minimumExpansionYear; + } + + changesEndYear += Timezone.EXTRA_COVERAGE; + + if (!this.changes.length || this.expandedUntilYear < aYear) { + let subcomps = this.component.getAllSubcomponents(); + let compLen = subcomps.length; + let compIdx = 0; + + for (; compIdx < compLen; compIdx++) { + this._expandComponent( + subcomps[compIdx], changesEndYear, this.changes + ); + } + + this.changes.sort(Timezone._compare_change_fn); + this.expandedUntilYear = changesEndYear; + } + } + + _expandComponent(aComponent, aYear, changes) { + if (!aComponent.hasProperty("dtstart") || + !aComponent.hasProperty("tzoffsetto") || + !aComponent.hasProperty("tzoffsetfrom")) { + return null; + } + + let dtstart = aComponent.getFirstProperty("dtstart").getFirstValue(); + let change; + + function convert_tzoffset(offset) { + return offset.factor * (offset.hours * 3600 + offset.minutes * 60); + } + + function init_changes() { + let changebase = {}; + changebase.is_daylight = (aComponent.name == "daylight"); + changebase.utcOffset = convert_tzoffset( + aComponent.getFirstProperty("tzoffsetto").getFirstValue() + ); + + changebase.prevUtcOffset = convert_tzoffset( + aComponent.getFirstProperty("tzoffsetfrom").getFirstValue() + ); + + return changebase; + } + + if (!aComponent.hasProperty("rrule") && !aComponent.hasProperty("rdate")) { + change = init_changes(); + change.year = dtstart.year; + change.month = dtstart.month; + change.day = dtstart.day; + change.hour = dtstart.hour; + change.minute = dtstart.minute; + change.second = dtstart.second; + + Timezone.adjust_change(change, 0, 0, 0, -change.prevUtcOffset); + changes.push(change); + } else { + let props = aComponent.getAllProperties("rdate"); + for (let rdate of props) { + let time = rdate.getFirstValue(); + change = init_changes(); + + change.year = time.year; + change.month = time.month; + change.day = time.day; + + if (time.isDate) { + change.hour = dtstart.hour; + change.minute = dtstart.minute; + change.second = dtstart.second; + + if (dtstart.zone != Timezone.utcTimezone) { + Timezone.adjust_change(change, 0, 0, 0, -change.prevUtcOffset); + } + } else { + change.hour = time.hour; + change.minute = time.minute; + change.second = time.second; + + if (time.zone != Timezone.utcTimezone) { + Timezone.adjust_change(change, 0, 0, 0, -change.prevUtcOffset); + } + } + + changes.push(change); + } + + let rrule = aComponent.getFirstProperty("rrule"); + + if (rrule) { + rrule = rrule.getFirstValue(); + change = init_changes(); + + if (rrule.until && rrule.until.zone == Timezone.utcTimezone) { + rrule.until.adjust(0, 0, 0, change.prevUtcOffset); + rrule.until.zone = Timezone.localTimezone; + } + + let iterator = rrule.iterator(dtstart); + + let occ; + while ((occ = iterator.next())) { + change = init_changes(); + if (occ.year > aYear || !occ) { + break; + } + + change.year = occ.year; + change.month = occ.month; + change.day = occ.day; + change.hour = occ.hour; + change.minute = occ.minute; + change.second = occ.second; + change.isDate = occ.isDate; + + Timezone.adjust_change(change, 0, 0, 0, -change.prevUtcOffset); + changes.push(change); + } + } + } + + return changes; + } + + /** + * The string representation of this timezone. + * @return {String} + */ + toString() { + return (this.tznames ? this.tznames : this.tzid); + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +let zones = null; + +/** + * @classdesc + * Singleton class to contain timezones. Right now it is all manual registry in + * the future we may use this class to download timezone information or handle + * loading pre-expanded timezones. + * + * @exports module:ICAL.TimezoneService + * @memberof ICAL + */ +const TimezoneService = { + get count() { + if (zones === null) { + return 0; + } + + return Object.keys(zones).length; + }, + + reset: function() { + zones = Object.create(null); + let utc = Timezone.utcTimezone; + + zones.Z = utc; + zones.UTC = utc; + zones.GMT = utc; + }, + _hard_reset: function() { + zones = null; + }, + + /** + * Checks if timezone id has been registered. + * + * @param {String} tzid Timezone identifier (e.g. America/Los_Angeles) + * @return {Boolean} False, when not present + */ + has: function(tzid) { + if (zones === null) { + return false; + } + + return !!zones[tzid]; + }, + + /** + * Returns a timezone by its tzid if present. + * + * @param {String} tzid Timezone identifier (e.g. America/Los_Angeles) + * @return {Timezone | undefined} The timezone, or undefined if not found + */ + get: function(tzid) { + if (zones === null) { + this.reset(); + } + + return zones[tzid]; + }, + + /** + * Registers a timezone object or component. + * + * @param {Component|Timezone} timezone + * The initialized zone or vtimezone. + * + * @param {String=} name + * The name of the timezone. Defaults to the component's TZID if not + * passed. + */ + register: function(timezone, name) { + if (zones === null) { + this.reset(); + } + + // This avoids a breaking change by the change of argument order + // TODO remove in v3 + if (typeof timezone === "string" && name instanceof Timezone) { + [timezone, name] = [name, timezone]; + } + + if (!name) { + if (timezone instanceof Timezone) { + name = timezone.tzid; + } else { + if (timezone.name === 'vtimezone') { + timezone = new Timezone(timezone); + name = timezone.tzid; + } + } + } + + if (!name) { + throw new TypeError("Neither a timezone nor a name was passed"); + } + + if (timezone instanceof Timezone) { + zones[name] = timezone; + } else { + throw new TypeError('timezone must be ICAL.Timezone or ICAL.Component'); + } + }, + + /** + * Removes a timezone by its tzid from the list. + * + * @param {String} tzid Timezone identifier (e.g. America/Los_Angeles) + * @return {?Timezone} The removed timezone, or null if not registered + */ + remove: function(tzid) { + if (zones === null) { + return null; + } + + return (delete zones[tzid]); + } +}; + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * Helper functions used in various places within ical.js + * @module ICAL.helpers + */ + +/** + * Compiles a list of all referenced TZIDs in all subcomponents and + * removes any extra VTIMEZONE subcomponents. In addition, if any TZIDs + * are referenced by a component, but a VTIMEZONE does not exist, + * an attempt will be made to generate a VTIMEZONE using ICAL.TimezoneService. + * + * @param {Component} vcal The top-level VCALENDAR component. + * @return {Component} The ICAL.Component that was passed in. + */ +function updateTimezones(vcal) { + let allsubs, properties, vtimezones, reqTzid, i; + + if (!vcal || vcal.name !== "vcalendar") { + //not a top-level vcalendar component + return vcal; + } + + //Store vtimezone subcomponents in an object reference by tzid. + //Store properties from everything else in another array + allsubs = vcal.getAllSubcomponents(); + properties = []; + vtimezones = {}; + for (i = 0; i < allsubs.length; i++) { + if (allsubs[i].name === "vtimezone") { + let tzid = allsubs[i].getFirstProperty("tzid").getFirstValue(); + vtimezones[tzid] = allsubs[i]; + } else { + properties = properties.concat(allsubs[i].getAllProperties()); + } + } + + //create an object with one entry for each required tz + reqTzid = {}; + for (i = 0; i < properties.length; i++) { + let tzid = properties[i].getParameter("tzid"); + if (tzid) { + reqTzid[tzid] = true; + } + } + + //delete any vtimezones that are not on the reqTzid list. + for (let [tzid, comp] of Object.entries(vtimezones)) { + if (!reqTzid[tzid]) { + vcal.removeSubcomponent(comp); + } + } + + //create any missing, but registered timezones + for (let tzid of Object.keys(reqTzid)) { + if (!vtimezones[tzid] && TimezoneService.has(tzid)) { + vcal.addSubcomponent(TimezoneService.get(tzid).component); + } + } + + return vcal; +} + +/** + * Checks if the given type is of the number type and also NaN. + * + * @param {Number} number The number to check + * @return {Boolean} True, if the number is strictly NaN + */ +function isStrictlyNaN(number) { + return typeof(number) === 'number' && isNaN(number); +} + +/** + * Parses a string value that is expected to be an integer, when the valid is + * not an integer throws a decoration error. + * + * @param {String} string Raw string input + * @return {Number} Parsed integer + */ +function strictParseInt(string) { + let result = parseInt(string, 10); + + if (isStrictlyNaN(result)) { + throw new Error( + 'Could not extract integer from "' + string + '"' + ); + } + + return result; +} + +/** + * Creates or returns a class instance of a given type with the initialization + * data if the data is not already an instance of the given type. + * + * @example + * var time = new ICAL.Time(...); + * var result = ICAL.helpers.formatClassType(time, ICAL.Time); + * + * (result instanceof ICAL.Time) + * // => true + * + * result = ICAL.helpers.formatClassType({}, ICAL.Time); + * (result isntanceof ICAL.Time) + * // => true + * + * + * @param {Object} data object initialization data + * @param {Object} type object type (like ICAL.Time) + * @return {?} An instance of the found type. + */ +function formatClassType(data, type) { + if (typeof(data) === 'undefined') { + return undefined; + } + + if (data instanceof type) { + return data; + } + return new type(data); +} + +/** + * Identical to indexOf but will only match values when they are not preceded + * by a backslash character. + * + * @param {String} buffer String to search + * @param {String} search Value to look for + * @param {Number} pos Start position + * @return {Number} The position, or -1 if not found + */ +function unescapedIndexOf(buffer, search, pos) { + while ((pos = buffer.indexOf(search, pos)) !== -1) { + if (pos > 0 && buffer[pos - 1] === '\\') { + pos += 1; + } else { + return pos; + } + } + return -1; +} + +/** + * Find the index for insertion using binary search. + * + * @param {Array} list The list to search + * @param {?} seekVal The value to insert + * @param {function(?,?)} cmpfunc The comparison func, that can + * compare two seekVals + * @return {Number} The insert position + */ +function binsearchInsert(list, seekVal, cmpfunc) { + if (!list.length) + return 0; + + let low = 0, high = list.length - 1, + mid, cmpval; + + while (low <= high) { + mid = low + Math.floor((high - low) / 2); + cmpval = cmpfunc(seekVal, list[mid]); + + if (cmpval < 0) + high = mid - 1; + else if (cmpval > 0) + low = mid + 1; + else + break; + } + + if (cmpval < 0) + return mid; // insertion is displacing, so use mid outright. + else if (cmpval > 0) + return mid + 1; + else + return mid; +} + +/** + * Clone the passed object or primitive. By default a shallow clone will be + * executed. + * + * @param {*} aSrc The thing to clone + * @param {Boolean=} aDeep If true, a deep clone will be performed + * @return {*} The copy of the thing + */ +function clone(aSrc, aDeep) { + if (!aSrc || typeof aSrc != "object") { + return aSrc; + } else if (aSrc instanceof Date) { + return new Date(aSrc.getTime()); + } else if ("clone" in aSrc) { + return aSrc.clone(); + } else if (Array.isArray(aSrc)) { + let arr = []; + for (let i = 0; i < aSrc.length; i++) { + arr.push(aDeep ? clone(aSrc[i], true) : aSrc[i]); + } + return arr; + } else { + let obj = {}; + for (let [name, value] of Object.entries(aSrc)) { + if (aDeep) { + obj[name] = clone(value, true); + } else { + obj[name] = value; + } + } + return obj; + } +} + +/** + * Performs iCalendar line folding. A line ending character is inserted and + * the next line begins with a whitespace. + * + * @example + * SUMMARY:This line will be fold + * ed right in the middle of a word. + * + * @param {String} aLine The line to fold + * @return {String} The folded line + */ +function foldline(aLine) { + let result = ""; + let line = aLine || "", pos = 0, line_length = 0; + //pos counts position in line for the UTF-16 presentation + //line_length counts the bytes for the UTF-8 presentation + while (line.length) { + let cp = line.codePointAt(pos); + if (cp < 128) ++line_length; + else if (cp < 2048) line_length += 2;//needs 2 UTF-8 bytes + else if (cp < 65536) line_length += 3; + else line_length += 4; //cp is less than 1114112 + if (line_length < ICALmodule.foldLength + 1) + pos += cp > 65535 ? 2 : 1; + else { + result += ICALmodule.newLineChar + " " + line.slice(0, Math.max(0, pos)); + line = line.slice(Math.max(0, pos)); + pos = line_length = 0; + } + } + return result.slice(ICALmodule.newLineChar.length + 1); +} + +/** + * Pads the given string or number with zeros so it will have at least two + * characters. + * + * @param {String|Number} data The string or number to pad + * @return {String} The number padded as a string + */ +function pad2(data) { + if (typeof(data) !== 'string') { + // handle fractions. + if (typeof(data) === 'number') { + data = parseInt(data); + } + data = String(data); + } + + let len = data.length; + + switch (len) { + case 0: + return '00'; + case 1: + return '0' + data; + default: + return data; + } +} + +/** + * Truncates the given number, correctly handling negative numbers. + * + * @param {Number} number The number to truncate + * @return {Number} The truncated number + */ +function trunc(number) { + return (number < 0 ? Math.ceil(number) : Math.floor(number)); +} + +/** + * Poor-man's cross-browser object extension. Doesn't support all the + * features, but enough for our usage. Note that the target's properties are + * not overwritten with the source properties. + * + * @example + * var child = ICAL.helpers.extend(parent, { + * "bar": 123 + * }); + * + * @param {Object} source The object to extend + * @param {Object} target The object to extend with + * @return {Object} Returns the target. + */ +function extend(source, target) { + for (let key in source) { + let descr = Object.getOwnPropertyDescriptor(source, key); + if (descr && !Object.getOwnPropertyDescriptor(target, key)) { + Object.defineProperty(target, key, descr); + } + } + return target; +} + +var helpers = /*#__PURE__*/Object.freeze({ + __proto__: null, + binsearchInsert: binsearchInsert, + clone: clone, + extend: extend, + foldline: foldline, + formatClassType: formatClassType, + isStrictlyNaN: isStrictlyNaN, + pad2: pad2, + strictParseInt: strictParseInt, + trunc: trunc, + unescapedIndexOf: unescapedIndexOf, + updateTimezones: updateTimezones +}); + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This class represents the "utc-offset" value type, with various calculation and manipulation + * methods. + * + * @memberof ICAL + */ +class UtcOffset { + /** + * Creates a new {@link ICAL.UtcOffset} instance from the passed string. + * + * @param {String} aString The string to parse + * @return {Duration} The created utc-offset instance + */ + static fromString(aString) { + // -05:00 + let options = {}; + //TODO: support seconds per rfc5545 ? + options.factor = (aString[0] === '+') ? 1 : -1; + options.hours = strictParseInt(aString.slice(1, 3)); + options.minutes = strictParseInt(aString.slice(4, 6)); + + return new UtcOffset(options); + } + + /** + * Creates a new {@link ICAL.UtcOffset} instance from the passed seconds + * value. + * + * @param {Number} aSeconds The number of seconds to convert + */ + static fromSeconds(aSeconds) { + let instance = new UtcOffset(); + instance.fromSeconds(aSeconds); + return instance; + } + + /** + * Creates a new ICAL.UtcOffset instance. + * + * @param {Object} aData An object with members of the utc offset + * @param {Number=} aData.hours The hours for the utc offset + * @param {Number=} aData.minutes The minutes in the utc offset + * @param {Number=} aData.factor The factor for the utc-offset, either -1 or 1 + */ + constructor(aData) { + this.fromData(aData); + } + + /** + * The hours in the utc-offset + * @type {Number} + */ + hours = 0; + + /** + * The minutes in the utc-offset + * @type {Number} + */ + minutes = 0; + + /** + * The sign of the utc offset, 1 for positive offset, -1 for negative + * offsets. + * @type {Number} + */ + factor = 1; + + /** + * The type name, to be used in the jCal object. + * @constant + * @type {String} + * @default "utc-offset" + */ + icaltype = "utc-offset"; + + /** + * Returns a clone of the utc offset object. + * + * @return {UtcOffset} The cloned object + */ + clone() { + return UtcOffset.fromSeconds(this.toSeconds()); + } + + /** + * Sets up the current instance using members from the passed data object. + * + * @param {Object} aData An object with members of the utc offset + * @param {Number=} aData.hours The hours for the utc offset + * @param {Number=} aData.minutes The minutes in the utc offset + * @param {Number=} aData.factor The factor for the utc-offset, either -1 or 1 + */ + fromData(aData) { + if (aData) { + for (let [key, value] of Object.entries(aData)) { + this[key] = value; + } + } + this._normalize(); + } + + /** + * Sets up the current instance from the given seconds value. The seconds + * value is truncated to the minute. Offsets are wrapped when the world + * ends, the hour after UTC+14:00 is UTC-12:00. + * + * @param {Number} aSeconds The seconds to convert into an offset + */ + fromSeconds(aSeconds) { + let secs = Math.abs(aSeconds); + + this.factor = aSeconds < 0 ? -1 : 1; + this.hours = trunc(secs / 3600); + + secs -= (this.hours * 3600); + this.minutes = trunc(secs / 60); + return this; + } + + /** + * Convert the current offset to a value in seconds + * + * @return {Number} The offset in seconds + */ + toSeconds() { + return this.factor * (60 * this.minutes + 3600 * this.hours); + } + + /** + * Compare this utc offset with another one. + * + * @param {UtcOffset} other The other offset to compare with + * @return {Number} -1, 0 or 1 for less/equal/greater + */ + compare(other) { + let a = this.toSeconds(); + let b = other.toSeconds(); + return (a > b) - (b > a); + } + + _normalize() { + // Range: 97200 seconds (with 1 hour inbetween) + let secs = this.toSeconds(); + let factor = this.factor; + while (secs < -43200) { // = UTC-12:00 + secs += 97200; + } + while (secs > 50400) { // = UTC+14:00 + secs -= 97200; + } + + this.fromSeconds(secs); + + // Avoid changing the factor when on zero seconds + if (secs == 0) { + this.factor = factor; + } + } + + /** + * The iCalendar string representation of this utc-offset. + * @return {String} + */ + toICALString() { + return design.icalendar.value['utc-offset'].toICAL(this.toString()); + } + + /** + * The string representation of this utc-offset. + * @return {String} + */ + toString() { + return (this.factor == 1 ? "+" : "-") + pad2(this.hours) + ':' + pad2(this.minutes); + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * Describes a vCard time, which has slight differences to the ICAL.Time. + * Properties can be null if not specified, for example for dates with + * reduced accuracy or truncation. + * + * Note that currently not all methods are correctly re-implemented for + * VCardTime. For example, comparison will have undefined results when some + * members are null. + * + * Also, normalization is not yet implemented for this class! + * + * @memberof ICAL + * @extends {Time} + */ +class VCardTime extends Time { + /** + * Returns a new ICAL.VCardTime instance from a date and/or time string. + * + * @param {String} aValue The string to create from + * @param {String} aIcalType The type for this instance, e.g. date-and-or-time + * @return {VCardTime} The date/time instance + */ + static fromDateAndOrTimeString(aValue, aIcalType) { + function part(v, s, e) { + return v ? strictParseInt(v.slice(s, s + e)) : null; + } + let parts = aValue.split('T'); + let dt = parts[0], tmz = parts[1]; + let splitzone = tmz ? design.vcard.value.time._splitZone(tmz) : []; + let zone = splitzone[0], tm = splitzone[1]; + + let dtlen = dt ? dt.length : 0; + let tmlen = tm ? tm.length : 0; + + let hasDashDate = dt && dt[0] == '-' && dt[1] == '-'; + let hasDashTime = tm && tm[0] == '-'; + + let o = { + year: hasDashDate ? null : part(dt, 0, 4), + month: hasDashDate && (dtlen == 4 || dtlen == 7) ? part(dt, 2, 2) : dtlen == 7 ? part(dt, 5, 2) : dtlen == 10 ? part(dt, 5, 2) : null, + day: dtlen == 5 ? part(dt, 3, 2) : dtlen == 7 && hasDashDate ? part(dt, 5, 2) : dtlen == 10 ? part(dt, 8, 2) : null, + + hour: hasDashTime ? null : part(tm, 0, 2), + minute: hasDashTime && tmlen == 3 ? part(tm, 1, 2) : tmlen > 4 ? hasDashTime ? part(tm, 1, 2) : part(tm, 3, 2) : null, + second: tmlen == 4 ? part(tm, 2, 2) : tmlen == 6 ? part(tm, 4, 2) : tmlen == 8 ? part(tm, 6, 2) : null + }; + + if (zone == 'Z') { + zone = Timezone.utcTimezone; + } else if (zone && zone[3] == ':') { + zone = UtcOffset.fromString(zone); + } else { + zone = null; + } + + return new VCardTime(o, zone, aIcalType); + } + + + /** + * Creates a new ICAL.VCardTime instance. + * + * @param {Object} data The data for the time instance + * @param {Number=} data.year The year for this date + * @param {Number=} data.month The month for this date + * @param {Number=} data.day The day for this date + * @param {Number=} data.hour The hour for this date + * @param {Number=} data.minute The minute for this date + * @param {Number=} data.second The second for this date + * @param {Timezone|UtcOffset} zone The timezone to use + * @param {String} icaltype The type for this date/time object + */ + constructor(data, zone, icaltype) { + super(data, zone); + this.icaltype = icaltype || "date-and-or-time"; + } + + /** + * The class identifier. + * @constant + * @type {String} + * @default "vcardtime" + */ + icalclass = "vcardtime"; + + /** + * The type name, to be used in the jCal object. + * @type {String} + * @default "date-and-or-time" + */ + icaltype = "date-and-or-time"; + + /** + * Returns a clone of the vcard date/time object. + * + * @return {VCardTime} The cloned object + */ + clone() { + return new VCardTime(this._time, this.zone, this.icaltype); + } + + _normalize() { + return this; + } + + /** + * @inheritdoc + */ + utcOffset() { + if (this.zone instanceof UtcOffset) { + return this.zone.toSeconds(); + } else { + return Time.prototype.utcOffset.apply(this, arguments); + } + } + + /** + * Returns an RFC 6350 compliant representation of this object. + * + * @return {String} vcard date/time string + */ + toICALString() { + return design.vcard.value[this.icaltype].toICAL(this.toString()); + } + + /** + * The string representation of this date/time, in jCard form + * (including : and - separators). + * @return {String} + */ + toString() { + let y = this.year, m = this.month, d = this.day; + let h = this.hour, mm = this.minute, s = this.second; + + let hasYear = y !== null, hasMonth = m !== null, hasDay = d !== null; + let hasHour = h !== null, hasMinute = mm !== null, hasSecond = s !== null; + + let datepart = (hasYear ? pad2(y) + (hasMonth || hasDay ? '-' : '') : (hasMonth || hasDay ? '--' : '')) + + (hasMonth ? pad2(m) : '') + + (hasDay ? '-' + pad2(d) : ''); + let timepart = (hasHour ? pad2(h) : '-') + (hasHour && hasMinute ? ':' : '') + + (hasMinute ? pad2(mm) : '') + (!hasHour && !hasMinute ? '-' : '') + + (hasMinute && hasSecond ? ':' : '') + + (hasSecond ? pad2(s) : ''); + + let zone; + if (this.zone === Timezone.utcTimezone) { + zone = 'Z'; + } else if (this.zone instanceof UtcOffset) { + zone = this.zone.toString(); + } else if (this.zone === Timezone.localTimezone) { + zone = ''; + } else if (this.zone instanceof Timezone) { + let offset = UtcOffset.fromSeconds(this.zone.utcOffset(this)); + zone = offset.toString(); + } else { + zone = ''; + } + + switch (this.icaltype) { + case "time": + return timepart + zone; + case "date-and-or-time": + case "date-time": + return datepart + (timepart == '--' ? '' : 'T' + timepart + zone); + case "date": + return datepart; + } + return null; + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * + * @ignore + * @typedef {import("./types.js").weekDay} weekDay + * Imports the 'weekDay' type from the "types.js" module + */ + +/** + * An iterator for a single recurrence rule. This class usually doesn't have to be instanciated + * directly, the convenience method {@link ICAL.Recur#iterator} can be used. + * + * @memberof ICAL + */ +class RecurIterator { + static _indexMap = { + "BYSECOND": 0, + "BYMINUTE": 1, + "BYHOUR": 2, + "BYDAY": 3, + "BYMONTHDAY": 4, + "BYYEARDAY": 5, + "BYWEEKNO": 6, + "BYMONTH": 7, + "BYSETPOS": 8 + }; + + static _expandMap = { + "SECONDLY": [1, 1, 1, 1, 1, 1, 1, 1], + "MINUTELY": [2, 1, 1, 1, 1, 1, 1, 1], + "HOURLY": [2, 2, 1, 1, 1, 1, 1, 1], + "DAILY": [2, 2, 2, 1, 1, 1, 1, 1], + "WEEKLY": [2, 2, 2, 2, 3, 3, 1, 1], + "MONTHLY": [2, 2, 2, 2, 2, 3, 3, 1], + "YEARLY": [2, 2, 2, 2, 2, 2, 2, 2] + }; + + static UNKNOWN = 0; + static CONTRACT = 1; + static EXPAND = 2; + static ILLEGAL = 3; + + /** + * Creates a new ICAL.RecurIterator instance. The options object may contain additional members + * when resuming iteration from a previous run. + * + * @param {Object} options The iterator options + * @param {Recur} options.rule The rule to iterate. + * @param {Time} options.dtstart The start date of the event. + * @param {Boolean=} options.initialized When true, assume that options are + * from a previously constructed iterator. Initialization will not be + * repeated. + */ + constructor(options) { + this.fromData(options); + } + + /** + * True when iteration is finished. + * @type {Boolean} + */ + completed = false; + + /** + * The rule that is being iterated + * @type {Recur} + */ + rule = null; + + /** + * The start date of the event being iterated. + * @type {Time} + */ + dtstart = null; + + /** + * The last occurrence that was returned from the + * {@link RecurIterator#next} method. + * @type {Time} + */ + last = null; + + /** + * The sequence number from the occurrence + * @type {Number} + */ + occurrence_number = 0; + + /** + * The indices used for the {@link ICAL.RecurIterator#by_data} object. + * @type {Object} + * @private + */ + by_indices = null; + + /** + * If true, the iterator has already been initialized + * @type {Boolean} + * @private + */ + initialized = false; + + /** + * The initializd by-data. + * @type {Object} + * @private + */ + by_data = null; + + /** + * The expanded yeardays + * @type {Array} + * @private + */ + days = null; + + /** + * The index in the {@link ICAL.RecurIterator#days} array. + * @type {Number} + * @private + */ + days_index = 0; + + /** + * Initialize the recurrence iterator from the passed data object. This + * method is usually not called directly, you can initialize the iterator + * through the constructor. + * + * @param {Object} options The iterator options + * @param {Recur} options.rule The rule to iterate. + * @param {Time} options.dtstart The start date of the event. + * @param {Boolean=} options.initialized When true, assume that options are + * from a previously constructed iterator. Initialization will not be + * repeated. + */ + fromData(options) { + this.rule = formatClassType(options.rule, Recur); + + if (!this.rule) { + throw new Error('iterator requires a (ICAL.Recur) rule'); + } + + this.dtstart = formatClassType(options.dtstart, Time); + + if (!this.dtstart) { + throw new Error('iterator requires a (ICAL.Time) dtstart'); + } + + if (options.by_data) { + this.by_data = options.by_data; + } else { + this.by_data = clone(this.rule.parts, true); + } + + if (options.occurrence_number) + this.occurrence_number = options.occurrence_number; + + this.days = options.days || []; + if (options.last) { + this.last = formatClassType(options.last, Time); + } + + this.by_indices = options.by_indices; + + if (!this.by_indices) { + this.by_indices = { + "BYSECOND": 0, + "BYMINUTE": 0, + "BYHOUR": 0, + "BYDAY": 0, + "BYMONTH": 0, + "BYWEEKNO": 0, + "BYMONTHDAY": 0 + }; + } + + this.initialized = options.initialized || false; + + if (!this.initialized) { + try { + this.init(); + } catch (e) { + if (e instanceof InvalidRecurrenceRuleError) { + // Init may error if there are no possible recurrence instances from + // the rule, but we don't want to bubble this error up. Instead, we + // create an empty iterator. + this.completed = true; + } else { + // Propagate other errors to consumers. + throw e; + } + } + } + } + + /** + * Initialize the iterator + * @private + */ + init() { + this.initialized = true; + this.last = this.dtstart.clone(); + let parts = this.by_data; + + if ("BYDAY" in parts) { + // libical does this earlier when the rule is loaded, but we postpone to + // now so we can preserve the original order. + this.sort_byday_rules(parts.BYDAY); + } + + // The BYYEARDAY may only appear with BYDAY + if ("BYYEARDAY" in parts) { + if ("BYMONTH" in parts || "BYWEEKNO" in parts || + "BYMONTHDAY" in parts) { + throw new Error("Invalid BYYEARDAY rule"); + } + } + + // BYWEEKNO and BYMONTHDAY rule parts may not both appear + if ("BYWEEKNO" in parts && "BYMONTHDAY" in parts) { + throw new Error("BYWEEKNO does not fit to BYMONTHDAY"); + } + + // For MONTHLY recurrences (FREQ=MONTHLY) neither BYYEARDAY nor + // BYWEEKNO may appear. + if (this.rule.freq == "MONTHLY" && + ("BYYEARDAY" in parts || "BYWEEKNO" in parts)) { + throw new Error("For MONTHLY recurrences neither BYYEARDAY nor BYWEEKNO may appear"); + } + + // For WEEKLY recurrences (FREQ=WEEKLY) neither BYMONTHDAY nor + // BYYEARDAY may appear. + if (this.rule.freq == "WEEKLY" && + ("BYYEARDAY" in parts || "BYMONTHDAY" in parts)) { + throw new Error("For WEEKLY recurrences neither BYMONTHDAY nor BYYEARDAY may appear"); + } + + // BYYEARDAY may only appear in YEARLY rules + if (this.rule.freq != "YEARLY" && "BYYEARDAY" in parts) { + throw new Error("BYYEARDAY may only appear in YEARLY rules"); + } + + this.last.second = this.setup_defaults("BYSECOND", "SECONDLY", this.dtstart.second); + this.last.minute = this.setup_defaults("BYMINUTE", "MINUTELY", this.dtstart.minute); + this.last.hour = this.setup_defaults("BYHOUR", "HOURLY", this.dtstart.hour); + this.last.day = this.setup_defaults("BYMONTHDAY", "DAILY", this.dtstart.day); + this.last.month = this.setup_defaults("BYMONTH", "MONTHLY", this.dtstart.month); + + if (this.rule.freq == "WEEKLY") { + if ("BYDAY" in parts) { + let [, dow] = this.ruleDayOfWeek(parts.BYDAY[0], this.rule.wkst); + let wkdy = dow - this.last.dayOfWeek(this.rule.wkst); + if ((this.last.dayOfWeek(this.rule.wkst) < dow && wkdy >= 0) || wkdy < 0) { + // Initial time is after first day of BYDAY data + this.last.day += wkdy; + } + } else { + let dayName = Recur.numericDayToIcalDay(this.dtstart.dayOfWeek()); + parts.BYDAY = [dayName]; + } + } + + if (this.rule.freq == "YEARLY") { + // Some yearly recurrence rules may be specific enough to not actually + // occur on a yearly basis, e.g. the 29th day of February or the fifth + // Monday of a given month. The standard isn't clear on the intended + // behavior in these cases, but `libical` at least will iterate until it + // finds a matching year. + // CAREFUL: Some rules may specify an occurrence that can never happen, + // e.g. the first Monday of April so long as it falls on the 15th + // through the 21st. Detecting these is non-trivial, so ensure that we + // stop iterating at some point. + const untilYear = this.rule.until ? this.rule.until.year : 20000; + while (this.last.year <= untilYear) { + this.expand_year_days(this.last.year); + if (this.days.length > 0) { + break; + } + this.increment_year(this.rule.interval); + } + + if (this.days.length == 0) { + throw new InvalidRecurrenceRuleError(); + } + + // If there's no occurrence in this year, try the following years. This + // would only happen looking for day 366 or -366. + if (!this._nextByYearDay() && !this.next_year() && !this.next_year() && !this.next_year()) { + // This should not be possible, but just in case it is, stop. + throw new InvalidRecurrenceRuleError(); + } + } + + if (this.rule.freq == "MONTHLY") { + if (this.has_by_data("BYDAY")) { + let tempLast = null; + let initLast = this.last.clone(); + let daysInMonth = Time.daysInMonth(this.last.month, this.last.year); + + // Check every weekday in BYDAY with relative dow and pos. + for (let bydow of this.by_data.BYDAY) { + this.last = initLast.clone(); + let [pos, dow] = this.ruleDayOfWeek(bydow); + let dayOfMonth = this.last.nthWeekDay(dow, pos); + + // If |pos| >= 6, the byday is invalid for a monthly rule. + if (pos >= 6 || pos <= -6) { + throw new Error("Malformed values in BYDAY part"); + } + + // If a Byday with pos=+/-5 is not in the current month it + // must be searched in the next months. + if (dayOfMonth > daysInMonth || dayOfMonth <= 0) { + // Skip if we have already found a "last" in this month. + if (tempLast && tempLast.month == initLast.month) { + continue; + } + while (dayOfMonth > daysInMonth || dayOfMonth <= 0) { + this.increment_month(); + daysInMonth = Time.daysInMonth(this.last.month, this.last.year); + dayOfMonth = this.last.nthWeekDay(dow, pos); + } + } + + this.last.day = dayOfMonth; + if (!tempLast || this.last.compare(tempLast) < 0) { + tempLast = this.last.clone(); + } + } + this.last = tempLast.clone(); + + //XXX: This feels like a hack, but we need to initialize + // the BYMONTHDAY case correctly and byDayAndMonthDay handles + // this case. It accepts a special flag which will avoid incrementing + // the initial value without the flag days that match the start time + // would be missed. + if (this.has_by_data('BYMONTHDAY')) { + this._byDayAndMonthDay(true); + } + + if (this.last.day > daysInMonth || this.last.day == 0) { + throw new Error("Malformed values in BYDAY part"); + } + } else if (this.has_by_data("BYMONTHDAY")) { + // Change the day value so that normalisation won't change the month. + this.last.day = 1; + + // Get a sorted list of days in the starting month that match the rule. + let normalized = this.normalizeByMonthDayRules( + this.last.year, + this.last.month, + this.rule.parts.BYMONTHDAY + ).filter(d => d >= this.last.day); + + if (normalized.length) { + // There's at least one valid day, use it. + this.last.day = normalized[0]; + this.by_data.BYMONTHDAY = normalized; + } else { + // There's no occurrence in this month, find the next valid month. + // The longest possible sequence of skipped months is February-April-June, + // so we might need to call next_month up to three times. + if (!this.next_month() && !this.next_month() && !this.next_month()) { + throw new InvalidRecurrenceRuleError(); + } + } + } + } + } + + /** + * Retrieve the next occurrence from the iterator. + * @return {Time} + */ + next(again = false) { + let before = (this.last ? this.last.clone() : null); + + if ((this.rule.count && this.occurrence_number >= this.rule.count) || + (this.rule.until && this.last.compare(this.rule.until) > 0)) { + this.completed = true; + } + + if (this.completed) { + return null; + } + + if (this.occurrence_number == 0 && this.last.compare(this.dtstart) >= 0) { + // First of all, give the instance that was initialized + this.occurrence_number++; + return this.last; + } + + let valid; + let invalid_count = 0; + do { + valid = 1; + + switch (this.rule.freq) { + case "SECONDLY": + this.next_second(); + break; + case "MINUTELY": + this.next_minute(); + break; + case "HOURLY": + this.next_hour(); + break; + case "DAILY": + this.next_day(); + break; + case "WEEKLY": + this.next_week(); + break; + case "MONTHLY": + valid = this.next_month(); + if (valid) { + invalid_count = 0; + } else if (++invalid_count == 336) { + // We've been through all 91 month variations and not found a recurrence. Stop. + // (12 months and 29-day February × 7 starting days.) + this.completed = true; + return null; + } + break; + case "YEARLY": + valid = this.next_year(); + if (valid) { + invalid_count = 0; + } else if (++invalid_count == 28) { + // We've been through all 14 year variations and not found a recurrence. Stop. + // (365-day and 366-day years × 7 starting days.) + this.completed = true; + return null; + } + break; + + default: + return null; + } + } while (!this.check_contracting_rules() || + this.last.compare(this.dtstart) < 0 || + !valid); + + if (this.last.compare(before) == 0) { + if (again) { + throw new Error("Same occurrence found twice, protecting you from death by recursion"); + } + this.next(true); + } + + if (this.rule.until && this.last.compare(this.rule.until) > 0) { + this.completed = true; + return null; + } else { + this.occurrence_number++; + return this.last; + } + } + + next_second() { + return this.next_generic("BYSECOND", "SECONDLY", "second", "minute"); + } + + increment_second(inc) { + return this.increment_generic(inc, "second", 60, "minute"); + } + + next_minute() { + return this.next_generic("BYMINUTE", "MINUTELY", + "minute", "hour", "next_second"); + } + + increment_minute(inc) { + return this.increment_generic(inc, "minute", 60, "hour"); + } + + next_hour() { + return this.next_generic("BYHOUR", "HOURLY", "hour", + "monthday", "next_minute"); + } + + increment_hour(inc) { + this.increment_generic(inc, "hour", 24, "monthday"); + } + + next_day() { + let this_freq = (this.rule.freq == "DAILY"); + + if (this.next_hour() == 0) { + return 0; + } + + if (this_freq) { + this.increment_monthday(this.rule.interval); + } else { + this.increment_monthday(1); + } + + return 0; + } + + next_week() { + let end_of_data = 0; + + if (this.next_weekday_by_week() == 0) { + return end_of_data; + } + + if (this.has_by_data("BYWEEKNO")) { + this.by_indices.BYWEEKNO++; + + if (this.by_indices.BYWEEKNO == this.by_data.BYWEEKNO.length) { + this.by_indices.BYWEEKNO = 0; + end_of_data = 1; + } + + // HACK should be first month of the year + this.last.month = 1; + this.last.day = 1; + + let week_no = this.by_data.BYWEEKNO[this.by_indices.BYWEEKNO]; + + this.last.day += 7 * week_no; + + if (end_of_data) { + this.increment_year(1); + } + } else { + // Jump to the next week + this.increment_monthday(7 * this.rule.interval); + } + + return end_of_data; + } + + /** + * Normalize each by day rule for a given year/month. + * Takes into account ordering and negative rules + * + * @private + * @param {Number} year Current year. + * @param {Number} month Current month. + * @param {Array} rules Array of rules. + * + * @return {Array} sorted and normalized rules. + * Negative rules will be expanded to their + * correct positive values for easier processing. + */ + normalizeByMonthDayRules(year, month, rules) { + let daysInMonth = Time.daysInMonth(month, year); + + // XXX: This is probably bad for performance to allocate + // a new array for each month we scan, if possible + // we should try to optimize this... + let newRules = []; + + let ruleIdx = 0; + let len = rules.length; + let rule; + + for (; ruleIdx < len; ruleIdx++) { + rule = parseInt(rules[ruleIdx], 10); + if (isNaN(rule)) { + throw new Error('Invalid BYMONTHDAY value'); + } + + // if this rule falls outside of given + // month discard it. + if (Math.abs(rule) > daysInMonth) { + continue; + } + + // negative case + if (rule < 0) { + // we add (not subtract it is a negative number) + // one from the rule because 1 === last day of month + rule = daysInMonth + (rule + 1); + } else if (rule === 0) { + // skip zero: it is invalid. + continue; + } + + // only add unique items... + if (newRules.indexOf(rule) === -1) { + newRules.push(rule); + } + + } + + // unique and sort + return newRules.sort(function(a, b) { return a - b; }); + } + + /** + * NOTES: + * We are given a list of dates in the month (BYMONTHDAY) (23, etc..) + * Also we are given a list of days (BYDAY) (MO, 2SU, etc..) when + * both conditions match a given date (this.last.day) iteration stops. + * + * @private + * @param {Boolean=} isInit When given true will not increment the + * current day (this.last). + */ + _byDayAndMonthDay(isInit) { + let byMonthDay; // setup in initMonth + let byDay = this.by_data.BYDAY; + + let date; + let dateIdx = 0; + let dateLen; // setup in initMonth + let dayLen = byDay.length; + + // we are not valid by default + let dataIsValid = 0; + + let daysInMonth; + let self = this; + // we need a copy of this, because a DateTime gets normalized + // automatically if the day is out of range. At some points we + // set the last day to 0 to start counting. + let lastDay = this.last.day; + + function initMonth() { + daysInMonth = Time.daysInMonth( + self.last.month, self.last.year + ); + + byMonthDay = self.normalizeByMonthDayRules( + self.last.year, + self.last.month, + self.by_data.BYMONTHDAY + ); + + dateLen = byMonthDay.length; + + // For the case of more than one occurrence in one month + // we have to be sure to start searching after the last + // found date or at the last BYMONTHDAY, unless we are + // initializing the iterator because in this case we have + // to consider the last found date too. + while (byMonthDay[dateIdx] <= lastDay && + !(isInit && byMonthDay[dateIdx] == lastDay) && + dateIdx < dateLen - 1) { + dateIdx++; + } + } + + function nextMonth() { + // since the day is incremented at the start + // of the loop below, we need to start at 0 + lastDay = 0; + self.increment_month(); + dateIdx = 0; + initMonth(); + } + + initMonth(); + + // should come after initMonth + if (isInit) { + lastDay -= 1; + } + + // Use a counter to avoid an infinite loop with malformed rules. + // Stop checking after 4 years so we consider also a leap year. + let monthsCounter = 48; + + while (!dataIsValid && monthsCounter) { + monthsCounter--; + // increment the current date. This is really + // important otherwise we may fall into the infinite + // loop trap. The initial date takes care of the case + // where the current date is the date we are looking + // for. + date = lastDay + 1; + + if (date > daysInMonth) { + nextMonth(); + continue; + } + + // find next date + let next = byMonthDay[dateIdx++]; + + // this logic is dependent on the BYMONTHDAYS + // being in order (which is done by #normalizeByMonthDayRules) + if (next >= date) { + // if the next month day is in the future jump to it. + lastDay = next; + } else { + // in this case the 'next' monthday has past + // we must move to the month. + nextMonth(); + continue; + } + + // Now we can loop through the day rules to see + // if one matches the current month date. + for (let dayIdx = 0; dayIdx < dayLen; dayIdx++) { + let parts = this.ruleDayOfWeek(byDay[dayIdx]); + let pos = parts[0]; + let dow = parts[1]; + + this.last.day = lastDay; + if (this.last.isNthWeekDay(dow, pos)) { + // when we find the valid one we can mark + // the conditions as met and break the loop. + // (Because we have this condition above + // it will also break the parent loop). + dataIsValid = 1; + break; + } + } + + // It is completely possible that the combination + // cannot be matched in the current month. + // When we reach the end of possible combinations + // in the current month we iterate to the next one. + // since dateIdx is incremented right after getting + // "next", we don't need dateLen -1 here. + if (!dataIsValid && dateIdx === dateLen) { + nextMonth(); + continue; + } + } + + if (monthsCounter <= 0) { + // Checked 4 years without finding a Byday that matches + // a Bymonthday. Maybe the rule is not correct. + throw new Error("Malformed values in BYDAY combined with BYMONTHDAY parts"); + } + + + return dataIsValid; + } + + next_month() { + let data_valid = 1; + + if (this.next_hour() == 0) { + return data_valid; + } + + if (this.has_by_data("BYDAY") && this.has_by_data("BYMONTHDAY")) { + data_valid = this._byDayAndMonthDay(); + } else if (this.has_by_data("BYDAY")) { + let daysInMonth = Time.daysInMonth(this.last.month, this.last.year); + let setpos = 0; + let setpos_total = 0; + + if (this.has_by_data("BYSETPOS")) { + let last_day = this.last.day; + for (let day = 1; day <= daysInMonth; day++) { + this.last.day = day; + if (this.is_day_in_byday(this.last)) { + setpos_total++; + if (day <= last_day) { + setpos++; + } + } + } + this.last.day = last_day; + } + + data_valid = 0; + let day; + for (day = this.last.day + 1; day <= daysInMonth; day++) { + this.last.day = day; + + if (this.is_day_in_byday(this.last)) { + if (!this.has_by_data("BYSETPOS") || + this.check_set_position(++setpos) || + this.check_set_position(setpos - setpos_total - 1)) { + + data_valid = 1; + break; + } + } + } + + if (day > daysInMonth) { + this.last.day = 1; + this.increment_month(); + + if (this.is_day_in_byday(this.last)) { + if (!this.has_by_data("BYSETPOS") || this.check_set_position(1)) { + data_valid = 1; + } + } else { + data_valid = 0; + } + } + } else if (this.has_by_data("BYMONTHDAY")) { + this.by_indices.BYMONTHDAY++; + + if (this.by_indices.BYMONTHDAY >= this.by_data.BYMONTHDAY.length) { + this.by_indices.BYMONTHDAY = 0; + this.increment_month(); + if (this.by_indices.BYMONTHDAY >= this.by_data.BYMONTHDAY.length) { + return 0; + } + } + + let daysInMonth = Time.daysInMonth(this.last.month, this.last.year); + let day = this.by_data.BYMONTHDAY[this.by_indices.BYMONTHDAY]; + + if (day < 0) { + day = daysInMonth + day + 1; + } + + if (day > daysInMonth) { + this.last.day = 1; + data_valid = this.is_day_in_byday(this.last); + } else { + this.last.day = day; + } + } else { + this.increment_month(); + let daysInMonth = Time.daysInMonth(this.last.month, this.last.year); + if (this.by_data.BYMONTHDAY[0] > daysInMonth) { + data_valid = 0; + } else { + this.last.day = this.by_data.BYMONTHDAY[0]; + } + } + + return data_valid; + } + + next_weekday_by_week() { + let end_of_data = 0; + + if (this.next_hour() == 0) { + return end_of_data; + } + + if (!this.has_by_data("BYDAY")) { + return 1; + } + + for (;;) { + let tt = new Time(); + this.by_indices.BYDAY++; + + if (this.by_indices.BYDAY == Object.keys(this.by_data.BYDAY).length) { + this.by_indices.BYDAY = 0; + end_of_data = 1; + } + + let coded_day = this.by_data.BYDAY[this.by_indices.BYDAY]; + let parts = this.ruleDayOfWeek(coded_day); + let dow = parts[1]; + + dow -= this.rule.wkst; + + if (dow < 0) { + dow += 7; + } + + tt.year = this.last.year; + tt.month = this.last.month; + tt.day = this.last.day; + + let startOfWeek = tt.startDoyWeek(this.rule.wkst); + + if (dow + startOfWeek < 1) { + // The selected date is in the previous year + if (!end_of_data) { + continue; + } + } + + let next = Time.fromDayOfYear(startOfWeek + dow, this.last.year); + + /** + * The normalization horrors below are due to + * the fact that when the year/month/day changes + * it can effect the other operations that come after. + */ + this.last.year = next.year; + this.last.month = next.month; + this.last.day = next.day; + + return end_of_data; + } + } + + next_year() { + if (this.next_hour() == 0) { + return 0; + } + + if (this.days.length == 0 || ++this.days_index == this.days.length) { + this.days_index = 0; + this.increment_year(this.rule.interval); + if (this.has_by_data("BYMONTHDAY")) { + this.by_data.BYMONTHDAY = this.normalizeByMonthDayRules( + this.last.year, + this.last.month, + this.rule.parts.BYMONTHDAY + ); + } + this.expand_year_days(this.last.year); + if (this.days.length == 0) { + return 0; + } + } + + return this._nextByYearDay(); + } + + _nextByYearDay() { + let doy = this.days[this.days_index]; + let year = this.last.year; + + if (Math.abs(doy) == 366 && !Time.isLeapYear(this.last.year)) { + return 0; + } + + if (doy < 1) { + // Time.fromDayOfYear(doy, year) indexes relative to the + // start of the given year. That is different from the + // semantics of BYYEARDAY where negative indexes are an + // offset from the end of the given year. + doy += 1; + year += 1; + } + let next = Time.fromDayOfYear(doy, year); + this.last.day = next.day; + this.last.month = next.month; + + return 1; + } + + /** + * @param dow (eg: '1TU', '-1MO') + * @param {weekDay=} aWeekStart The week start weekday + * @return [pos, numericDow] (eg: [1, 3]) numericDow is relative to aWeekStart + */ + ruleDayOfWeek(dow, aWeekStart) { + let matches = dow.match(/([+-]?[0-9])?(MO|TU|WE|TH|FR|SA|SU)/); + if (matches) { + let pos = parseInt(matches[1] || 0, 10); + dow = Recur.icalDayToNumericDay(matches[2], aWeekStart); + return [pos, dow]; + } else { + return [0, 0]; + } + } + + next_generic(aRuleType, aInterval, aDateAttr, aFollowingAttr, aPreviousIncr) { + let has_by_rule = (aRuleType in this.by_data); + let this_freq = (this.rule.freq == aInterval); + let end_of_data = 0; + + if (aPreviousIncr && this[aPreviousIncr]() == 0) { + return end_of_data; + } + + if (has_by_rule) { + this.by_indices[aRuleType]++; + let dta = this.by_data[aRuleType]; + + if (this.by_indices[aRuleType] == dta.length) { + this.by_indices[aRuleType] = 0; + end_of_data = 1; + } + this.last[aDateAttr] = dta[this.by_indices[aRuleType]]; + } else if (this_freq) { + this["increment_" + aDateAttr](this.rule.interval); + } + + if (has_by_rule && end_of_data && this_freq) { + this["increment_" + aFollowingAttr](1); + } + + return end_of_data; + } + + increment_monthday(inc) { + for (let i = 0; i < inc; i++) { + let daysInMonth = Time.daysInMonth(this.last.month, this.last.year); + this.last.day++; + + if (this.last.day > daysInMonth) { + this.last.day -= daysInMonth; + this.increment_month(); + } + } + } + + increment_month() { + this.last.day = 1; + if (this.has_by_data("BYMONTH")) { + this.by_indices.BYMONTH++; + + if (this.by_indices.BYMONTH == this.by_data.BYMONTH.length) { + this.by_indices.BYMONTH = 0; + this.increment_year(1); + } + + this.last.month = this.by_data.BYMONTH[this.by_indices.BYMONTH]; + } else { + if (this.rule.freq == "MONTHLY") { + this.last.month += this.rule.interval; + } else { + this.last.month++; + } + + this.last.month--; + let years = trunc(this.last.month / 12); + this.last.month %= 12; + this.last.month++; + + if (years != 0) { + this.increment_year(years); + } + } + + if (this.has_by_data("BYMONTHDAY")) { + this.by_data.BYMONTHDAY = this.normalizeByMonthDayRules( + this.last.year, + this.last.month, + this.rule.parts.BYMONTHDAY + ); + } + } + + increment_year(inc) { + // Don't jump into the next month if this.last is Feb 29. + this.last.day = 1; + this.last.year += inc; + } + + increment_generic(inc, aDateAttr, aFactor, aNextIncrement) { + this.last[aDateAttr] += inc; + let nextunit = trunc(this.last[aDateAttr] / aFactor); + this.last[aDateAttr] %= aFactor; + if (nextunit != 0) { + this["increment_" + aNextIncrement](nextunit); + } + } + + has_by_data(aRuleType) { + return (aRuleType in this.rule.parts); + } + + expand_year_days(aYear) { + let t = new Time(); + this.days = []; + + // We need our own copy with a few keys set + let parts = {}; + let rules = ["BYDAY", "BYWEEKNO", "BYMONTHDAY", "BYMONTH", "BYYEARDAY"]; + for (let part of rules) { + if (part in this.rule.parts) { + parts[part] = this.rule.parts[part]; + } + } + + if ("BYMONTH" in parts && "BYWEEKNO" in parts) { + let valid = 1; + let validWeeks = {}; + t.year = aYear; + t.isDate = true; + + for (let monthIdx = 0; monthIdx < this.by_data.BYMONTH.length; monthIdx++) { + let month = this.by_data.BYMONTH[monthIdx]; + t.month = month; + t.day = 1; + let first_week = t.weekNumber(this.rule.wkst); + t.day = Time.daysInMonth(month, aYear); + let last_week = t.weekNumber(this.rule.wkst); + for (monthIdx = first_week; monthIdx < last_week; monthIdx++) { + validWeeks[monthIdx] = 1; + } + } + + for (let weekIdx = 0; weekIdx < this.by_data.BYWEEKNO.length && valid; weekIdx++) { + let weekno = this.by_data.BYWEEKNO[weekIdx]; + if (weekno < 52) { + valid &= validWeeks[weekIdx]; + } else { + valid = 0; + } + } + + if (valid) { + delete parts.BYMONTH; + } else { + delete parts.BYWEEKNO; + } + } + + let partCount = Object.keys(parts).length; + + if (partCount == 0) { + let t1 = this.dtstart.clone(); + t1.year = this.last.year; + this.days.push(t1.dayOfYear()); + } else if (partCount == 1 && "BYMONTH" in parts) { + for (let month of this.by_data.BYMONTH) { + let t2 = this.dtstart.clone(); + t2.year = aYear; + t2.month = month; + t2.isDate = true; + this.days.push(t2.dayOfYear()); + } + } else if (partCount == 1 && "BYMONTHDAY" in parts) { + for (let monthday of this.by_data.BYMONTHDAY) { + let t3 = this.dtstart.clone(); + if (monthday < 0) { + let daysInMonth = Time.daysInMonth(t3.month, aYear); + monthday = monthday + daysInMonth + 1; + } + t3.day = monthday; + t3.year = aYear; + t3.isDate = true; + this.days.push(t3.dayOfYear()); + } + } else if (partCount == 2 && + "BYMONTHDAY" in parts && + "BYMONTH" in parts) { + for (let month of this.by_data.BYMONTH) { + let daysInMonth = Time.daysInMonth(month, aYear); + for (let monthday of this.by_data.BYMONTHDAY) { + if (monthday < 0) { + monthday = monthday + daysInMonth + 1; + } + t.day = monthday; + t.month = month; + t.year = aYear; + t.isDate = true; + + this.days.push(t.dayOfYear()); + } + } + } else if (partCount == 1 && "BYWEEKNO" in parts) ; else if (partCount == 2 && + "BYWEEKNO" in parts && + "BYMONTHDAY" in parts) ; else if (partCount == 1 && "BYDAY" in parts) { + this.days = this.days.concat(this.expand_by_day(aYear)); + } else if (partCount == 2 && "BYDAY" in parts && "BYMONTH" in parts) { + for (let month of this.by_data.BYMONTH) { + let daysInMonth = Time.daysInMonth(month, aYear); + + t.year = aYear; + t.month = month; + t.day = 1; + t.isDate = true; + + let first_dow = t.dayOfWeek(); + let doy_offset = t.dayOfYear() - 1; + + t.day = daysInMonth; + let last_dow = t.dayOfWeek(); + + if (this.has_by_data("BYSETPOS")) { + let by_month_day = []; + for (let day = 1; day <= daysInMonth; day++) { + t.day = day; + if (this.is_day_in_byday(t)) { + by_month_day.push(day); + } + } + + for (let spIndex = 0; spIndex < by_month_day.length; spIndex++) { + if (this.check_set_position(spIndex + 1) || + this.check_set_position(spIndex - by_month_day.length)) { + this.days.push(doy_offset + by_month_day[spIndex]); + } + } + } else { + for (let coded_day of this.by_data.BYDAY) { + let bydayParts = this.ruleDayOfWeek(coded_day); + let pos = bydayParts[0]; + let dow = bydayParts[1]; + let month_day; + + let first_matching_day = ((dow + 7 - first_dow) % 7) + 1; + let last_matching_day = daysInMonth - ((last_dow + 7 - dow) % 7); + + if (pos == 0) { + for (let day = first_matching_day; day <= daysInMonth; day += 7) { + this.days.push(doy_offset + day); + } + } else if (pos > 0) { + month_day = first_matching_day + (pos - 1) * 7; + + if (month_day <= daysInMonth) { + this.days.push(doy_offset + month_day); + } + } else { + month_day = last_matching_day + (pos + 1) * 7; + + if (month_day > 0) { + this.days.push(doy_offset + month_day); + } + } + } + } + } + // Return dates in order of occurrence (1,2,3,...) instead + // of by groups of weekdays (1,8,15,...,2,9,16,...). + this.days.sort(function(a, b) { return a - b; }); // Comparator function allows to sort numbers. + } else if (partCount == 2 && "BYDAY" in parts && "BYMONTHDAY" in parts) { + let expandedDays = this.expand_by_day(aYear); + + for (let day of expandedDays) { + let tt = Time.fromDayOfYear(day, aYear); + if (this.by_data.BYMONTHDAY.indexOf(tt.day) >= 0) { + this.days.push(day); + } + } + } else if (partCount == 3 && + "BYDAY" in parts && + "BYMONTHDAY" in parts && + "BYMONTH" in parts) { + let expandedDays = this.expand_by_day(aYear); + + for (let day of expandedDays) { + let tt = Time.fromDayOfYear(day, aYear); + + if (this.by_data.BYMONTH.indexOf(tt.month) >= 0 && + this.by_data.BYMONTHDAY.indexOf(tt.day) >= 0) { + this.days.push(day); + } + } + } else if (partCount == 2 && "BYDAY" in parts && "BYWEEKNO" in parts) { + let expandedDays = this.expand_by_day(aYear); + + for (let day of expandedDays) { + let tt = Time.fromDayOfYear(day, aYear); + let weekno = tt.weekNumber(this.rule.wkst); + + if (this.by_data.BYWEEKNO.indexOf(weekno)) { + this.days.push(day); + } + } + } else if (partCount == 3 && + "BYDAY" in parts && + "BYWEEKNO" in parts && + "BYMONTHDAY" in parts) ; else if (partCount == 1 && "BYYEARDAY" in parts) { + this.days = this.days.concat(this.by_data.BYYEARDAY); + } else if (partCount == 2 && "BYYEARDAY" in parts && "BYDAY" in parts) { + let daysInYear = Time.isLeapYear(aYear) ? 366 : 365; + let expandedDays = new Set(this.expand_by_day(aYear)); + + for (let doy of this.by_data.BYYEARDAY) { + if (doy < 0) { + doy += daysInYear + 1; + } + + if (expandedDays.has(doy)) { + this.days.push(doy); + } + } + } else { + this.days = []; + } + + let daysInYear = Time.isLeapYear(aYear) ? 366 : 365; + this.days.sort((a, b) => { + if (a < 0) a += daysInYear + 1; + if (b < 0) b += daysInYear + 1; + return a - b; + }); + + return 0; + } + + expand_by_day(aYear) { + + let days_list = []; + let tmp = this.last.clone(); + + tmp.year = aYear; + tmp.month = 1; + tmp.day = 1; + tmp.isDate = true; + + let start_dow = tmp.dayOfWeek(); + + tmp.month = 12; + tmp.day = 31; + tmp.isDate = true; + + let end_dow = tmp.dayOfWeek(); + let end_year_day = tmp.dayOfYear(); + + for (let day of this.by_data.BYDAY) { + let parts = this.ruleDayOfWeek(day); + let pos = parts[0]; + let dow = parts[1]; + + if (pos == 0) { + let tmp_start_doy = ((dow + 7 - start_dow) % 7) + 1; + + for (let doy = tmp_start_doy; doy <= end_year_day; doy += 7) { + days_list.push(doy); + } + + } else if (pos > 0) { + let first; + if (dow >= start_dow) { + first = dow - start_dow + 1; + } else { + first = dow - start_dow + 8; + } + + days_list.push(first + (pos - 1) * 7); + } else { + let last; + pos = -pos; + + if (dow <= end_dow) { + last = end_year_day - end_dow + dow; + } else { + last = end_year_day - end_dow + dow - 7; + } + + days_list.push(last - (pos - 1) * 7); + } + } + return days_list; + } + + is_day_in_byday(tt) { + if (this.by_data.BYDAY) { + for (let day of this.by_data.BYDAY) { + let parts = this.ruleDayOfWeek(day); + let pos = parts[0]; + let dow = parts[1]; + let this_dow = tt.dayOfWeek(); + + if ((pos == 0 && dow == this_dow) || + (tt.nthWeekDay(dow, pos) == tt.day)) { + return 1; + } + } + } + + return 0; + } + + /** + * Checks if given value is in BYSETPOS. + * + * @private + * @param {Numeric} aPos position to check for. + * @return {Boolean} false unless BYSETPOS rules exist + * and the given value is present in rules. + */ + check_set_position(aPos) { + if (this.has_by_data('BYSETPOS')) { + let idx = this.by_data.BYSETPOS.indexOf(aPos); + // negative numbers are not false-y + return idx !== -1; + } + return false; + } + + sort_byday_rules(aRules) { + for (let i = 0; i < aRules.length; i++) { + for (let j = 0; j < i; j++) { + let one = this.ruleDayOfWeek(aRules[j], this.rule.wkst)[1]; + let two = this.ruleDayOfWeek(aRules[i], this.rule.wkst)[1]; + + if (one > two) { + let tmp = aRules[i]; + aRules[i] = aRules[j]; + aRules[j] = tmp; + } + } + } + } + + check_contract_restriction(aRuleType, v) { + let indexMapValue = RecurIterator._indexMap[aRuleType]; + let ruleMapValue = RecurIterator._expandMap[this.rule.freq][indexMapValue]; + let pass = false; + + if (aRuleType in this.by_data && + ruleMapValue == RecurIterator.CONTRACT) { + + let ruleType = this.by_data[aRuleType]; + + for (let bydata of ruleType) { + if (bydata == v) { + pass = true; + break; + } + } + } else { + // Not a contracting byrule or has no data, test passes + pass = true; + } + return pass; + } + + check_contracting_rules() { + let dow = this.last.dayOfWeek(); + let weekNo = this.last.weekNumber(this.rule.wkst); + let doy = this.last.dayOfYear(); + + return (this.check_contract_restriction("BYSECOND", this.last.second) && + this.check_contract_restriction("BYMINUTE", this.last.minute) && + this.check_contract_restriction("BYHOUR", this.last.hour) && + this.check_contract_restriction("BYDAY", Recur.numericDayToIcalDay(dow)) && + this.check_contract_restriction("BYWEEKNO", weekNo) && + this.check_contract_restriction("BYMONTHDAY", this.last.day) && + this.check_contract_restriction("BYMONTH", this.last.month) && + this.check_contract_restriction("BYYEARDAY", doy)); + } + + setup_defaults(aRuleType, req, deftime) { + let indexMapValue = RecurIterator._indexMap[aRuleType]; + let ruleMapValue = RecurIterator._expandMap[this.rule.freq][indexMapValue]; + + if (ruleMapValue != RecurIterator.CONTRACT) { + if (!(aRuleType in this.by_data)) { + this.by_data[aRuleType] = [deftime]; + } + if (this.rule.freq != req) { + return this.by_data[aRuleType][0]; + } + } + return deftime; + } + + /** + * Convert iterator into a serialize-able object. Will preserve current + * iteration sequence to ensure the seamless continuation of the recurrence + * rule. + * @return {Object} + */ + toJSON() { + let result = Object.create(null); + + result.initialized = this.initialized; + result.rule = this.rule.toJSON(); + result.dtstart = this.dtstart.toJSON(); + result.by_data = this.by_data; + result.days = this.days; + result.last = this.last.toJSON(); + result.by_indices = this.by_indices; + result.occurrence_number = this.occurrence_number; + + return result; + } +} + +/** + * An error indicating that a recurrence rule is invalid and produces no + * occurrences. + * + * @extends {Error} + * @class + */ +class InvalidRecurrenceRuleError extends Error { + constructor() { + super("Recurrence rule has no valid occurrences"); + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * + * @ignore + * @typedef {import("./types.js").weekDay} weekDay + * Imports the 'weekDay' type from the "types.js" module + * @typedef {import("./types.js").frequencyValues} frequencyValues + * Imports the 'frequencyValues' type from the "types.js" module + */ + +const VALID_DAY_NAMES = /^(SU|MO|TU|WE|TH|FR|SA)$/; +const VALID_BYDAY_PART = /^([+-])?(5[0-3]|[1-4][0-9]|[1-9])?(SU|MO|TU|WE|TH|FR|SA)$/; +const DOW_MAP = { + SU: Time.SUNDAY, + MO: Time.MONDAY, + TU: Time.TUESDAY, + WE: Time.WEDNESDAY, + TH: Time.THURSDAY, + FR: Time.FRIDAY, + SA: Time.SATURDAY +}; + +const REVERSE_DOW_MAP = Object.fromEntries(Object.entries(DOW_MAP).map(entry => entry.reverse())); + +const ALLOWED_FREQ = ['SECONDLY', 'MINUTELY', 'HOURLY', + 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY']; + +/** + * This class represents the "recur" value type, used for example by RRULE. It provides methods to + * calculate occurrences among others. + * + * @memberof ICAL + */ +class Recur { + /** + * Creates a new {@link ICAL.Recur} instance from the passed string. + * + * @param {String} string The string to parse + * @return {Recur} The created recurrence instance + */ + static fromString(string) { + let data = this._stringToData(string, false); + return new Recur(data); + } + + /** + * Creates a new {@link ICAL.Recur} instance using members from the passed + * data object. + * + * @param {Object} aData An object with members of the recurrence + * @param {frequencyValues=} aData.freq The frequency value + * @param {Number=} aData.interval The INTERVAL value + * @param {weekDay=} aData.wkst The week start value + * @param {Time=} aData.until The end of the recurrence set + * @param {Number=} aData.count The number of occurrences + * @param {Array.=} aData.bysecond The seconds for the BYSECOND part + * @param {Array.=} aData.byminute The minutes for the BYMINUTE part + * @param {Array.=} aData.byhour The hours for the BYHOUR part + * @param {Array.=} aData.byday The BYDAY values + * @param {Array.=} aData.bymonthday The days for the BYMONTHDAY part + * @param {Array.=} aData.byyearday The days for the BYYEARDAY part + * @param {Array.=} aData.byweekno The weeks for the BYWEEKNO part + * @param {Array.=} aData.bymonth The month for the BYMONTH part + * @param {Array.=} aData.bysetpos The positionals for the BYSETPOS part + */ + static fromData(aData) { + return new Recur(aData); + } + + /** + * Converts a recurrence string to a data object, suitable for the fromData + * method. + * + * @private + * @param {String} string The string to parse + * @param {Boolean} fmtIcal If true, the string is considered to be an + * iCalendar string + * @return {Recur} The recurrence instance + */ + static _stringToData(string, fmtIcal) { + let dict = Object.create(null); + + // split is slower in FF but fast enough. + // v8 however this is faster then manual split? + let values = string.split(';'); + let len = values.length; + + for (let i = 0; i < len; i++) { + let parts = values[i].split('='); + let ucname = parts[0].toUpperCase(); + let lcname = parts[0].toLowerCase(); + let name = (fmtIcal ? lcname : ucname); + let value = parts[1]; + + if (ucname in partDesign) { + let partArr = value.split(','); + let partSet = new Set(); + + for (let part of partArr) { + partSet.add(partDesign[ucname](part)); + } + partArr = [...partSet]; + + dict[name] = (partArr.length == 1 ? partArr[0] : partArr); + } else if (ucname in optionDesign) { + optionDesign[ucname](value, dict, fmtIcal); + } else { + // Don't swallow unknown values. Just set them as they are. + dict[lcname] = value; + } + } + + return dict; + } + + /** + * Convert an ical representation of a day (SU, MO, etc..) + * into a numeric value of that day. + * + * @param {String} string The iCalendar day name + * @param {weekDay=} aWeekStart + * The week start weekday, defaults to SUNDAY + * @return {Number} Numeric value of given day + */ + static icalDayToNumericDay(string, aWeekStart) { + //XXX: this is here so we can deal + // with possibly invalid string values. + let firstDow = aWeekStart || Time.SUNDAY; + return ((DOW_MAP[string] - firstDow + 7) % 7) + 1; + } + + /** + * Convert a numeric day value into its ical representation (SU, MO, etc..) + * + * @param {Number} num Numeric value of given day + * @param {weekDay=} aWeekStart + * The week start weekday, defaults to SUNDAY + * @return {String} The ICAL day value, e.g SU,MO,... + */ + static numericDayToIcalDay(num, aWeekStart) { + //XXX: this is here so we can deal with possibly invalid number values. + // Also, this allows consistent mapping between day numbers and day + // names for external users. + let firstDow = aWeekStart || Time.SUNDAY; + let dow = (num + firstDow - Time.SUNDAY); + if (dow > 7) { + dow -= 7; + } + return REVERSE_DOW_MAP[dow]; + } + + /** + * Create a new instance of the Recur class. + * + * @param {Object} data An object with members of the recurrence + * @param {frequencyValues=} data.freq The frequency value + * @param {Number=} data.interval The INTERVAL value + * @param {weekDay=} data.wkst The week start value + * @param {Time=} data.until The end of the recurrence set + * @param {Number=} data.count The number of occurrences + * @param {Array.=} data.bysecond The seconds for the BYSECOND part + * @param {Array.=} data.byminute The minutes for the BYMINUTE part + * @param {Array.=} data.byhour The hours for the BYHOUR part + * @param {Array.=} data.byday The BYDAY values + * @param {Array.=} data.bymonthday The days for the BYMONTHDAY part + * @param {Array.=} data.byyearday The days for the BYYEARDAY part + * @param {Array.=} data.byweekno The weeks for the BYWEEKNO part + * @param {Array.=} data.bymonth The month for the BYMONTH part + * @param {Array.=} data.bysetpos The positionals for the BYSETPOS part + */ + constructor(data) { + this.wrappedJSObject = this; + this.parts = {}; + + if (data && typeof(data) === 'object') { + this.fromData(data); + } + } + + /** + * An object holding the BY-parts of the recurrence rule + * @memberof ICAL.Recur + * @typedef {Object} byParts + * @property {Array.=} BYSECOND The seconds for the BYSECOND part + * @property {Array.=} BYMINUTE The minutes for the BYMINUTE part + * @property {Array.=} BYHOUR The hours for the BYHOUR part + * @property {Array.=} BYDAY The BYDAY values + * @property {Array.=} BYMONTHDAY The days for the BYMONTHDAY part + * @property {Array.=} BYYEARDAY The days for the BYYEARDAY part + * @property {Array.=} BYWEEKNO The weeks for the BYWEEKNO part + * @property {Array.=} BYMONTH The month for the BYMONTH part + * @property {Array.=} BYSETPOS The positionals for the BYSETPOS part + */ + + /** + * An object holding the BY-parts of the recurrence rule + * @type {byParts} + */ + parts = null; + + /** + * The interval value for the recurrence rule. + * @type {Number} + */ + interval = 1; + + /** + * The week start day + * + * @type {weekDay} + * @default ICAL.Time.MONDAY + */ + wkst = Time.MONDAY; + + /** + * The end of the recurrence + * @type {?Time} + */ + until = null; + + /** + * The maximum number of occurrences + * @type {?Number} + */ + count = null; + + /** + * The frequency value. + * @type {frequencyValues} + */ + freq = null; + + /** + * The class identifier. + * @constant + * @type {String} + * @default "icalrecur" + */ + icalclass = "icalrecur"; + + /** + * The type name, to be used in the jCal object. + * @constant + * @type {String} + * @default "recur" + */ + icaltype = "recur"; + + /** + * Create a new iterator for this recurrence rule. The passed start date + * must be the start date of the event, not the start of the range to + * search in. + * + * @example + * let recur = comp.getFirstPropertyValue('rrule'); + * let dtstart = comp.getFirstPropertyValue('dtstart'); + * let iter = recur.iterator(dtstart); + * for (let next = iter.next(); next; next = iter.next()) { + * if (next.compare(rangeStart) < 0) { + * continue; + * } + * console.log(next.toString()); + * } + * + * @param {Time} aStart The item's start date + * @return {RecurIterator} The recurrence iterator + */ + iterator(aStart) { + return new RecurIterator({ + rule: this, + dtstart: aStart + }); + } + + /** + * Returns a clone of the recurrence object. + * + * @return {Recur} The cloned object + */ + clone() { + return new Recur(this.toJSON()); + } + + /** + * Checks if the current rule is finite, i.e. has a count or until part. + * + * @return {Boolean} True, if the rule is finite + */ + isFinite() { + return !!(this.count || this.until); + } + + /** + * Checks if the current rule has a count part, and not limited by an until + * part. + * + * @return {Boolean} True, if the rule is by count + */ + isByCount() { + return !!(this.count && !this.until); + } + + /** + * Adds a component (part) to the recurrence rule. This is not a component + * in the sense of {@link ICAL.Component}, but a part of the recurrence + * rule, i.e. BYMONTH. + * + * @param {String} aType The name of the component part + * @param {Array|String} aValue The component value + */ + addComponent(aType, aValue) { + let ucname = aType.toUpperCase(); + if (ucname in this.parts) { + this.parts[ucname].push(aValue); + } else { + this.parts[ucname] = [aValue]; + } + } + + /** + * Sets the component value for the given by-part. + * + * @param {String} aType The component part name + * @param {Array} aValues The component values + */ + setComponent(aType, aValues) { + this.parts[aType.toUpperCase()] = aValues.slice(); + } + + /** + * Gets (a copy) of the requested component value. + * + * @param {String} aType The component part name + * @return {Array} The component part value + */ + getComponent(aType) { + let ucname = aType.toUpperCase(); + return (ucname in this.parts ? this.parts[ucname].slice() : []); + } + + /** + * Retrieves the next occurrence after the given recurrence id. See the + * guide on {@tutorial terminology} for more details. + * + * NOTE: Currently, this method iterates all occurrences from the start + * date. It should not be called in a loop for performance reasons. If you + * would like to get more than one occurrence, you can iterate the + * occurrences manually, see the example on the + * {@link ICAL.Recur#iterator iterator} method. + * + * @param {Time} aStartTime The start of the event series + * @param {Time} aRecurrenceId The date of the last occurrence + * @return {Time} The next occurrence after + */ + getNextOccurrence(aStartTime, aRecurrenceId) { + let iter = this.iterator(aStartTime); + let next; + + do { + next = iter.next(); + } while (next && next.compare(aRecurrenceId) <= 0); + + if (next && aRecurrenceId.zone) { + next.zone = aRecurrenceId.zone; + } + + return next; + } + + /** + * Sets up the current instance using members from the passed data object. + * + * @param {Object} data An object with members of the recurrence + * @param {frequencyValues=} data.freq The frequency value + * @param {Number=} data.interval The INTERVAL value + * @param {weekDay=} data.wkst The week start value + * @param {Time=} data.until The end of the recurrence set + * @param {Number=} data.count The number of occurrences + * @param {Array.=} data.bysecond The seconds for the BYSECOND part + * @param {Array.=} data.byminute The minutes for the BYMINUTE part + * @param {Array.=} data.byhour The hours for the BYHOUR part + * @param {Array.=} data.byday The BYDAY values + * @param {Array.=} data.bymonthday The days for the BYMONTHDAY part + * @param {Array.=} data.byyearday The days for the BYYEARDAY part + * @param {Array.=} data.byweekno The weeks for the BYWEEKNO part + * @param {Array.=} data.bymonth The month for the BYMONTH part + * @param {Array.=} data.bysetpos The positionals for the BYSETPOS part + */ + fromData(data) { + for (let key in data) { + let uckey = key.toUpperCase(); + + if (uckey in partDesign) { + if (Array.isArray(data[key])) { + this.parts[uckey] = data[key]; + } else { + this.parts[uckey] = [data[key]]; + } + } else { + this[key] = data[key]; + } + } + + if (this.interval && typeof this.interval != "number") { + optionDesign.INTERVAL(this.interval, this); + } + + if (this.wkst && typeof this.wkst != "number") { + this.wkst = Recur.icalDayToNumericDay(this.wkst); + } + + if (this.until && !(this.until instanceof Time)) { + this.until = Time.fromString(this.until); + } + } + + /** + * The jCal representation of this recurrence type. + * @return {Object} + */ + toJSON() { + let res = Object.create(null); + res.freq = this.freq; + + if (this.count) { + res.count = this.count; + } + + if (this.interval > 1) { + res.interval = this.interval; + } + + for (let [k, kparts] of Object.entries(this.parts)) { + if (Array.isArray(kparts) && kparts.length == 1) { + res[k.toLowerCase()] = kparts[0]; + } else { + res[k.toLowerCase()] = clone(kparts); + } + } + + if (this.until) { + res.until = this.until.toString(); + } + if ('wkst' in this && this.wkst !== Time.DEFAULT_WEEK_START) { + res.wkst = Recur.numericDayToIcalDay(this.wkst); + } + return res; + } + + /** + * The string representation of this recurrence rule. + * @return {String} + */ + toString() { + // TODO retain order + let str = "FREQ=" + this.freq; + if (this.count) { + str += ";COUNT=" + this.count; + } + if (this.interval > 1) { + str += ";INTERVAL=" + this.interval; + } + for (let [k, v] of Object.entries(this.parts)) { + str += ";" + k + "=" + v; + } + if (this.until) { + str += ';UNTIL=' + this.until.toICALString(); + } + if ('wkst' in this && this.wkst !== Time.DEFAULT_WEEK_START) { + str += ';WKST=' + Recur.numericDayToIcalDay(this.wkst); + } + return str; + } +} + +function parseNumericValue(type, min, max, value) { + let result = value; + + if (value[0] === '+') { + result = value.slice(1); + } + + result = strictParseInt(result); + + if (min !== undefined && value < min) { + throw new Error( + type + ': invalid value "' + value + '" must be > ' + min + ); + } + + if (max !== undefined && value > max) { + throw new Error( + type + ': invalid value "' + value + '" must be < ' + min + ); + } + + return result; +} + +const optionDesign = { + FREQ: function(value, dict, fmtIcal) { + // yes this is actually equal or faster then regex. + // upside here is we can enumerate the valid values. + if (ALLOWED_FREQ.indexOf(value) !== -1) { + dict.freq = value; + } else { + throw new Error( + 'invalid frequency "' + value + '" expected: "' + + ALLOWED_FREQ.join(', ') + '"' + ); + } + }, + + COUNT: function(value, dict, fmtIcal) { + dict.count = strictParseInt(value); + }, + + INTERVAL: function(value, dict, fmtIcal) { + dict.interval = strictParseInt(value); + if (dict.interval < 1) { + // 0 or negative values are not allowed, some engines seem to generate + // it though. Assume 1 instead. + dict.interval = 1; + } + }, + + UNTIL: function(value, dict, fmtIcal) { + if (value.length > 10) { + dict.until = design.icalendar.value['date-time'].fromICAL(value); + } else { + dict.until = design.icalendar.value.date.fromICAL(value); + } + if (!fmtIcal) { + dict.until = Time.fromString(dict.until); + } + }, + + WKST: function(value, dict, fmtIcal) { + if (VALID_DAY_NAMES.test(value)) { + dict.wkst = Recur.icalDayToNumericDay(value); + } else { + throw new Error('invalid WKST value "' + value + '"'); + } + } +}; + +const partDesign = { + BYSECOND: parseNumericValue.bind(undefined, 'BYSECOND', 0, 60), + BYMINUTE: parseNumericValue.bind(undefined, 'BYMINUTE', 0, 59), + BYHOUR: parseNumericValue.bind(undefined, 'BYHOUR', 0, 23), + BYDAY: function(value) { + if (VALID_BYDAY_PART.test(value)) { + return value; + } else { + throw new Error('invalid BYDAY value "' + value + '"'); + } + }, + BYMONTHDAY: parseNumericValue.bind(undefined, 'BYMONTHDAY', -31, 31), + BYYEARDAY: parseNumericValue.bind(undefined, 'BYYEARDAY', -366, 366), + BYWEEKNO: parseNumericValue.bind(undefined, 'BYWEEKNO', -53, 53), + BYMONTH: parseNumericValue.bind(undefined, 'BYMONTH', 1, 12), + BYSETPOS: parseNumericValue.bind(undefined, 'BYSETPOS', -366, 366) +}; + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * @ignore + * @typedef {import("./types.js").designSet} designSet + * Imports the 'designSet' type from the "types.js" module + */ + +/** @module ICAL.design */ + +const FROM_ICAL_NEWLINE = /\\\\|\\;|\\,|\\[Nn]/g; +const TO_ICAL_NEWLINE = /\\|;|,|\n/g; +const FROM_VCARD_NEWLINE = /\\\\|\\,|\\[Nn]/g; +const TO_VCARD_NEWLINE = /\\|,|\n/g; + +function createTextType(fromNewline, toNewline) { + let result = { + matches: /.*/, + + fromICAL: function(aValue, structuredEscape) { + return replaceNewline(aValue, fromNewline, structuredEscape); + }, + + toICAL: function(aValue, structuredEscape) { + let regEx = toNewline; + if (structuredEscape) + regEx = new RegExp(regEx.source + '|' + structuredEscape, regEx.flags); + return aValue.replace(regEx, function(str) { + switch (str) { + case "\\": + return "\\\\"; + case ";": + return "\\;"; + case ",": + return "\\,"; + case "\n": + return "\\n"; + /* c8 ignore next 2 */ + default: + return str; + } + }); + } + }; + return result; +} + +// default types used multiple times +const DEFAULT_TYPE_TEXT = { defaultType: "text" }; +const DEFAULT_TYPE_TEXT_MULTI = { defaultType: "text", multiValue: "," }; +const DEFAULT_TYPE_TEXT_STRUCTURED = { defaultType: "text", structuredValue: ";" }; +const DEFAULT_TYPE_INTEGER = { defaultType: "integer" }; +const DEFAULT_TYPE_DATETIME_DATE = { defaultType: "date-time", allowedTypes: ["date-time", "date"] }; +const DEFAULT_TYPE_DATETIME = { defaultType: "date-time" }; +const DEFAULT_TYPE_URI = { defaultType: "uri" }; +const DEFAULT_TYPE_UTCOFFSET = { defaultType: "utc-offset" }; +const DEFAULT_TYPE_RECUR = { defaultType: "recur" }; +const DEFAULT_TYPE_DATE_ANDOR_TIME = { defaultType: "date-and-or-time", allowedTypes: ["date-time", "date", "text"] }; + +function replaceNewlineReplace(string) { + switch (string) { + case "\\\\": + return "\\"; + case "\\;": + return ";"; + case "\\,": + return ","; + case "\\n": + case "\\N": + return "\n"; + /* c8 ignore next 2 */ + default: + return string; + } +} + +function replaceNewline(value, newline, structuredEscape) { + // avoid regex when possible. + if (value.indexOf('\\') === -1) { + return value; + } + if (structuredEscape) + newline = new RegExp(newline.source + '|\\\\' + structuredEscape, newline.flags); + return value.replace(newline, replaceNewlineReplace); +} + +let commonProperties = { + "categories": DEFAULT_TYPE_TEXT_MULTI, + "url": DEFAULT_TYPE_URI, + "version": DEFAULT_TYPE_TEXT, + "uid": DEFAULT_TYPE_TEXT +}; + +let commonValues = { + "boolean": { + values: ["TRUE", "FALSE"], + + fromICAL: function(aValue) { + switch (aValue) { + case 'TRUE': + return true; + case 'FALSE': + return false; + default: + //TODO: parser warning + return false; + } + }, + + toICAL: function(aValue) { + if (aValue) { + return 'TRUE'; + } + return 'FALSE'; + } + + }, + float: { + matches: /^[+-]?\d+\.\d+$/, + + fromICAL: function(aValue) { + let parsed = parseFloat(aValue); + if (isStrictlyNaN(parsed)) { + // TODO: parser warning + return 0.0; + } + return parsed; + }, + + toICAL: function(aValue) { + return String(aValue); + } + }, + integer: { + fromICAL: function(aValue) { + let parsed = parseInt(aValue); + if (isStrictlyNaN(parsed)) { + return 0; + } + return parsed; + }, + + toICAL: function(aValue) { + return String(aValue); + } + }, + "utc-offset": { + toICAL: function(aValue) { + if (aValue.length < 7) { + // no seconds + // -0500 + return aValue.slice(0, 3) + + aValue.slice(4, 6); + } else { + // seconds + // -050000 + return aValue.slice(0, 3) + + aValue.slice(4, 6) + + aValue.slice(7, 9); + } + }, + + fromICAL: function(aValue) { + if (aValue.length < 6) { + // no seconds + // -05:00 + return aValue.slice(0, 3) + ':' + + aValue.slice(3, 5); + } else { + // seconds + // -05:00:00 + return aValue.slice(0, 3) + ':' + + aValue.slice(3, 5) + ':' + + aValue.slice(5, 7); + } + }, + + decorate: function(aValue) { + return UtcOffset.fromString(aValue); + }, + + undecorate: function(aValue) { + return aValue.toString(); + } + } +}; + +let icalParams = { + // Although the syntax is DQUOTE uri DQUOTE, I don't think we should + // enforce anything aside from it being a valid content line. + // + // At least some params require - if multi values are used - DQUOTEs + // for each of its values - e.g. delegated-from="uri1","uri2" + // To indicate this, I introduced the new k/v pair + // multiValueSeparateDQuote: true + // + // "ALTREP": { ... }, + + // CN just wants a param-value + // "CN": { ... } + + "cutype": { + values: ["INDIVIDUAL", "GROUP", "RESOURCE", "ROOM", "UNKNOWN"], + allowXName: true, + allowIanaToken: true + }, + + "delegated-from": { + valueType: "cal-address", + multiValue: ",", + multiValueSeparateDQuote: true + }, + "delegated-to": { + valueType: "cal-address", + multiValue: ",", + multiValueSeparateDQuote: true + }, + // "DIR": { ... }, // See ALTREP + "encoding": { + values: ["8BIT", "BASE64"] + }, + // "FMTTYPE": { ... }, // See ALTREP + "fbtype": { + values: ["FREE", "BUSY", "BUSY-UNAVAILABLE", "BUSY-TENTATIVE"], + allowXName: true, + allowIanaToken: true + }, + // "LANGUAGE": { ... }, // See ALTREP + "member": { + valueType: "cal-address", + multiValue: ",", + multiValueSeparateDQuote: true + }, + "partstat": { + // TODO These values are actually different per-component + values: ["NEEDS-ACTION", "ACCEPTED", "DECLINED", "TENTATIVE", + "DELEGATED", "COMPLETED", "IN-PROCESS"], + allowXName: true, + allowIanaToken: true + }, + "range": { + values: ["THISANDFUTURE"] + }, + "related": { + values: ["START", "END"] + }, + "reltype": { + values: ["PARENT", "CHILD", "SIBLING"], + allowXName: true, + allowIanaToken: true + }, + "role": { + values: ["REQ-PARTICIPANT", "CHAIR", + "OPT-PARTICIPANT", "NON-PARTICIPANT"], + allowXName: true, + allowIanaToken: true + }, + "rsvp": { + values: ["TRUE", "FALSE"] + }, + "sent-by": { + valueType: "cal-address" + }, + "tzid": { + matches: /^\// + }, + "value": { + // since the value here is a 'type' lowercase is used. + values: ["binary", "boolean", "cal-address", "date", "date-time", + "duration", "float", "integer", "period", "recur", "text", + "time", "uri", "utc-offset"], + allowXName: true, + allowIanaToken: true + } +}; + +// When adding a value here, be sure to add it to the parameter types! +const icalValues = extend(commonValues, { + text: createTextType(FROM_ICAL_NEWLINE, TO_ICAL_NEWLINE), + + uri: { + // TODO + /* ... */ + }, + + "binary": { + decorate: function(aString) { + return Binary.fromString(aString); + }, + + undecorate: function(aBinary) { + return aBinary.toString(); + } + }, + "cal-address": { + // needs to be an uri + }, + "date": { + decorate: function(aValue, aProp) { + if (design.strict) { + return Time.fromDateString(aValue, aProp); + } else { + return Time.fromString(aValue, aProp); + } + }, + + /** + * undecorates a time object. + */ + undecorate: function(aValue) { + return aValue.toString(); + }, + + fromICAL: function(aValue) { + // from: 20120901 + // to: 2012-09-01 + if (!design.strict && aValue.length >= 15) { + // This is probably a date-time, e.g. 20120901T130000Z + return icalValues["date-time"].fromICAL(aValue); + } else { + return aValue.slice(0, 4) + '-' + + aValue.slice(4, 6) + '-' + + aValue.slice(6, 8); + } + }, + + toICAL: function(aValue) { + // from: 2012-09-01 + // to: 20120901 + let len = aValue.length; + + if (len == 10) { + return aValue.slice(0, 4) + + aValue.slice(5, 7) + + aValue.slice(8, 10); + } else if (len >= 19) { + return icalValues["date-time"].toICAL(aValue); + } else { + //TODO: serialize warning? + return aValue; + } + + } + }, + "date-time": { + fromICAL: function(aValue) { + // from: 20120901T130000 + // to: 2012-09-01T13:00:00 + if (!design.strict && aValue.length == 8) { + // This is probably a date, e.g. 20120901 + return icalValues.date.fromICAL(aValue); + } else { + let result = aValue.slice(0, 4) + '-' + + aValue.slice(4, 6) + '-' + + aValue.slice(6, 8) + 'T' + + aValue.slice(9, 11) + ':' + + aValue.slice(11, 13) + ':' + + aValue.slice(13, 15); + + if (aValue[15] && aValue[15] === 'Z') { + result += 'Z'; + } + + return result; + } + }, + + toICAL: function(aValue) { + // from: 2012-09-01T13:00:00 + // to: 20120901T130000 + let len = aValue.length; + + if (len == 10 && !design.strict) { + return icalValues.date.toICAL(aValue); + } else if (len >= 19) { + let result = aValue.slice(0, 4) + + aValue.slice(5, 7) + + // grab the (DDTHH) segment + aValue.slice(8, 13) + + // MM + aValue.slice(14, 16) + + // SS + aValue.slice(17, 19); + + if (aValue[19] && aValue[19] === 'Z') { + result += 'Z'; + } + return result; + } else { + // TODO: error + return aValue; + } + }, + + decorate: function(aValue, aProp) { + if (design.strict) { + return Time.fromDateTimeString(aValue, aProp); + } else { + return Time.fromString(aValue, aProp); + } + }, + + undecorate: function(aValue) { + return aValue.toString(); + } + }, + duration: { + decorate: function(aValue) { + return Duration.fromString(aValue); + }, + undecorate: function(aValue) { + return aValue.toString(); + } + }, + period: { + fromICAL: function(string) { + let parts = string.split('/'); + parts[0] = icalValues['date-time'].fromICAL(parts[0]); + + if (!Duration.isValueString(parts[1])) { + parts[1] = icalValues['date-time'].fromICAL(parts[1]); + } + + return parts; + }, + + toICAL: function(parts) { + parts = parts.slice(); + if (!design.strict && parts[0].length == 10) { + parts[0] = icalValues.date.toICAL(parts[0]); + } else { + parts[0] = icalValues['date-time'].toICAL(parts[0]); + } + + if (!Duration.isValueString(parts[1])) { + if (!design.strict && parts[1].length == 10) { + parts[1] = icalValues.date.toICAL(parts[1]); + } else { + parts[1] = icalValues['date-time'].toICAL(parts[1]); + } + } + + return parts.join("/"); + }, + + decorate: function(aValue, aProp) { + return Period.fromJSON(aValue, aProp, !design.strict); + }, + + undecorate: function(aValue) { + return aValue.toJSON(); + } + }, + recur: { + fromICAL: function(string) { + return Recur._stringToData(string, true); + }, + + toICAL: function(data) { + let str = ""; + for (let [k, val] of Object.entries(data)) { + if (k == "until") { + if (val.length > 10) { + val = icalValues['date-time'].toICAL(val); + } else { + val = icalValues.date.toICAL(val); + } + } else if (k == "wkst") { + if (typeof val === 'number') { + val = Recur.numericDayToIcalDay(val); + } + } else if (Array.isArray(val)) { + val = val.join(","); + } + str += k.toUpperCase() + "=" + val + ";"; + } + return str.slice(0, Math.max(0, str.length - 1)); + }, + + decorate: function decorate(aValue) { + return Recur.fromData(aValue); + }, + + undecorate: function(aRecur) { + return aRecur.toJSON(); + } + }, + + time: { + fromICAL: function(aValue) { + // from: MMHHSS(Z)? + // to: HH:MM:SS(Z)? + if (aValue.length < 6) { + // TODO: parser exception? + return aValue; + } + + // HH::MM::SSZ? + let result = aValue.slice(0, 2) + ':' + + aValue.slice(2, 4) + ':' + + aValue.slice(4, 6); + + if (aValue[6] === 'Z') { + result += 'Z'; + } + + return result; + }, + + toICAL: function(aValue) { + // from: HH:MM:SS(Z)? + // to: MMHHSS(Z)? + if (aValue.length < 8) { + //TODO: error + return aValue; + } + + let result = aValue.slice(0, 2) + + aValue.slice(3, 5) + + aValue.slice(6, 8); + + if (aValue[8] === 'Z') { + result += 'Z'; + } + + return result; + } + } +}); + +let icalProperties = extend(commonProperties, { + + "action": DEFAULT_TYPE_TEXT, + "attach": { defaultType: "uri" }, + "attendee": { defaultType: "cal-address" }, + "calscale": DEFAULT_TYPE_TEXT, + "class": DEFAULT_TYPE_TEXT, + "comment": DEFAULT_TYPE_TEXT, + "completed": DEFAULT_TYPE_DATETIME, + "contact": DEFAULT_TYPE_TEXT, + "created": DEFAULT_TYPE_DATETIME, + "description": DEFAULT_TYPE_TEXT, + "dtend": DEFAULT_TYPE_DATETIME_DATE, + "dtstamp": DEFAULT_TYPE_DATETIME, + "dtstart": DEFAULT_TYPE_DATETIME_DATE, + "due": DEFAULT_TYPE_DATETIME_DATE, + "duration": { defaultType: "duration" }, + "exdate": { + defaultType: "date-time", + allowedTypes: ["date-time", "date"], + multiValue: ',' + }, + "exrule": DEFAULT_TYPE_RECUR, + "freebusy": { defaultType: "period", multiValue: "," }, + "geo": { defaultType: "float", structuredValue: ";" }, + "last-modified": DEFAULT_TYPE_DATETIME, + "location": DEFAULT_TYPE_TEXT, + "method": DEFAULT_TYPE_TEXT, + "organizer": { defaultType: "cal-address" }, + "percent-complete": DEFAULT_TYPE_INTEGER, + "priority": DEFAULT_TYPE_INTEGER, + "prodid": DEFAULT_TYPE_TEXT, + "related-to": DEFAULT_TYPE_TEXT, + "repeat": DEFAULT_TYPE_INTEGER, + "rdate": { + defaultType: "date-time", + allowedTypes: ["date-time", "date", "period"], + multiValue: ',', + detectType: function(string) { + if (string.indexOf('/') !== -1) { + return 'period'; + } + return (string.indexOf('T') === -1) ? 'date' : 'date-time'; + } + }, + "recurrence-id": DEFAULT_TYPE_DATETIME_DATE, + "resources": DEFAULT_TYPE_TEXT_MULTI, + "request-status": DEFAULT_TYPE_TEXT_STRUCTURED, + "rrule": DEFAULT_TYPE_RECUR, + "sequence": DEFAULT_TYPE_INTEGER, + "status": DEFAULT_TYPE_TEXT, + "summary": DEFAULT_TYPE_TEXT, + "transp": DEFAULT_TYPE_TEXT, + "trigger": { defaultType: "duration", allowedTypes: ["duration", "date-time"] }, + "tzoffsetfrom": DEFAULT_TYPE_UTCOFFSET, + "tzoffsetto": DEFAULT_TYPE_UTCOFFSET, + "tzurl": DEFAULT_TYPE_URI, + "tzid": DEFAULT_TYPE_TEXT, + "tzname": DEFAULT_TYPE_TEXT +}); + +// When adding a value here, be sure to add it to the parameter types! +const vcardValues = extend(commonValues, { + text: createTextType(FROM_VCARD_NEWLINE, TO_VCARD_NEWLINE), + uri: createTextType(FROM_VCARD_NEWLINE, TO_VCARD_NEWLINE), + + date: { + decorate: function(aValue) { + return VCardTime.fromDateAndOrTimeString(aValue, "date"); + }, + undecorate: function(aValue) { + return aValue.toString(); + }, + fromICAL: function(aValue) { + if (aValue.length == 8) { + return icalValues.date.fromICAL(aValue); + } else if (aValue[0] == '-' && aValue.length == 6) { + return aValue.slice(0, 4) + '-' + aValue.slice(4); + } else { + return aValue; + } + }, + toICAL: function(aValue) { + if (aValue.length == 10) { + return icalValues.date.toICAL(aValue); + } else if (aValue[0] == '-' && aValue.length == 7) { + return aValue.slice(0, 4) + aValue.slice(5); + } else { + return aValue; + } + } + }, + + time: { + decorate: function(aValue) { + return VCardTime.fromDateAndOrTimeString("T" + aValue, "time"); + }, + undecorate: function(aValue) { + return aValue.toString(); + }, + fromICAL: function(aValue) { + let splitzone = vcardValues.time._splitZone(aValue, true); + let zone = splitzone[0], value = splitzone[1]; + + //console.log("SPLIT: ",splitzone); + + if (value.length == 6) { + value = value.slice(0, 2) + ':' + + value.slice(2, 4) + ':' + + value.slice(4, 6); + } else if (value.length == 4 && value[0] != '-') { + value = value.slice(0, 2) + ':' + value.slice(2, 4); + } else if (value.length == 5) { + value = value.slice(0, 3) + ':' + value.slice(3, 5); + } + + if (zone.length == 5 && (zone[0] == '-' || zone[0] == '+')) { + zone = zone.slice(0, 3) + ':' + zone.slice(3); + } + + return value + zone; + }, + + toICAL: function(aValue) { + let splitzone = vcardValues.time._splitZone(aValue); + let zone = splitzone[0], value = splitzone[1]; + + if (value.length == 8) { + value = value.slice(0, 2) + + value.slice(3, 5) + + value.slice(6, 8); + } else if (value.length == 5 && value[0] != '-') { + value = value.slice(0, 2) + value.slice(3, 5); + } else if (value.length == 6) { + value = value.slice(0, 3) + value.slice(4, 6); + } + + if (zone.length == 6 && (zone[0] == '-' || zone[0] == '+')) { + zone = zone.slice(0, 3) + zone.slice(4); + } + + return value + zone; + }, + + _splitZone: function(aValue, isFromIcal) { + let lastChar = aValue.length - 1; + let signChar = aValue.length - (isFromIcal ? 5 : 6); + let sign = aValue[signChar]; + let zone, value; + + if (aValue[lastChar] == 'Z') { + zone = aValue[lastChar]; + value = aValue.slice(0, Math.max(0, lastChar)); + } else if (aValue.length > 6 && (sign == '-' || sign == '+')) { + zone = aValue.slice(signChar); + value = aValue.slice(0, Math.max(0, signChar)); + } else { + zone = ""; + value = aValue; + } + + return [zone, value]; + } + }, + + "date-time": { + decorate: function(aValue) { + return VCardTime.fromDateAndOrTimeString(aValue, "date-time"); + }, + + undecorate: function(aValue) { + return aValue.toString(); + }, + + fromICAL: function(aValue) { + return vcardValues['date-and-or-time'].fromICAL(aValue); + }, + + toICAL: function(aValue) { + return vcardValues['date-and-or-time'].toICAL(aValue); + } + }, + + "date-and-or-time": { + decorate: function(aValue) { + return VCardTime.fromDateAndOrTimeString(aValue, "date-and-or-time"); + }, + + undecorate: function(aValue) { + return aValue.toString(); + }, + + fromICAL: function(aValue) { + let parts = aValue.split('T'); + return (parts[0] ? vcardValues.date.fromICAL(parts[0]) : '') + + (parts[1] ? 'T' + vcardValues.time.fromICAL(parts[1]) : ''); + }, + + toICAL: function(aValue) { + let parts = aValue.split('T'); + return vcardValues.date.toICAL(parts[0]) + + (parts[1] ? 'T' + vcardValues.time.toICAL(parts[1]) : ''); + + } + }, + timestamp: icalValues['date-time'], + "language-tag": { + matches: /^[a-zA-Z0-9-]+$/ // Could go with a more strict regex here + }, + "phone-number": { + fromICAL: function(aValue) { + return Array.from(aValue).filter(function(c) { + return c === '\\' ? undefined : c; + }).join(''); + }, + toICAL: function(aValue) { + return Array.from(aValue).map(function(c) { + return c === ',' || c === ";" ? '\\' + c : c; + }).join(''); + } + } +}); + +let vcardParams = { + "type": { + valueType: "text", + multiValue: "," + }, + "value": { + // since the value here is a 'type' lowercase is used. + values: ["text", "uri", "date", "time", "date-time", "date-and-or-time", + "timestamp", "boolean", "integer", "float", "utc-offset", + "language-tag"], + allowXName: true, + allowIanaToken: true + } +}; + +let vcardProperties = extend(commonProperties, { + "adr": { defaultType: "text", structuredValue: ";", multiValue: "," }, + "anniversary": DEFAULT_TYPE_DATE_ANDOR_TIME, + "bday": DEFAULT_TYPE_DATE_ANDOR_TIME, + "caladruri": DEFAULT_TYPE_URI, + "caluri": DEFAULT_TYPE_URI, + "clientpidmap": DEFAULT_TYPE_TEXT_STRUCTURED, + "email": DEFAULT_TYPE_TEXT, + "fburl": DEFAULT_TYPE_URI, + "fn": DEFAULT_TYPE_TEXT, + "gender": DEFAULT_TYPE_TEXT_STRUCTURED, + "geo": DEFAULT_TYPE_URI, + "impp": DEFAULT_TYPE_URI, + "key": DEFAULT_TYPE_URI, + "kind": DEFAULT_TYPE_TEXT, + "lang": { defaultType: "language-tag" }, + "logo": DEFAULT_TYPE_URI, + "member": DEFAULT_TYPE_URI, + "n": { defaultType: "text", structuredValue: ";", multiValue: "," }, + "nickname": DEFAULT_TYPE_TEXT_MULTI, + "note": DEFAULT_TYPE_TEXT, + "org": { defaultType: "text", structuredValue: ";" }, + "photo": DEFAULT_TYPE_URI, + "related": DEFAULT_TYPE_URI, + "rev": { defaultType: "timestamp" }, + "role": DEFAULT_TYPE_TEXT, + "sound": DEFAULT_TYPE_URI, + "source": DEFAULT_TYPE_URI, + "tel": { defaultType: "uri", allowedTypes: ["uri", "text"] }, + "title": DEFAULT_TYPE_TEXT, + "tz": { defaultType: "text", allowedTypes: ["text", "utc-offset", "uri"] }, + "xml": DEFAULT_TYPE_TEXT +}); + +let vcard3Values = extend(commonValues, { + binary: icalValues.binary, + date: vcardValues.date, + "date-time": vcardValues["date-time"], + "phone-number": vcardValues["phone-number"], + uri: icalValues.uri, + text: vcardValues.text, + time: icalValues.time, + vcard: icalValues.text, + "utc-offset": { + toICAL: function(aValue) { + return aValue.slice(0, 7); + }, + + fromICAL: function(aValue) { + return aValue.slice(0, 7); + }, + + decorate: function(aValue) { + return UtcOffset.fromString(aValue); + }, + + undecorate: function(aValue) { + return aValue.toString(); + } + } +}); + +let vcard3Params = { + "type": { + valueType: "text", + multiValue: "," + }, + "value": { + // since the value here is a 'type' lowercase is used. + values: ["text", "uri", "date", "date-time", "phone-number", "time", + "boolean", "integer", "float", "utc-offset", "vcard", "binary"], + allowXName: true, + allowIanaToken: true + } +}; + +let vcard3Properties = extend(commonProperties, { + fn: DEFAULT_TYPE_TEXT, + n: { defaultType: "text", structuredValue: ";", multiValue: "," }, + nickname: DEFAULT_TYPE_TEXT_MULTI, + photo: { defaultType: "binary", allowedTypes: ["binary", "uri"] }, + bday: { + defaultType: "date-time", + allowedTypes: ["date-time", "date"], + detectType: function(string) { + return (string.indexOf('T') === -1) ? 'date' : 'date-time'; + } + }, + + adr: { defaultType: "text", structuredValue: ";", multiValue: "," }, + label: DEFAULT_TYPE_TEXT, + + tel: { defaultType: "phone-number" }, + email: DEFAULT_TYPE_TEXT, + mailer: DEFAULT_TYPE_TEXT, + + tz: { defaultType: "utc-offset", allowedTypes: ["utc-offset", "text"] }, + geo: { defaultType: "float", structuredValue: ";" }, + + title: DEFAULT_TYPE_TEXT, + role: DEFAULT_TYPE_TEXT, + logo: { defaultType: "binary", allowedTypes: ["binary", "uri"] }, + agent: { defaultType: "vcard", allowedTypes: ["vcard", "text", "uri"] }, + org: DEFAULT_TYPE_TEXT_STRUCTURED, + + note: DEFAULT_TYPE_TEXT_MULTI, + prodid: DEFAULT_TYPE_TEXT, + rev: { + defaultType: "date-time", + allowedTypes: ["date-time", "date"], + detectType: function(string) { + return (string.indexOf('T') === -1) ? 'date' : 'date-time'; + } + }, + "sort-string": DEFAULT_TYPE_TEXT, + sound: { defaultType: "binary", allowedTypes: ["binary", "uri"] }, + + class: DEFAULT_TYPE_TEXT, + key: { defaultType: "binary", allowedTypes: ["binary", "text"] } +}); + +/** + * iCalendar design set + * @type {designSet} + */ +let icalSet = { + name: "ical", + value: icalValues, + param: icalParams, + property: icalProperties, + propertyGroups: false +}; + +/** + * vCard 4.0 design set + * @type {designSet} + */ +let vcardSet = { + name: "vcard4", + value: vcardValues, + param: vcardParams, + property: vcardProperties, + propertyGroups: true +}; + +/** + * vCard 3.0 design set + * @type {designSet} + */ +let vcard3Set = { + name: "vcard3", + value: vcard3Values, + param: vcard3Params, + property: vcard3Properties, + propertyGroups: true +}; + +/** + * The design data, used by the parser to determine types for properties and + * other metadata needed to produce correct jCard/jCal data. + * + * @alias ICAL.design + * @exports module:ICAL.design + */ +const design = { + /** + * Can be set to false to make the parser more lenient. + */ + strict: true, + + /** + * The default set for new properties and components if none is specified. + * @type {designSet} + */ + defaultSet: icalSet, + + /** + * The default type for unknown properties + * @type {String} + */ + defaultType: 'unknown', + + /** + * Holds the design set for known top-level components + * + * @type {Object} + * @property {designSet} vcard vCard VCARD + * @property {designSet} vevent iCalendar VEVENT + * @property {designSet} vtodo iCalendar VTODO + * @property {designSet} vjournal iCalendar VJOURNAL + * @property {designSet} valarm iCalendar VALARM + * @property {designSet} vtimezone iCalendar VTIMEZONE + * @property {designSet} daylight iCalendar DAYLIGHT + * @property {designSet} standard iCalendar STANDARD + * + * @example + * let propertyName = 'fn'; + * let componentDesign = ICAL.design.components.vcard; + * let propertyDetails = componentDesign.property[propertyName]; + * if (propertyDetails.defaultType == 'text') { + * // Yep, sure is... + * } + */ + components: { + vcard: vcardSet, + vcard3: vcard3Set, + vevent: icalSet, + vtodo: icalSet, + vjournal: icalSet, + valarm: icalSet, + vtimezone: icalSet, + daylight: icalSet, + standard: icalSet + }, + + + /** + * The design set for iCalendar (rfc5545/rfc7265) components. + * @type {designSet} + */ + icalendar: icalSet, + + /** + * The design set for vCard (rfc6350/rfc7095) components. + * @type {designSet} + */ + vcard: vcardSet, + + /** + * The design set for vCard (rfc2425/rfc2426/rfc7095) components. + * @type {designSet} + */ + vcard3: vcard3Set, + + /** + * Gets the design set for the given component name. + * + * @param {String} componentName The name of the component + * @return {designSet} The design set for the component + */ + getDesignSet: function(componentName) { + let isInDesign = componentName && componentName in design.components; + return isInDesign ? design.components[componentName] : design.defaultSet; + } +}; + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * + * @ignore + * @typedef {import("./types.js").designSet} designSet + * Imports the 'designSet' type from the "types.js" module + */ + +const LINE_ENDING = '\r\n'; +const DEFAULT_VALUE_TYPE = 'unknown'; +const RFC6868_REPLACE_MAP = { '"': "^'", "\n": "^n", "^": "^^" }; + +/** + * Convert a full jCal/jCard array into a iCalendar/vCard string. + * + * @function ICAL.stringify + * @variation function + * @param {Array} jCal The jCal/jCard document + * @return {String} The stringified iCalendar/vCard document + */ +function stringify(jCal) { + if (typeof jCal[0] == "string") { + // This is a single component + jCal = [jCal]; + } + + let i = 0; + let len = jCal.length; + let result = ''; + + for (; i < len; i++) { + result += stringify.component(jCal[i]) + LINE_ENDING; + } + + return result; +} + +/** + * Converts an jCal component array into a ICAL string. + * Recursive will resolve sub-components. + * + * Exact component/property order is not saved all + * properties will come before subcomponents. + * + * @function ICAL.stringify.component + * @param {Array} component + * jCal/jCard fragment of a component + * @param {designSet} designSet + * The design data to use for this component + * @return {String} The iCalendar/vCard string + */ +stringify.component = function(component, designSet) { + let name = component[0].toUpperCase(); + let result = 'BEGIN:' + name + LINE_ENDING; + + let props = component[1]; + let propIdx = 0; + let propLen = props.length; + + let designSetName = component[0]; + // rfc6350 requires that in vCard 4.0 the first component is the VERSION + // component with as value 4.0, note that 3.0 does not have this requirement. + if (designSetName === 'vcard' && component[1].length > 0 && + !(component[1][0][0] === "version" && component[1][0][3] === "4.0")) { + designSetName = "vcard3"; + } + designSet = designSet || design.getDesignSet(designSetName); + + for (; propIdx < propLen; propIdx++) { + result += stringify.property(props[propIdx], designSet) + LINE_ENDING; + } + + // Ignore subcomponents if none exist, e.g. in vCard. + let comps = component[2] || []; + let compIdx = 0; + let compLen = comps.length; + + for (; compIdx < compLen; compIdx++) { + result += stringify.component(comps[compIdx], designSet) + LINE_ENDING; + } + + result += 'END:' + name; + return result; +}; + +/** + * Converts a single jCal/jCard property to a iCalendar/vCard string. + * + * @function ICAL.stringify.property + * @param {Array} property + * jCal/jCard property array + * @param {designSet} designSet + * The design data to use for this property + * @param {Boolean} noFold + * If true, the line is not folded + * @return {String} The iCalendar/vCard string + */ +stringify.property = function(property, designSet, noFold) { + let name = property[0].toUpperCase(); + let jsName = property[0]; + let params = property[1]; + + if (!designSet) { + designSet = design.defaultSet; + } + + let groupName = params.group; + let line; + if (designSet.propertyGroups && groupName) { + line = groupName.toUpperCase() + "." + name; + } else { + line = name; + } + + for (let [paramName, value] of Object.entries(params)) { + if (designSet.propertyGroups && paramName == 'group') { + continue; + } + + let paramDesign = designSet.param[paramName]; + let multiValue = paramDesign && paramDesign.multiValue; + if (multiValue && Array.isArray(value)) { + value = value.map(function(val) { + val = stringify._rfc6868Unescape(val); + val = stringify.paramPropertyValue(val, paramDesign.multiValueSeparateDQuote); + return val; + }); + value = stringify.multiValue(value, multiValue, "unknown", null, designSet); + } else { + value = stringify._rfc6868Unescape(value); + value = stringify.paramPropertyValue(value); + } + + line += ';' + paramName.toUpperCase() + '=' + value; + } + + if (property.length === 3) { + // If there are no values, we must assume a blank value + return line + ':'; + } + + let valueType = property[2]; + + let propDetails; + let multiValue = false; + let structuredValue = false; + let isDefault = false; + + if (jsName in designSet.property) { + propDetails = designSet.property[jsName]; + + if ('multiValue' in propDetails) { + multiValue = propDetails.multiValue; + } + + if (('structuredValue' in propDetails) && Array.isArray(property[3])) { + structuredValue = propDetails.structuredValue; + } + + if ('defaultType' in propDetails) { + if (valueType === propDetails.defaultType) { + isDefault = true; + } + } else { + if (valueType === DEFAULT_VALUE_TYPE) { + isDefault = true; + } + } + } else { + if (valueType === DEFAULT_VALUE_TYPE) { + isDefault = true; + } + } + + // push the VALUE property if type is not the default + // for the current property. + if (!isDefault) { + // value will never contain ;/:/, so we don't escape it here. + line += ';VALUE=' + valueType.toUpperCase(); + } + + line += ':'; + + if (multiValue && structuredValue) { + line += stringify.multiValue( + property[3], structuredValue, valueType, multiValue, designSet, structuredValue + ); + } else if (multiValue) { + line += stringify.multiValue( + property.slice(3), multiValue, valueType, null, designSet, false + ); + } else if (structuredValue) { + line += stringify.multiValue( + property[3], structuredValue, valueType, null, designSet, structuredValue + ); + } else { + line += stringify.value(property[3], valueType, designSet, false); + } + + return noFold ? line : foldline(line); +}; + +/** + * Handles escaping of property values that may contain: + * + * COLON (:), SEMICOLON (;), or COMMA (,) + * + * If any of the above are present the result is wrapped + * in double quotes. + * + * @function ICAL.stringify.paramPropertyValue + * @param {String} value Raw property value + * @param {boolean} force If value should be escaped even when unnecessary + * @return {String} Given or escaped value when needed + */ +stringify.paramPropertyValue = function(value, force) { + if (!force && + (value.indexOf(',') === -1) && + (value.indexOf(':') === -1) && + (value.indexOf(';') === -1)) { + + return value; + } + + return '"' + value + '"'; +}; + +/** + * Converts an array of ical values into a single + * string based on a type and a delimiter value (like ","). + * + * @function ICAL.stringify.multiValue + * @param {Array} values List of values to convert + * @param {String} delim Used to join the values (",", ";", ":") + * @param {String} type Lowecase ical value type + * (like boolean, date-time, etc..) + * @param {?String} innerMulti If set, each value will again be processed + * Used for structured values + * @param {designSet} designSet + * The design data to use for this property + * + * @return {String} iCalendar/vCard string for value + */ +stringify.multiValue = function(values, delim, type, innerMulti, designSet, structuredValue) { + let result = ''; + let len = values.length; + let i = 0; + + for (; i < len; i++) { + if (innerMulti && Array.isArray(values[i])) { + result += stringify.multiValue(values[i], innerMulti, type, null, designSet, structuredValue); + } else { + result += stringify.value(values[i], type, designSet, structuredValue); + } + + if (i !== (len - 1)) { + result += delim; + } + } + + return result; +}; + +/** + * Processes a single ical value runs the associated "toICAL" method from the + * design value type if available to convert the value. + * + * @function ICAL.stringify.value + * @param {String|Number} value A formatted value + * @param {String} type Lowercase iCalendar/vCard value type + * (like boolean, date-time, etc..) + * @return {String} iCalendar/vCard value for single value + */ +stringify.value = function(value, type, designSet, structuredValue) { + if (type in designSet.value && 'toICAL' in designSet.value[type]) { + return designSet.value[type].toICAL(value, structuredValue); + } + return value; +}; + +/** + * Internal helper for rfc6868. Exposing this on ICAL.stringify so that + * hackers can disable the rfc6868 parsing if the really need to. + * + * @param {String} val The value to unescape + * @return {String} The escaped value + */ +stringify._rfc6868Unescape = function(val) { + return val.replace(/[\n^"]/g, function(x) { + return RFC6868_REPLACE_MAP[x]; + }); +}; + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + +const NAME_INDEX$1 = 0; +const PROP_INDEX = 1; +const TYPE_INDEX = 2; +const VALUE_INDEX = 3; + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * @ignore + * @typedef {import("./types.js").designSet} designSet + * Imports the 'designSet' type from the "types.js" module + * @typedef {import("./types.js").Geo} Geo + * Imports the 'Geo' type from the "types.js" module + */ + +/** + * Provides a layer on top of the raw jCal object for manipulating a single property, with its + * parameters and value. + * + * @memberof ICAL + */ +class Property { + /** + * Create an {@link ICAL.Property} by parsing the passed iCalendar string. + * + * @param {String} str The iCalendar string to parse + * @param {designSet=} designSet The design data to use for this property + * @return {Property} The created iCalendar property + */ + static fromString(str, designSet) { + return new Property(parse.property(str, designSet)); + } + + /** + * Creates a new ICAL.Property instance. + * + * It is important to note that mutations done in the wrapper directly mutate the jCal object used + * to initialize. + * + * Can also be used to create new properties by passing the name of the property (as a String). + * + * @param {Array|String} jCal Raw jCal representation OR the new name of the property + * @param {Component=} parent Parent component + */ + constructor(jCal, parent) { + this._parent = parent || null; + + if (typeof(jCal) === 'string') { + // We are creating the property by name and need to detect the type + this.jCal = [jCal, {}, design.defaultType]; + this.jCal[TYPE_INDEX] = this.getDefaultType(); + } else { + this.jCal = jCal; + } + this._updateType(); + } + + /** + * The value type for this property + * @type {String} + */ + get type() { + return this.jCal[TYPE_INDEX]; + } + + /** + * The name of this property, in lowercase. + * @type {String} + */ + get name() { + return this.jCal[NAME_INDEX$1]; + } + + /** + * The parent component for this property. + * @type {Component} + */ + get parent() { + return this._parent; + } + + set parent(p) { + // Before setting the parent, check if the design set has changed. If it + // has, we later need to update the type if it was unknown before. + let designSetChanged = !this._parent || (p && p._designSet != this._parent._designSet); + + this._parent = p; + + if (this.type == design.defaultType && designSetChanged) { + this.jCal[TYPE_INDEX] = this.getDefaultType(); + this._updateType(); + } + } + + /** + * The design set for this property, e.g. icalendar vs vcard + * + * @type {designSet} + * @private + */ + get _designSet() { + return this.parent ? this.parent._designSet : design.defaultSet; + } + + /** + * Updates the type metadata from the current jCal type and design set. + * + * @private + */ + _updateType() { + let designSet = this._designSet; + + if (this.type in designSet.value) { + if ('decorate' in designSet.value[this.type]) { + this.isDecorated = true; + } else { + this.isDecorated = false; + } + + if (this.name in designSet.property) { + this.isMultiValue = ('multiValue' in designSet.property[this.name]); + this.isStructuredValue = ('structuredValue' in designSet.property[this.name]); + } + } + } + + /** + * Hydrate a single value. The act of hydrating means turning the raw jCal + * value into a potentially wrapped object, for example {@link ICAL.Time}. + * + * @private + * @param {Number} index The index of the value to hydrate + * @return {?Object} The decorated value. + */ + _hydrateValue(index) { + if (this._values && this._values[index]) { + return this._values[index]; + } + + // for the case where there is no value. + if (this.jCal.length <= (VALUE_INDEX + index)) { + return null; + } + + if (this.isDecorated) { + if (!this._values) { + this._values = []; + } + return (this._values[index] = this._decorate( + this.jCal[VALUE_INDEX + index] + )); + } else { + return this.jCal[VALUE_INDEX + index]; + } + } + + /** + * Decorate a single value, returning its wrapped object. This is used by + * the hydrate function to actually wrap the value. + * + * @private + * @param {?} value The value to decorate + * @return {Object} The decorated value + */ + _decorate(value) { + return this._designSet.value[this.type].decorate(value, this); + } + + /** + * Undecorate a single value, returning its raw jCal data. + * + * @private + * @param {Object} value The value to undecorate + * @return {?} The undecorated value + */ + _undecorate(value) { + return this._designSet.value[this.type].undecorate(value, this); + } + + /** + * Sets the value at the given index while also hydrating it. The passed + * value can either be a decorated or undecorated value. + * + * @private + * @param {?} value The value to set + * @param {Number} index The index to set it at + */ + _setDecoratedValue(value, index) { + if (!this._values) { + this._values = []; + } + + if (typeof(value) === 'object' && 'icaltype' in value) { + // decorated value + this.jCal[VALUE_INDEX + index] = this._undecorate(value); + this._values[index] = value; + } else { + // undecorated value + this.jCal[VALUE_INDEX + index] = value; + this._values[index] = this._decorate(value); + } + } + + /** + * Gets a parameter on the property. + * + * @param {String} name Parameter name (lowercase) + * @return {Array|String} Parameter value + */ + getParameter(name) { + if (name in this.jCal[PROP_INDEX]) { + return this.jCal[PROP_INDEX][name]; + } else { + return undefined; + } + } + + /** + * Gets first parameter on the property. + * + * @param {String} name Parameter name (lowercase) + * @return {String} Parameter value + */ + getFirstParameter(name) { + let parameters = this.getParameter(name); + + if (Array.isArray(parameters)) { + return parameters[0]; + } + + return parameters; + } + + /** + * Sets a parameter on the property. + * + * @param {String} name The parameter name + * @param {Array|String} value The parameter value + */ + setParameter(name, value) { + let lcname = name.toLowerCase(); + if (typeof value === "string" && + lcname in this._designSet.param && + 'multiValue' in this._designSet.param[lcname]) { + value = [value]; + } + this.jCal[PROP_INDEX][name] = value; + } + + /** + * Removes a parameter + * + * @param {String} name The parameter name + */ + removeParameter(name) { + delete this.jCal[PROP_INDEX][name]; + } + + /** + * Get the default type based on this property's name. + * + * @return {String} The default type for this property + */ + getDefaultType() { + let name = this.jCal[NAME_INDEX$1]; + let designSet = this._designSet; + + if (name in designSet.property) { + let details = designSet.property[name]; + if ('defaultType' in details) { + return details.defaultType; + } + } + return design.defaultType; + } + + /** + * Sets type of property and clears out any existing values of the current + * type. + * + * @param {String} type New iCAL type (see design.*.values) + */ + resetType(type) { + this.removeAllValues(); + this.jCal[TYPE_INDEX] = type; + this._updateType(); + } + + /** + * Finds the first property value. + * + * @return {Binary | Duration | Period | + * Recur | Time | UtcOffset | Geo | string | null} First property value + */ + getFirstValue() { + return this._hydrateValue(0); + } + + /** + * Gets all values on the property. + * + * NOTE: this creates an array during each call. + * + * @return {Array} List of values + */ + getValues() { + let len = this.jCal.length - VALUE_INDEX; + + if (len < 1) { + // it is possible for a property to have no value. + return []; + } + + let i = 0; + let result = []; + + for (; i < len; i++) { + result[i] = this._hydrateValue(i); + } + + return result; + } + + /** + * Removes all values from this property + */ + removeAllValues() { + if (this._values) { + this._values.length = 0; + } + this.jCal.length = 3; + } + + /** + * Sets the values of the property. Will overwrite the existing values. + * This can only be used for multi-value properties. + * + * @param {Array} values An array of values + */ + setValues(values) { + if (!this.isMultiValue) { + throw new Error( + this.name + ': does not not support mulitValue.\n' + + 'override isMultiValue' + ); + } + + let len = values.length; + let i = 0; + this.removeAllValues(); + + if (len > 0 && + typeof(values[0]) === 'object' && + 'icaltype' in values[0]) { + this.resetType(values[0].icaltype); + } + + if (this.isDecorated) { + for (; i < len; i++) { + this._setDecoratedValue(values[i], i); + } + } else { + for (; i < len; i++) { + this.jCal[VALUE_INDEX + i] = values[i]; + } + } + } + + /** + * Sets the current value of the property. If this is a multi-value + * property, all other values will be removed. + * + * @param {String|Object} value New property value. + */ + setValue(value) { + this.removeAllValues(); + if (typeof(value) === 'object' && 'icaltype' in value) { + this.resetType(value.icaltype); + } + + if (this.isDecorated) { + this._setDecoratedValue(value, 0); + } else { + this.jCal[VALUE_INDEX] = value; + } + } + + /** + * Returns the Object representation of this component. The returned object + * is a live jCal object and should be cloned if modified. + * @return {Object} + */ + toJSON() { + return this.jCal; + } + + /** + * The string representation of this component. + * @return {String} + */ + toICALString() { + return stringify.property( + this.jCal, this._designSet, true + ); + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * @ignore + * @typedef {import("./types.js").designSet} designSet + * Imports the 'designSet' type from the "types.js" module + * @typedef {import("./types.js").Geo} Geo + * Imports the 'Geo' type from the "types.js" module + */ + +const NAME_INDEX = 0; +const PROPERTY_INDEX = 1; +const COMPONENT_INDEX = 2; + +const PROPERTY_NAME_INDEX = 0; +const PROPERTY_VALUE_INDEX = 3; + +/** + * Wraps a jCal component, adding convenience methods to add, remove and update subcomponents and + * properties. + * + * @memberof ICAL + */ +class Component { + /** + * Create an {@link ICAL.Component} by parsing the passed iCalendar string. + * + * @param {String} str The iCalendar string to parse + */ + static fromString(str) { + return new Component(parse.component(str)); + } + + /** + * Creates a new Component instance. + * + * @param {Array|String} jCal Raw jCal component data OR name of new + * component + * @param {Component=} parent Parent component to associate + */ + constructor(jCal, parent) { + if (typeof(jCal) === 'string') { + // jCal spec (name, properties, components) + jCal = [jCal, [], []]; + } + + // mostly for legacy reasons. + this.jCal = jCal; + + this.parent = parent || null; + + if (!this.parent && this.name === 'vcalendar') { + this._timezoneCache = new Map(); + } + } + + /** + * Hydrated properties are inserted into the _properties array at the same + * position as in the jCal array, so it is possible that the array contains + * undefined values for unhydrdated properties. To avoid iterating the + * array when checking if all properties have been hydrated, we save the + * count here. + * + * @type {Number} + * @private + */ + _hydratedPropertyCount = 0; + + /** + * The same count as for _hydratedPropertyCount, but for subcomponents + * + * @type {Number} + * @private + */ + _hydratedComponentCount = 0; + + /** + * A cache of hydrated time zone objects which may be used by consumers, keyed + * by time zone ID. + * + * @type {Map} + * @private + */ + _timezoneCache = null; + + /** + * @private + */ + _components = null; + + /** + * @private + */ + _properties = null; + + /** + * The name of this component + * + * @type {String} + */ + get name() { + return this.jCal[NAME_INDEX]; + } + + /** + * The design set for this component, e.g. icalendar vs vcard + * + * @type {designSet} + * @private + */ + get _designSet() { + let parentDesign = this.parent && this.parent._designSet; + if (!parentDesign && this.name == "vcard") { + // We can't decide on vcard3 vs vcard4 just based on the component name, the version number is + // in the version property. We also can't use hydrated properties here because it would lead + // to recursion, but the spec says that the version property needs to be the very first one. + let versionProp = this.jCal[PROPERTY_INDEX]?.[0]; + + if (versionProp && versionProp[PROPERTY_NAME_INDEX] == "version" && versionProp[PROPERTY_VALUE_INDEX] == "3.0") { + return design.getDesignSet("vcard3"); + } + } + + return parentDesign || design.getDesignSet(this.name); + } + + /** + * @private + */ + _hydrateComponent(index) { + if (!this._components) { + this._components = []; + this._hydratedComponentCount = 0; + } + + if (this._components[index]) { + return this._components[index]; + } + + let comp = new Component( + this.jCal[COMPONENT_INDEX][index], + this + ); + + this._hydratedComponentCount++; + return (this._components[index] = comp); + } + + /** + * @private + */ + _hydrateProperty(index) { + if (!this._properties) { + this._properties = []; + this._hydratedPropertyCount = 0; + } + + if (this._properties[index]) { + return this._properties[index]; + } + + let prop = new Property( + this.jCal[PROPERTY_INDEX][index], + this + ); + + this._hydratedPropertyCount++; + return (this._properties[index] = prop); + } + + /** + * Finds first sub component, optionally filtered by name. + * + * @param {String=} name Optional name to filter by + * @return {?Component} The found subcomponent + */ + getFirstSubcomponent(name) { + if (name) { + let i = 0; + let comps = this.jCal[COMPONENT_INDEX]; + let len = comps.length; + + for (; i < len; i++) { + if (comps[i][NAME_INDEX] === name) { + let result = this._hydrateComponent(i); + return result; + } + } + } else { + if (this.jCal[COMPONENT_INDEX].length) { + return this._hydrateComponent(0); + } + } + + // ensure we return a value (strict mode) + return null; + } + + /** + * Finds all sub components, optionally filtering by name. + * + * @param {String=} name Optional name to filter by + * @return {Component[]} The found sub components + */ + getAllSubcomponents(name) { + let jCalLen = this.jCal[COMPONENT_INDEX].length; + let i = 0; + + if (name) { + let comps = this.jCal[COMPONENT_INDEX]; + let result = []; + + for (; i < jCalLen; i++) { + if (name === comps[i][NAME_INDEX]) { + result.push( + this._hydrateComponent(i) + ); + } + } + return result; + } else { + if (!this._components || + (this._hydratedComponentCount !== jCalLen)) { + for (; i < jCalLen; i++) { + this._hydrateComponent(i); + } + } + + return this._components || []; + } + } + + /** + * Returns true when a named property exists. + * + * @param {String} name The property name + * @return {Boolean} True, when property is found + */ + hasProperty(name) { + let props = this.jCal[PROPERTY_INDEX]; + let len = props.length; + + let i = 0; + for (; i < len; i++) { + // 0 is property name + if (props[i][NAME_INDEX] === name) { + return true; + } + } + + return false; + } + + /** + * Finds the first property, optionally with the given name. + * + * @param {String=} name Lowercase property name + * @return {?Property} The found property + */ + getFirstProperty(name) { + if (name) { + let i = 0; + let props = this.jCal[PROPERTY_INDEX]; + let len = props.length; + + for (; i < len; i++) { + if (props[i][NAME_INDEX] === name) { + let result = this._hydrateProperty(i); + return result; + } + } + } else { + if (this.jCal[PROPERTY_INDEX].length) { + return this._hydrateProperty(0); + } + } + + return null; + } + + /** + * Returns first property's value, if available. + * + * @param {String=} name Lowercase property name + * @return {Binary | Duration | Period | + * Recur | Time | UtcOffset | Geo | string | null} The found property value. + */ + getFirstPropertyValue(name) { + let prop = this.getFirstProperty(name); + if (prop) { + return prop.getFirstValue(); + } + + return null; + } + + /** + * Get all properties in the component, optionally filtered by name. + * + * @param {String=} name Lowercase property name + * @return {Property[]} List of properties + */ + getAllProperties(name) { + let jCalLen = this.jCal[PROPERTY_INDEX].length; + let i = 0; + + if (name) { + let props = this.jCal[PROPERTY_INDEX]; + let result = []; + + for (; i < jCalLen; i++) { + if (name === props[i][NAME_INDEX]) { + result.push( + this._hydrateProperty(i) + ); + } + } + return result; + } else { + if (!this._properties || + (this._hydratedPropertyCount !== jCalLen)) { + for (; i < jCalLen; i++) { + this._hydrateProperty(i); + } + } + + return this._properties || []; + } + } + + /** + * @private + */ + _removeObjectByIndex(jCalIndex, cache, index) { + cache = cache || []; + // remove cached version + if (cache[index]) { + let obj = cache[index]; + if ("parent" in obj) { + obj.parent = null; + } + } + + cache.splice(index, 1); + + // remove it from the jCal + this.jCal[jCalIndex].splice(index, 1); + } + + /** + * @private + */ + _removeObject(jCalIndex, cache, nameOrObject) { + let i = 0; + let objects = this.jCal[jCalIndex]; + let len = objects.length; + let cached = this[cache]; + + if (typeof(nameOrObject) === 'string') { + for (; i < len; i++) { + if (objects[i][NAME_INDEX] === nameOrObject) { + this._removeObjectByIndex(jCalIndex, cached, i); + return true; + } + } + } else if (cached) { + for (; i < len; i++) { + if (cached[i] && cached[i] === nameOrObject) { + this._removeObjectByIndex(jCalIndex, cached, i); + return true; + } + } + } + + return false; + } + + /** + * @private + */ + _removeAllObjects(jCalIndex, cache, name) { + let cached = this[cache]; + + // Unfortunately we have to run through all children to reset their + // parent property. + let objects = this.jCal[jCalIndex]; + let i = objects.length - 1; + + // descending search required because splice + // is used and will effect the indices. + for (; i >= 0; i--) { + if (!name || objects[i][NAME_INDEX] === name) { + this._removeObjectByIndex(jCalIndex, cached, i); + } + } + } + + /** + * Adds a single sub component. + * + * @param {Component} component The component to add + * @return {Component} The passed in component + */ + addSubcomponent(component) { + if (!this._components) { + this._components = []; + this._hydratedComponentCount = 0; + } + + if (component.parent) { + component.parent.removeSubcomponent(component); + } + + let idx = this.jCal[COMPONENT_INDEX].push(component.jCal); + this._components[idx - 1] = component; + this._hydratedComponentCount++; + component.parent = this; + return component; + } + + /** + * Removes a single component by name or the instance of a specific + * component. + * + * @param {Component|String} nameOrComp Name of component, or component + * @return {Boolean} True when comp is removed + */ + removeSubcomponent(nameOrComp) { + let removed = this._removeObject(COMPONENT_INDEX, '_components', nameOrComp); + if (removed) { + this._hydratedComponentCount--; + } + return removed; + } + + /** + * Removes all components or (if given) all components by a particular + * name. + * + * @param {String=} name Lowercase component name + */ + removeAllSubcomponents(name) { + let removed = this._removeAllObjects(COMPONENT_INDEX, '_components', name); + this._hydratedComponentCount = 0; + return removed; + } + + /** + * Adds an {@link ICAL.Property} to the component. + * + * @param {Property} property The property to add + * @return {Property} The passed in property + */ + addProperty(property) { + if (!(property instanceof Property)) { + throw new TypeError('must be instance of ICAL.Property'); + } + + if (!this._properties) { + this._properties = []; + this._hydratedPropertyCount = 0; + } + + if (property.parent) { + property.parent.removeProperty(property); + } + + let idx = this.jCal[PROPERTY_INDEX].push(property.jCal); + this._properties[idx - 1] = property; + this._hydratedPropertyCount++; + property.parent = this; + return property; + } + + /** + * Helper method to add a property with a value to the component. + * + * @param {String} name Property name to add + * @param {String|Number|Object} value Property value + * @return {Property} The created property + */ + addPropertyWithValue(name, value) { + let prop = new Property(name); + prop.setValue(value); + + this.addProperty(prop); + + return prop; + } + + /** + * Helper method that will update or create a property of the given name + * and sets its value. If multiple properties with the given name exist, + * only the first is updated. + * + * @param {String} name Property name to update + * @param {String|Number|Object} value Property value + * @return {Property} The created property + */ + updatePropertyWithValue(name, value) { + let prop = this.getFirstProperty(name); + + if (prop) { + prop.setValue(value); + } else { + prop = this.addPropertyWithValue(name, value); + } + + return prop; + } + + /** + * Removes a single property by name or the instance of the specific + * property. + * + * @param {String|Property} nameOrProp Property name or instance to remove + * @return {Boolean} True, when deleted + */ + removeProperty(nameOrProp) { + let removed = this._removeObject(PROPERTY_INDEX, '_properties', nameOrProp); + if (removed) { + this._hydratedPropertyCount--; + } + return removed; + } + + /** + * Removes all properties associated with this component, optionally + * filtered by name. + * + * @param {String=} name Lowercase property name + * @return {Boolean} True, when deleted + */ + removeAllProperties(name) { + let removed = this._removeAllObjects(PROPERTY_INDEX, '_properties', name); + this._hydratedPropertyCount = 0; + return removed; + } + + /** + * Returns the Object representation of this component. The returned object + * is a live jCal object and should be cloned if modified. + * @return {Object} + */ + toJSON() { + return this.jCal; + } + + /** + * The string representation of this component. + * @return {String} + */ + toString() { + return stringify.component( + this.jCal, this._designSet + ); + } + + /** + * Retrieve a time zone definition from the component tree, if any is present. + * If the tree contains no time zone definitions or the TZID cannot be + * matched, returns null. + * + * @param {String} tzid The ID of the time zone to retrieve + * @return {Timezone} The time zone corresponding to the ID, or null + */ + getTimeZoneByID(tzid) { + // VTIMEZONE components can only appear as a child of the VCALENDAR + // component; walk the tree if we're not the root. + if (this.parent) { + return this.parent.getTimeZoneByID(tzid); + } + + // If there is no time zone cache, we are probably parsing an incomplete + // file and will have no time zone definitions. + if (!this._timezoneCache) { + return null; + } + + if (this._timezoneCache.has(tzid)) { + return this._timezoneCache.get(tzid); + } + + // If the time zone is not already cached, hydrate it from the + // subcomponents. + const zones = this.getAllSubcomponents('vtimezone'); + for (const zone of zones) { + if (zone.getFirstProperty('tzid').getFirstValue() === tzid) { + const hydratedZone = new Timezone({ + component: zone, + tzid: tzid, + }); + + this._timezoneCache.set(tzid, hydratedZone); + + return hydratedZone; + } + } + + // Per the standard, we should always have a time zone defined in a file + // for any referenced TZID, but don't blow up if the file is invalid. + return null; + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * Primary class for expanding recurring rules. Can take multiple rrules, rdates, exdate(s) and + * iterate (in order) over each next occurrence. + * + * Once initialized this class can also be serialized saved and continue iteration from the last + * point. + * + * NOTE: it is intended that this class is to be used with {@link ICAL.Event} which handles recurrence + * exceptions. + * + * @example + * // assuming event is a parsed ical component + * var event; + * + * var expand = new ICAL.RecurExpansion({ + * component: event, + * dtstart: event.getFirstPropertyValue('dtstart') + * }); + * + * // remember there are infinite rules so it is a good idea to limit the scope of the iterations + * // then resume later on. + * + * // next is always an ICAL.Time or null + * var next; + * + * while (someCondition && (next = expand.next())) { + * // do something with next + * } + * + * // save instance for later + * var json = JSON.stringify(expand); + * + * //... + * + * // NOTE: if the component's properties have changed you will need to rebuild the class and start + * // over. This only works when the component's recurrence info is the same. + * var expand = new ICAL.RecurExpansion(JSON.parse(json)); + * + * @memberof ICAL + */ +class RecurExpansion { + /** + * Creates a new ICAL.RecurExpansion instance. + * + * The options object can be filled with the specified initial values. It can also contain + * additional members, as a result of serializing a previous expansion state, as shown in the + * example. + * + * @param {Object} options + * Recurrence expansion options + * @param {Time} options.dtstart + * Start time of the event + * @param {Component=} options.component + * Component for expansion, required if not resuming. + */ + constructor(options) { + this.ruleDates = []; + this.exDates = []; + this.fromData(options); + } + + /** + * True when iteration is fully completed. + * @type {Boolean} + */ + complete = false; + + /** + * Array of rrule iterators. + * + * @type {RecurIterator[]} + * @private + */ + ruleIterators = null; + + /** + * Array of rdate instances. + * + * @type {Time[]} + * @private + */ + ruleDates = null; + + /** + * Array of exdate instances. + * + * @type {Time[]} + * @private + */ + exDates = null; + + /** + * Current position in ruleDates array. + * @type {Number} + * @private + */ + ruleDateInc = 0; + + /** + * Current position in exDates array + * @type {Number} + * @private + */ + exDateInc = 0; + + /** + * Current negative date. + * + * @type {Time} + * @private + */ + exDate = null; + + /** + * Current additional date. + * + * @type {Time} + * @private + */ + ruleDate = null; + + /** + * Start date of recurring rules. + * + * @type {Time} + */ + dtstart = null; + + /** + * Last expanded time + * + * @type {Time} + */ + last = null; + + /** + * Initialize the recurrence expansion from the data object. The options + * object may also contain additional members, see the + * {@link ICAL.RecurExpansion constructor} for more details. + * + * @param {Object} options + * Recurrence expansion options + * @param {Time} options.dtstart + * Start time of the event + * @param {Component=} options.component + * Component for expansion, required if not resuming. + */ + fromData(options) { + let start = formatClassType(options.dtstart, Time); + + if (!start) { + throw new Error('.dtstart (ICAL.Time) must be given'); + } else { + this.dtstart = start; + } + + if (options.component) { + this._init(options.component); + } else { + this.last = formatClassType(options.last, Time) || start.clone(); + + if (!options.ruleIterators) { + throw new Error('.ruleIterators or .component must be given'); + } + + this.ruleIterators = options.ruleIterators.map(function(item) { + return formatClassType(item, RecurIterator); + }); + + this.ruleDateInc = options.ruleDateInc; + this.exDateInc = options.exDateInc; + + if (options.ruleDates) { + this.ruleDates = options.ruleDates.map(item => formatClassType(item, Time)); + this.ruleDate = this.ruleDates[this.ruleDateInc]; + } + + if (options.exDates) { + this.exDates = options.exDates.map(item => formatClassType(item, Time)); + this.exDate = this.exDates[this.exDateInc]; + } + + if (typeof(options.complete) !== 'undefined') { + this.complete = options.complete; + } + } + } + + /** + * Compare two ICAL.Time objects. When the second parameter is a DATE and the first parameter is + * DATE-TIME, strip the time and compare only the days. + * + * @private + * @param {Time} a The one object to compare + * @param {Time} b The other object to compare + */ + _compare_special(a, b) { + if (!a.isDate && b.isDate) + return new Time({ year: a.year, month: a.month, day: a.day }).compare(b); + return a.compare(b); + } + + /** + * Retrieve the next occurrence in the series. + * @return {Time} + */ + next() { + let iter; + let next; + let compare; + + let maxTries = 500; + let currentTry = 0; + + while (true) { + if (currentTry++ > maxTries) { + throw new Error( + 'max tries have occurred, rule may be impossible to fulfill.' + ); + } + + next = this.ruleDate; + iter = this._nextRecurrenceIter(this.last); + + // no more matches + // because we increment the rule day or rule + // _after_ we choose a value this should be + // the only spot where we need to worry about the + // end of events. + if (!next && !iter) { + // there are no more iterators or rdates + this.complete = true; + break; + } + + // no next rule day or recurrence rule is first. + if (!next || (iter && next.compare(iter.last) > 0)) { + // must be cloned, recur will reuse the time element. + next = iter.last.clone(); + // move to next so we can continue + iter.next(); + } + + // if the ruleDate is still next increment it. + if (this.ruleDate === next) { + this._nextRuleDay(); + } + + this.last = next; + + // check the negative rules + if (this.exDate) { + // EXDATE can be in DATE format, but DTSTART is in DATE-TIME format + compare = this._compare_special(this.last, this.exDate); + + if (compare > 0) { + this._nextExDay(); + } + + // if the current rule is excluded skip it. + if (compare === 0) { + this._nextExDay(); + continue; + } + } + + //XXX: The spec states that after we resolve the final + // list of dates we execute exdate this seems somewhat counter + // intuitive to what I have seen most servers do so for now + // I exclude based on the original date not the one that may + // have been modified by the exception. + return this.last; + } + } + + /** + * Converts object into a serialize-able format. This format can be passed + * back into the expansion to resume iteration. + * @return {Object} + */ + toJSON() { + function toJSON(item) { + return item.toJSON(); + } + + let result = Object.create(null); + result.ruleIterators = this.ruleIterators.map(toJSON); + + if (this.ruleDates) { + result.ruleDates = this.ruleDates.map(toJSON); + } + + if (this.exDates) { + result.exDates = this.exDates.map(toJSON); + } + + result.ruleDateInc = this.ruleDateInc; + result.exDateInc = this.exDateInc; + result.last = this.last.toJSON(); + result.dtstart = this.dtstart.toJSON(); + result.complete = this.complete; + + return result; + } + + /** + * Extract all dates from the properties in the given component. The + * properties will be filtered by the property name. + * + * @private + * @param {Component} component The component to search in + * @param {String} propertyName The property name to search for + * @return {Time[]} The extracted dates. + */ + _extractDates(component, propertyName) { + let result = []; + let props = component.getAllProperties(propertyName); + + for (let i = 0, len = props.length; i < len; i++) { + for (let prop of props[i].getValues()) { + let idx = binsearchInsert( + result, + prop, + (a, b) => a.compare(b) + ); + + // ordered insert + result.splice(idx, 0, prop); + } + } + + return result; + } + + /** + * Initialize the recurrence expansion. + * + * @private + * @param {Component} component The component to initialize from. + */ + _init(component) { + this.ruleIterators = []; + + this.last = this.dtstart.clone(); + + // to provide api consistency non-recurring + // events can also use the iterator though it will + // only return a single time. + if (!component.hasProperty('rdate') && + !component.hasProperty('rrule') && + !component.hasProperty('recurrence-id')) { + this.ruleDate = this.last.clone(); + this.complete = true; + return; + } + + if (component.hasProperty('rdate')) { + this.ruleDates = this._extractDates(component, 'rdate'); + + // special hack for cases where first rdate is prior + // to the start date. We only check for the first rdate. + // This is mostly for google's crazy recurring date logic + // (contacts birthdays). + if ((this.ruleDates[0]) && + (this.ruleDates[0].compare(this.dtstart) < 0)) { + + this.ruleDateInc = 0; + this.last = this.ruleDates[0].clone(); + } else { + this.ruleDateInc = binsearchInsert( + this.ruleDates, + this.last, + (a, b) => a.compare(b) + ); + } + + this.ruleDate = this.ruleDates[this.ruleDateInc]; + } + + if (component.hasProperty('rrule')) { + let rules = component.getAllProperties('rrule'); + let i = 0; + let len = rules.length; + + let rule; + let iter; + + for (; i < len; i++) { + rule = rules[i].getFirstValue(); + iter = rule.iterator(this.dtstart); + this.ruleIterators.push(iter); + + // increment to the next occurrence so future + // calls to next return times beyond the initial iteration. + // XXX: I find this suspicious might be a bug? + iter.next(); + } + } + + if (component.hasProperty('exdate')) { + this.exDates = this._extractDates(component, 'exdate'); + // if we have a .last day we increment the index to beyond it. + // When DTSTART is in DATE-TIME format, EXDATE is in DATE format and EXDATE is + // the date of DTSTART, _compare_special finds this out and compareTime fails. + this.exDateInc = binsearchInsert( + this.exDates, + this.last, + this._compare_special + ); + + this.exDate = this.exDates[this.exDateInc]; + } + } + + /** + * Advance to the next exdate + * @private + */ + _nextExDay() { + this.exDate = this.exDates[++this.exDateInc]; + } + + /** + * Advance to the next rule date + * @private + */ + _nextRuleDay() { + this.ruleDate = this.ruleDates[++this.ruleDateInc]; + } + + /** + * Find and return the recurrence rule with the most recent event and + * return it. + * + * @private + * @return {?RecurIterator} Found iterator. + */ + _nextRecurrenceIter() { + let iters = this.ruleIterators; + + if (iters.length === 0) { + return null; + } + + let len = iters.length; + let iter; + let iterTime; + let iterIdx = 0; + let chosenIter; + + // loop through each iterator + for (; iterIdx < len; iterIdx++) { + iter = iters[iterIdx]; + iterTime = iter.last; + + // if iteration is complete + // then we must exclude it from + // the search and remove it. + if (iter.completed) { + len--; + if (iterIdx !== 0) { + iterIdx--; + } + iters.splice(iterIdx, 1); + continue; + } + + // find the most recent possible choice + if (!chosenIter || chosenIter.last.compare(iterTime) > 0) { + // that iterator is saved + chosenIter = iter; + } + } + + // the chosen iterator is returned but not mutated + // this iterator contains the most recent event. + return chosenIter; + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * This lets typescript resolve our custom types in the + * generated d.ts files (jsdoc typedefs are converted to typescript types). + * Ignore prevents the typedefs from being documented more than once. + * @ignore + * @typedef {import("./types.js").frequencyValues} frequencyValues + * Imports the 'frequencyValues' type from the "types.js" module + * @typedef {import("./types.js").occurrenceDetails} occurrenceDetails + * Imports the 'occurrenceDetails' type from the "types.js" module + */ + +/** + * ICAL.js is organized into multiple layers. The bottom layer is a raw jCal + * object, followed by the component/property layer. The highest level is the + * event representation, which this class is part of. See the + * {@tutorial layers} guide for more details. + * + * @memberof ICAL + */ +class Event { + /** + * Creates a new ICAL.Event instance. + * + * @param {Component=} component The ICAL.Component to base this event on + * @param {Object} [options] Options for this event + * @param {Boolean=} options.strictExceptions When true, will verify exceptions are related by + * their UUID + * @param {Array=} options.exceptions + * Exceptions to this event, either as components or events. If not + * specified exceptions will automatically be set in relation of + * component's parent + */ + constructor(component, options) { + if (!(component instanceof Component)) { + options = component; + component = null; + } + + if (component) { + this.component = component; + } else { + this.component = new Component('vevent'); + } + + this._rangeExceptionCache = Object.create(null); + this.exceptions = Object.create(null); + this.rangeExceptions = []; + + if (options && options.strictExceptions) { + this.strictExceptions = options.strictExceptions; + } + + if (options && options.exceptions) { + options.exceptions.forEach(this.relateException, this); + } else if (this.component.parent && !this.isRecurrenceException()) { + this.component.parent.getAllSubcomponents('vevent').forEach(function(event) { + if (event.hasProperty('recurrence-id')) { + this.relateException(event); + } + }, this); + } + } + + + static THISANDFUTURE = 'THISANDFUTURE'; + + /** + * List of related event exceptions. + * + * @type {Event[]} + */ + exceptions = null; + + /** + * When true, will verify exceptions are related by their UUID. + * + * @type {Boolean} + */ + strictExceptions = false; + + /** + * Relates a given event exception to this object. If the given component + * does not share the UID of this event it cannot be related and will throw + * an exception. + * + * If this component is an exception it cannot have other exceptions + * related to it. + * + * @param {Component|Event} obj Component or event + */ + relateException(obj) { + if (this.isRecurrenceException()) { + throw new Error('cannot relate exception to exceptions'); + } + + if (obj instanceof Component) { + obj = new Event(obj); + } + + if (this.strictExceptions && obj.uid !== this.uid) { + throw new Error('attempted to relate unrelated exception'); + } + + let id = obj.recurrenceId.toString(); + + // we don't sort or manage exceptions directly + // here the recurrence expander handles that. + this.exceptions[id] = obj; + + // index RANGE=THISANDFUTURE exceptions so we can + // look them up later in getOccurrenceDetails. + if (obj.modifiesFuture()) { + let item = [ + obj.recurrenceId.toUnixTime(), id + ]; + + // we keep them sorted so we can find the nearest + // value later on... + let idx = binsearchInsert( + this.rangeExceptions, + item, + compareRangeException + ); + + this.rangeExceptions.splice(idx, 0, item); + } + } + + /** + * Checks if this record is an exception and has the RANGE=THISANDFUTURE + * value. + * + * @return {Boolean} True, when exception is within range + */ + modifiesFuture() { + if (!this.component.hasProperty('recurrence-id')) { + return false; + } + + let range = this.component.getFirstProperty('recurrence-id').getParameter('range'); + return range === Event.THISANDFUTURE; + } + + /** + * Finds the range exception nearest to the given date. + * + * @param {Time} time usually an occurrence time of an event + * @return {?Event} the related event/exception or null + */ + findRangeException(time) { + if (!this.rangeExceptions.length) { + return null; + } + + let utc = time.toUnixTime(); + let idx = binsearchInsert( + this.rangeExceptions, + [utc], + compareRangeException + ); + + idx -= 1; + + // occurs before + if (idx < 0) { + return null; + } + + let rangeItem = this.rangeExceptions[idx]; + + /* c8 ignore next 4 */ + if (utc < rangeItem[0]) { + // sanity check only + return null; + } + + return rangeItem[1]; + } + + /** + * Returns the occurrence details based on its start time. If the + * occurrence has an exception will return the details for that exception. + * + * NOTE: this method is intend to be used in conjunction + * with the {@link ICAL.Event#iterator iterator} method. + * + * @param {Time} occurrence time occurrence + * @return {occurrenceDetails} Information about the occurrence + */ + getOccurrenceDetails(occurrence) { + let id = occurrence.toString(); + let utcId = occurrence.convertToZone(Timezone.utcTimezone).toString(); + let item; + let result = { + //XXX: Clone? + recurrenceId: occurrence + }; + + if (id in this.exceptions) { + item = result.item = this.exceptions[id]; + result.startDate = item.startDate; + result.endDate = item.endDate; + result.item = item; + } else if (utcId in this.exceptions) { + item = this.exceptions[utcId]; + result.startDate = item.startDate; + result.endDate = item.endDate; + result.item = item; + } else { + // range exceptions (RANGE=THISANDFUTURE) have a + // lower priority then direct exceptions but + // must be accounted for first. Their item is + // always the first exception with the range prop. + let rangeExceptionId = this.findRangeException( + occurrence + ); + let end; + + if (rangeExceptionId) { + let exception = this.exceptions[rangeExceptionId]; + + // range exception must modify standard time + // by the difference (if any) in start/end times. + result.item = exception; + + let startDiff = this._rangeExceptionCache[rangeExceptionId]; + + if (!startDiff) { + let original = exception.recurrenceId.clone(); + let newStart = exception.startDate.clone(); + + // zones must be same otherwise subtract may be incorrect. + original.zone = newStart.zone; + startDiff = newStart.subtractDate(original); + + this._rangeExceptionCache[rangeExceptionId] = startDiff; + } + + let start = occurrence.clone(); + start.zone = exception.startDate.zone; + start.addDuration(startDiff); + + end = start.clone(); + end.addDuration(exception.duration); + + result.startDate = start; + result.endDate = end; + } else { + // no range exception standard expansion + end = occurrence.clone(); + end.addDuration(this.duration); + + result.endDate = end; + result.startDate = occurrence; + result.item = this; + } + } + + return result; + } + + /** + * Builds a recur expansion instance for a specific point in time (defaults + * to startDate). + * + * @param {Time=} startTime Starting point for expansion + * @return {RecurExpansion} Expansion object + */ + iterator(startTime) { + return new RecurExpansion({ + component: this.component, + dtstart: startTime || this.startDate + }); + } + + /** + * Checks if the event is recurring + * + * @return {Boolean} True, if event is recurring + */ + isRecurring() { + let comp = this.component; + return comp.hasProperty('rrule') || comp.hasProperty('rdate'); + } + + /** + * Checks if the event describes a recurrence exception. See + * {@tutorial terminology} for details. + * + * @return {Boolean} True, if the event describes a recurrence exception + */ + isRecurrenceException() { + return this.component.hasProperty('recurrence-id'); + } + + /** + * Returns the types of recurrences this event may have. + * + * Returned as an object with the following possible keys: + * + * - YEARLY + * - MONTHLY + * - WEEKLY + * - DAILY + * - MINUTELY + * - SECONDLY + * + * @return {Object.} + * Object of recurrence flags + */ + getRecurrenceTypes() { + let rules = this.component.getAllProperties('rrule'); + let i = 0; + let len = rules.length; + let result = Object.create(null); + + for (; i < len; i++) { + let value = rules[i].getFirstValue(); + result[value.freq] = true; + } + + return result; + } + + /** + * The uid of this event + * @type {String} + */ + get uid() { + return this._firstProp('uid'); + } + + set uid(value) { + this._setProp('uid', value); + } + + /** + * The start date + * @type {Time} + */ + get startDate() { + return this._firstProp('dtstart'); + } + + set startDate(value) { + this._setTime('dtstart', value); + } + + /** + * The end date. This can be the result directly from the property, or the + * end date calculated from start date and duration. Setting the property + * will remove any duration properties. + * @type {Time} + */ + get endDate() { + let endDate = this._firstProp('dtend'); + if (!endDate) { + let duration = this._firstProp('duration'); + endDate = this.startDate.clone(); + if (duration) { + endDate.addDuration(duration); + } else if (endDate.isDate) { + endDate.day += 1; + } + } + return endDate; + } + + set endDate(value) { + if (this.component.hasProperty('duration')) { + this.component.removeProperty('duration'); + } + this._setTime('dtend', value); + } + + /** + * The duration. This can be the result directly from the property, or the + * duration calculated from start date and end date. Setting the property + * will remove any `dtend` properties. + * @type {Duration} + */ + get duration() { + let duration = this._firstProp('duration'); + if (!duration) { + return this.endDate.subtractDateTz(this.startDate); + } + return duration; + } + + set duration(value) { + if (this.component.hasProperty('dtend')) { + this.component.removeProperty('dtend'); + } + + this._setProp('duration', value); + } + + /** + * The location of the event. + * @type {String} + */ + get location() { + return this._firstProp('location'); + } + + set location(value) { + this._setProp('location', value); + } + + /** + * The attendees in the event + * @type {Property[]} + */ + get attendees() { + //XXX: This is way lame we should have a better + // data structure for this later. + return this.component.getAllProperties('attendee'); + } + + /** + * The event summary + * @type {String} + */ + get summary() { + return this._firstProp('summary'); + } + + set summary(value) { + this._setProp('summary', value); + } + + /** + * The event description. + * @type {String} + */ + get description() { + return this._firstProp('description'); + } + + set description(value) { + this._setProp('description', value); + } + + /** + * The event color from [rfc7986](https://datatracker.ietf.org/doc/html/rfc7986) + * @type {String} + */ + get color() { + return this._firstProp('color'); + } + + set color(value) { + this._setProp('color', value); + } + + /** + * The organizer value as an uri. In most cases this is a mailto: uri, but + * it can also be something else, like urn:uuid:... + * @type {String} + */ + get organizer() { + return this._firstProp('organizer'); + } + + set organizer(value) { + this._setProp('organizer', value); + } + + /** + * The sequence value for this event. Used for scheduling + * see {@tutorial terminology}. + * @type {Number} + */ + get sequence() { + return this._firstProp('sequence'); + } + + set sequence(value) { + this._setProp('sequence', value); + } + + /** + * The recurrence id for this event. See {@tutorial terminology} for details. + * @type {Time} + */ + get recurrenceId() { + return this._firstProp('recurrence-id'); + } + + set recurrenceId(value) { + this._setTime('recurrence-id', value); + } + + /** + * Set/update a time property's value. + * This will also update the TZID of the property. + * + * TODO: this method handles the case where we are switching + * from a known timezone to an implied timezone (one without TZID). + * This does _not_ handle the case of moving between a known + * (by TimezoneService) timezone to an unknown timezone... + * + * We will not add/remove/update the VTIMEZONE subcomponents + * leading to invalid ICAL data... + * @private + * @param {String} propName The property name + * @param {Time} time The time to set + */ + _setTime(propName, time) { + let prop = this.component.getFirstProperty(propName); + + if (!prop) { + prop = new Property(propName); + this.component.addProperty(prop); + } + + // utc and local don't get a tzid + if ( + time.zone === Timezone.localTimezone || + time.zone === Timezone.utcTimezone + ) { + // remove the tzid + prop.removeParameter('tzid'); + } else { + prop.setParameter('tzid', time.zone.tzid); + } + + prop.setValue(time); + } + + _setProp(name, value) { + this.component.updatePropertyWithValue(name, value); + } + + _firstProp(name) { + return this.component.getFirstPropertyValue(name); + } + + /** + * The string representation of this event. + * @return {String} + */ + toString() { + return this.component.toString(); + } +} + +function compareRangeException(a, b) { + if (a[0] > b[0]) return 1; + if (b[0] > a[0]) return -1; + return 0; +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * The ComponentParser is used to process a String or jCal Object, + * firing callbacks for various found components, as well as completion. + * + * @example + * var options = { + * // when false no events will be emitted for type + * parseEvent: true, + * parseTimezone: true + * }; + * + * var parser = new ICAL.ComponentParser(options); + * + * parser.onevent(eventComponent) { + * //... + * } + * + * // ontimezone, etc... + * + * parser.oncomplete = function() { + * + * }; + * + * parser.process(stringOrComponent); + * + * @memberof ICAL + */ +class ComponentParser { + /** + * Creates a new ICAL.ComponentParser instance. + * + * @param {Object=} options Component parser options + * @param {Boolean} options.parseEvent Whether events should be parsed + * @param {Boolean} options.parseTimezeone Whether timezones should be parsed + */ + constructor(options) { + if (typeof(options) === 'undefined') { + options = {}; + } + + for (let [key, value] of Object.entries(options)) { + this[key] = value; + } + } + + /** + * When true, parse events + * + * @type {Boolean} + */ + parseEvent = true; + + /** + * When true, parse timezones + * + * @type {Boolean} + */ + parseTimezone = true; + + + /* SAX like events here for reference */ + + /** + * Fired when parsing is complete + * @callback + */ + oncomplete = /* c8 ignore next */ function() {}; + + /** + * Fired if an error occurs during parsing. + * + * @callback + * @param {Error} err details of error + */ + onerror = /* c8 ignore next */ function(err) {}; + + /** + * Fired when a top level component (VTIMEZONE) is found + * + * @callback + * @param {Timezone} component Timezone object + */ + ontimezone = /* c8 ignore next */ function(component) {}; + + /** + * Fired when a top level component (VEVENT) is found. + * + * @callback + * @param {Event} component Top level component + */ + onevent = /* c8 ignore next */ function(component) {}; + + /** + * Process a string or parse ical object. This function itself will return + * nothing but will start the parsing process. + * + * Events must be registered prior to calling this method. + * + * @param {Component|String|Object} ical The component to process, + * either in its final form, as a jCal Object, or string representation + */ + process(ical) { + //TODO: this is sync now in the future we will have a incremental parser. + if (typeof(ical) === 'string') { + ical = parse(ical); + } + + if (!(ical instanceof Component)) { + ical = new Component(ical); + } + + let components = ical.getAllSubcomponents(); + let i = 0; + let len = components.length; + let component; + + for (; i < len; i++) { + component = components[i]; + + switch (component.name) { + case 'vtimezone': + if (this.parseTimezone) { + let tzid = component.getFirstPropertyValue('tzid'); + if (tzid) { + this.ontimezone(new Timezone({ + tzid: tzid, + component: component + })); + } + } + break; + case 'vevent': + if (this.parseEvent) { + this.onevent(new Event(component)); + } + break; + default: + continue; + } + } + + //XXX: ideally we should do a "nextTick" here + // so in all cases this is actually async. + this.oncomplete(); + } +} + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * Portions Copyright (C) Philipp Kewisch */ + + +/** + * The main ICAL module. Provides access to everything else. + * + * @alias ICAL + * @namespace ICAL + * @property {ICAL.design} design + * @property {ICAL.helpers} helpers + */ +var ICALmodule = { + /** + * The number of characters before iCalendar line folding should occur + * @type {Number} + * @default 75 + */ + foldLength: 75, + + debug: false, + + /** + * The character(s) to be used for a newline. The default value is provided by + * rfc5545. + * @type {String} + * @default "\r\n" + */ + newLineChar: '\r\n', + + Binary, + Component, + ComponentParser, + Duration, + Event, + Period, + Property, + Recur, + RecurExpansion, + RecurIterator, + Time, + Timezone, + TimezoneService, + UtcOffset, + VCardTime, + + parse, + stringify, + + design, + helpers +}; + +export { ICALmodule as default }; diff --git a/content/_index.md b/content/_index.md index 4d73f01..cb897dc 100644 --- a/content/_index.md +++ b/content/_index.md @@ -25,9 +25,6 @@ description: "Startseite CCCB mit Kurzkalender" ### Nächste Veranstaltungen - -
+{{< upcoming >}} Weitere Termine findest du im [Veranstaltungskalender](/verein/calendar/). - - diff --git a/layouts/shortcodes/upcoming.html b/layouts/shortcodes/upcoming.html new file mode 100644 index 0000000..18173b3 --- /dev/null +++ b/layouts/shortcodes/upcoming.html @@ -0,0 +1,3 @@ +{{- $js := resources.Get "js/upcoming.js" | js.Build (dict "minify" true "format" "esm" "target" "es2020") | fingerprint -}} +
+ From 60ab62827033640c25b98c8dc1e15c6d925d3331 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 20:10:25 +0200 Subject: [PATCH 10/18] Parse the calendar with ical.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The calendar page brought its own ICS parser and its own RRULE expansion. Both only covered the cases that happened to be needed when they were written, and the calendar has moved on since. Against the published calendar, for September 2026: Spieleabend FREQ=WEEKLY;INTERVAL=2;BYDAY=SA shown 05. 12. 19. 26., correct 05. 19. CCCB Plenum FREQ=MONTHLY;BYDAY=TU;BYSETPOS=2 shown 01., correct 08. CCCB Plenum FREQ=MONTHLY;BYDAY=TU;BYSETPOS=4 shown 01., correct 22. INTERVAL was only read for monthly rules, so the Spieleabend was shown twice as often as it takes place. BYSETPOS was not implemented at all, and since parseInt("TU") is NaN the fallback turned both Plenum rules into "first Tuesday", putting two Plenums on a day without one and none on the two days with one. UNTIL, COUNT, EXDATE, RECURRENCE-ID, BYMONTHDAY and a BYDAY listing more than one weekday were not handled either. The text was no better. Content lines longer than 75 characters are continued on the next line, of which there are 477 in the calendar, and the parser did not join them, so it cut values off in the middle of a word. It also split every line at the first colon, which lands inside the parameter of DESCRIPTION;ALTREP="data:text/html,...". And it never resolved the escaping, so "\n" was shown as those two characters. 30 of 31 descriptions were wrong: before: "Der Club Discordia ist ein öffentliches Treffen in den Clubr" after: "Der Club Discordia ist ein öffentliches Treffen in den Clubräumen des CCC Berlin" Hand the parsing and the expansion to ical.js, which is vendored for the start page anyway. The month view now asks the library for the occurrences that touch the month, which removes the reimplementation along with all of the above. While the events are being reduced to what the view needs: - An event is entered on every day it covers, so the Amateurfunk trip from 30.10. to 01.11. is no longer marked on 30.10. alone. The end of an event is not part of it, so one ending at midnight stays on the day before. - A time that names a zone is converted to Europe/Berlin instead of being read off the digits of the ICS string. Every event currently carries TZID=Europe/Berlin, so the wall clock time shown does not change, but a UTC timestamp would have been shown in UTC. A date is a different matter, see further down. - The URL of the event is used for the link in the detail panel. Events without one are shown without a link, as on the start page. This replaces createEventLink(), which guessed URLs from the title and was never called, and the panel no longer builds an element, which is not an element. Descriptions may contain line breaks, so keep them in the panel. The times of an event are labelled in German like the rest of the page, "Beginn" and "Ende" instead of "Start" and "End". An all day event carries a date, and a date has neither a time nor a zone: its digits are the day itself. `toJSDate()` reads them as midnight in the zone of the browser, and deriving the Berlin day from that afterwards moves the event by the offset between the two, so the promise of the same days everywhere would have held for every event except the ones that consist of nothing but days. An event on 30. and 31.08. would have been marked on: Berlin 30. 31.08. Los Angeles 30. 31.08. 01.09. Tokio 29. 30. 31.08. Take the day from the ICAL time, which still knows whether it names a day or a point in time, and convert only the latter. Stepping to the end of the event moves by a day where it is made of days and by a second where it is not, which also expresses "the end is not part of the event" in the terms of the event itself. The occurrences of a day are sorted by their start, which for an all day event is that same midnight, so order them before the timed events instead. Resolving an occurrence that was modified on its own needs two more things to be right. Unless it is told which modifications belong to an event, `ICAL.Event` relates every VEVENT with a RECURRENCE-ID in the file to every recurring event and keys them by the recurrence id alone; the UID is only compared with `strictExceptions`, which then throws instead of skipping. A modification would therefore also override the occurrence another series holds at the same instant, so the detail panel of that day would show the wrong event and the modified one twice. Group the modifications by the UID of the event they belong to and hand each event its own. And the expansion walks the unmodified recurrence times, so an occurrence pulled forward into the month from a later one would never be reached: the walk stops at its original time, and the month it was moved out of drops it because it no longer falls into it, which loses it from the calendar altogether. Iterate far enough that the largest move towards the past can still reach the month. Moving a Plenum or a Club Discordia to the week before, out of the way of a holiday, is exactly what produces such a modification. With a weekly series whose occurrence of 07.09. is moved to 28.08.: before: August 03. 10. 17. 24. 31. September 14. 21. 28. after: August 03. 10. 17. 24. 28. 31. September 14. 21. 28. The URL ends up in the href of a link and the calendar is exported from a CalDAV server, so whoever may write to it decides what that is; `URL:javascript:alert(1)` on an event would run that script when a visitor clicks the name. Pass on nothing but http and https. The stylesheet of the page goes through `minify | fingerprint` while the script next to it is rewritten, so both are delivered the way the assets of the start page already are: smaller, under a name that carries their content hash, and with an integrity hash in the tag. The published calendar has neither all day events nor RECURRENCE-ID today, both can be created in the CalDAV calendar the export comes from. Checked in Berlin, Tokyo, Los Angeles and Kiritimati: an all day event over 30. and 31.08. is marked on those two days in all four, one from 31.08. to 02.09. is marked across the month boundary, and the month view of the published calendar is the same in all of them. Fixes: 4068fab565ef ("improved calendar and fixed url temporarily") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- assets/css/calendar.css | 4 + assets/js/calendar.js | 978 +++++++++++++++++-------------- layouts/shortcodes/calendar.html | 8 +- 3 files changed, 547 insertions(+), 443 deletions(-) diff --git a/assets/css/calendar.css b/assets/css/calendar.css index 2806966..5bec886 100644 --- a/assets/css/calendar.css +++ b/assets/css/calendar.css @@ -107,6 +107,10 @@ font-size: 0.9em; margin-bottom: 5px; } + .event-description { + /* Descriptions carry their own line breaks, keep them. */ + white-space: pre-line; + } .no-events { font-style: italic; color: var(--color-text-secondary); diff --git a/assets/js/calendar.js b/assets/js/calendar.js index 18b4768..596eca0 100644 --- a/assets/js/calendar.js +++ b/assets/js/calendar.js @@ -1,449 +1,549 @@ -document.addEventListener('DOMContentLoaded', function() { - (function(){ - let events = []; - let eventsByDate = {}; +import ICAL from "./vendor/ical.js"; - // Funktion zum Parsen der ICS-Datei - function parseICS(icsText) { - let events = []; - let lines = icsText.split(/\r?\n/); - let event = null; - lines.forEach(line => { - if (line.startsWith("BEGIN:VEVENT")) { - event = {}; - } else if (line.startsWith("END:VEVENT")) { - if (event) events.push(event); - event = null; - } else if (event) { - let colonIndex = line.indexOf(":"); - if (colonIndex > -1) { - let key = line.substring(0, colonIndex); - let value = line.substring(colonIndex + 1); +const icsUrl = "/calendars/all.ics"; - // Handle properties with parameters (like TZID) - const baseKey = key.split(";")[0]; +// The club is in Berlin, so the calendar shows Berlin days and Berlin times, +// no matter which time zone the browser of the visitor is set to. +const timeZone = "Europe/Berlin"; - if (baseKey === "DTSTART") { - event.start = value; - event.startParams = key.includes(";") ? key.substring(key.indexOf(";") + 1) : null; - } else if (baseKey === "DTEND") { - event.end = value; - event.endParams = key.includes(";") ? key.substring(key.indexOf(";") + 1) : null; - } else if (baseKey === "SUMMARY") { - event.summary = value; - } else if (baseKey === "DESCRIPTION") { - event.description = value; - } else if (baseKey === "RRULE") { - event.rrule = value; - } - } - } - }); - return events; - } +const monthNames = [ + "Januar", "Februar", "März", "April", "Mai", "Juni", + "Juli", "August", "September", "Oktober", "November", "Dezember", +]; - // Hilfsfunktion: Parst einen ICS-Datum-String ins Format "YYYY-MM-DD" - function parseDateString(icsDateStr) { - // Handle different date formats - if (!icsDateStr) return null; - - // For basic date format: YYYYMMDD - if (icsDateStr.length === 8) { - let year = icsDateStr.substring(0, 4); - let month = icsDateStr.substring(4, 6); - let day = icsDateStr.substring(6, 8); - return `${year}-${month}-${day}`; - } - // For datetime formats: YYYYMMDDTHHmmssZ or YYYYMMDDTHHmmss - else if (icsDateStr.includes("T")) { - let year = icsDateStr.substring(0, 4); - let month = icsDateStr.substring(4, 6); - let day = icsDateStr.substring(6, 8); - return `${year}-${month}-${day}`; - } - return null; +const dayKeyFormat = new Intl.DateTimeFormat("en-US", { + timeZone, + year: "numeric", + month: "2-digit", + day: "2-digit", +}); + +const timeOfDayFormat = new Intl.DateTimeFormat("de-DE", { + timeZone, + hour: "2-digit", + minute: "2-digit", +}); + +let calendar = null; +let eventsByDate = {}; +let currentYear; +let currentMonth; + +let currentMonthElem; +let calendarBody; +let eventPanel; +let eventDateElem; +let eventDetailsElem; + +/** + * The day a point in time falls on in Berlin. + * + * @param {Date} date The point in time + * @returns {string} The day as "YYYY-MM-DD" + */ +function dayKey(date) { + const parts = {}; + + for (const part of dayKeyFormat.formatToParts(date)) { + parts[part.type] = part.value; + } + + return `${parts.year}-${parts.month}-${parts.day}`; +} + +/** + * The day an occurrence time falls on in Berlin. + * + * A date has neither a time nor a zone, its digits are the day itself. + * toJSDate() would read them as midnight in the zone of the browser, which + * far enough east or west of Berlin lands on the day before or after. + * + * @param {ICAL.Time} time The time + * @returns {string} The day as "YYYY-MM-DD" + */ +function timeDayKey(time) { + if (time.isDate) { + const month = String(time.month).padStart(2, "0"); + const day = String(time.day).padStart(2, "0"); + + return `${time.year}-${month}-${day}`; + } + + return dayKey(time.toJSDate()); +} + +/** + * The days an event covers, so that an event running over several days is + * shown on each of them and not only on the day it starts. + * + * @param {ICAL.Time} start Start of the event + * @param {ICAL.Time} end End of the event + * @returns {string[]} The days as "YYYY-MM-DD" + */ +function daysCovered(start, end) { + // The end is not part of the event: one ending at midnight belongs to the day + // before, and an all day event ends on the day before its DTEND. + const last = end.clone(); + + if (end.isDate) { + last.adjust(-1, 0, 0, 0); + } else { + last.adjust(0, 0, 0, -1); + } + + const lastKey = timeDayKey(last); + const days = []; + + let key = timeDayKey(start); + + // The guard keeps a broken event from looping forever, a year of dots on the + // same event is well past the point where the calendar is still useful. + while (days.length <= 366) { + days.push(key); + + // The keys sort as the days do, so this also stops an event whose end lies + // before its start after the day it starts on. + if (key >= lastKey) { + break; + } + + // Step to noon UTC of the next day, which is inside the same Berlin day + // whether daylight saving time is in effect or not. + const [year, month, day] = key.split("-").map(Number); + key = dayKey(new Date(Date.UTC(year, month - 1, day + 1, 12))); + } + + return days; +} + +/** + * Read the URL of an event. + * + * ICAL.Event does not expose the URL property, so read it from the component. + * + * The value ends up in the href of a link, and the calendar is exported from a + * CalDAV server, so whoever may write to it decides what that value is. A + * "javascript:" URL there would run on our page as soon as a visitor clicks + * the event, so hand on nothing but http and https. + * + * @param {ICAL.Event} event The event to read the URL of + * @returns {string} The URL, empty when the event has none or it is not http(s) + */ +function eventUrl(event) { + const url = event.component.getFirstPropertyValue("url") ?? ""; + + if (!url) { + return ""; + } + + try { + // A relative URL is resolved against the page and keeps its scheme. + const { protocol } = new URL(url, document.baseURI); + + return protocol === "http:" || protocol === "https:" ? url : ""; + } catch { + // Not a URL at all. + return ""; + } +} + +/** + * Reduce one occurrence of an event to what the calendar displays. + * + * @param {ICAL.Event} event The event the occurrence belongs to + * @param {ICAL.Time} startDate Start of this occurrence + * @param {ICAL.Time} endDate End of this occurrence + * @returns {{summary: string, description: string, url: string, start: Date, end: Date, allDay: boolean, days: string[]}} + */ +function toOccurrence(event, startDate, endDate) { + return { + summary: event.summary ?? "", + description: event.description ?? "", + url: eventUrl(event), + start: startDate.toJSDate(), + end: endDate.toJSDate(), + allDay: startDate.isDate, + // Taken from the ICAL times, which still know whether they name a day or a + // point in time; the JS dates above no longer do. + days: daysCovered(startDate, endDate), + }; +} + +/** + * Group the occurrences that were modified on their own by the UID of the event + * they belong to. + * + * Unless it is told which exceptions belong to an event, ICAL.Event relates + * every VEVENT with a RECURRENCE-ID in the file to every recurring event, and + * it keys them by the recurrence id alone. Two series that meet at the same + * time would therefore take over each other's modifications. + * + * @param {ICAL.Component[]} components The VEVENTs of the calendar + * @returns {Map} The exceptions per UID + */ +function exceptionsByUid(components) { + const exceptions = new Map(); + + for (const component of components) { + if (!component.hasProperty("recurrence-id")) { + continue; + } + + const uid = component.getFirstPropertyValue("uid"); + const ofEvent = exceptions.get(uid); + + if (ofEvent) { + ofEvent.push(component); + } else { + exceptions.set(uid, [component]); + } + } + + return exceptions; +} + +/** + * How far the recurrences of an event have to be iterated. + * + * The iteration walks the unmodified recurrence times, so an occurrence that + * was moved to an earlier time is only reached through the time it originally + * had, which can lie past the end of the month. Keep going for as long as the + * largest move towards the past can still carry an occurrence into it. + * + * @param {ICAL.Event} event The event whose recurrences are iterated + * @param {Date} to End of the window + * @returns {Date} The recurrence time to stop at + */ +function iterationEnd(event, to) { + let last = to.getTime(); + + for (const exception of Object.values(event.exceptions)) { + const movedBy = exception.recurrenceId.toJSDate().getTime() + - exception.startDate.toJSDate().getTime(); + + if (movedBy > 0) { + last = Math.max(last, to.getTime() + movedBy); + } + } + + return new Date(last); +} + +/** + * Collect everything that takes place in the given month, keyed by day. + * + * @param {number} year The year of the month + * @param {number} month The month, January is 0 + * @returns {Object} The occurrences per "YYYY-MM-DD" + */ +function occurrencesOfMonth(year, month) { + const byDate = {}; + + if (!calendar) { + return byDate; + } + + // These bounds only limit how far the recurrences have to be expanded, which + // day an occurrence ends up on is decided by its Berlin day below. They are + // deliberately generous so that no occurrence is cut off at the edge of the + // month by a time zone difference. + const from = new Date(year, month, 1); + const to = new Date(year, month + 1, 1); + from.setDate(from.getDate() - 2); + to.setDate(to.getDate() + 2); + + const monthPrefix = `${year}-${String(month + 1).padStart(2, "0")}-`; + + const add = (occurrence) => { + for (const key of occurrence.days) { + if (!key.startsWith(monthPrefix)) { + continue; + } + + if (!byDate[key]) { + byDate[key] = []; + } + + byDate[key].push(occurrence); + } + }; + + const components = calendar.getAllSubcomponents("vevent"); + const exceptions = exceptionsByUid(components); + + for (const component of components) { + // Occurrences modified via RECURRENCE-ID are reached through the event they + // belong to, handling them here as well would show them twice. + if (component.hasProperty("recurrence-id")) { + continue; + } + + const event = new ICAL.Event(component, { + exceptions: exceptions.get(component.getFirstPropertyValue("uid")) ?? [], + }); + + if (!event.startDate) { + continue; + } + + if (event.isRecurring()) { + const iterator = event.iterator(); + const iterateUntil = iterationEnd(event, to); + + while (true) { + const occurrence = iterator.next(); + + // Recurrences are chronological, so we are done once one starts after + // the month, and after the occurrences a modification can still move + // back into it. + if (!occurrence || occurrence.toJSDate() >= iterateUntil) { + break; } - // Extract date components from different date formats - function getDateComponents(icsDateStr) { - if (!icsDateStr) return null; + // Details resolve time, name and URL of an occurrence that was + // modified via RECURRENCE-ID. + const details = event.getOccurrenceDetails(occurrence); - // Basic handling - extract YYYY, MM, DD regardless of format - const year = parseInt(icsDateStr.substring(0, 4)); - const month = parseInt(icsDateStr.substring(4, 6)) - 1; // 0-based months - const day = parseInt(icsDateStr.substring(6, 8)); - - return { year, month, day }; - } - - function expandRecurringEvents(event, year, month) { - if (!event.rrule) return [event]; - - const rruleStr = event.rrule; - - // Get start date components - const startComponents = getDateComponents(event.start); - if (!startComponents) return [event]; - - const startDate = new Date( - startComponents.year, - startComponents.month, - startComponents.day - ); - - const rangeStart = new Date(year, month, 1); - const rangeEnd = new Date(year, month + 1, 0); - const expandedEvents = []; - - if (rruleStr.includes("FREQ=WEEKLY") && rruleStr.includes("BYDAY")) { - const bydayMatch = rruleStr.match(/BYDAY=([^;]+)/); - if (bydayMatch) { - const dayCode = bydayMatch[1]; - const dayMap = { - 'MO': 1, 'TU': 2, 'WE': 3, 'TH': 4, 'FR': 5, 'SA': 6, 'SU': 0 - }; - const targetDay = dayMap[dayCode]; - - if (targetDay !== undefined) { - // Create events for each matching day in the month - let day = 1; - while (day <= rangeEnd.getDate()) { - const testDate = new Date(year, month, day); - if (testDate.getDay() === targetDay && testDate >= startDate) { - const newEvent = {...event}; - const eventDate = formatDateForICS(testDate); - - // Preserve time portion from original event - const timePart = event.start.includes('T') ? - event.start.substring(event.start.indexOf('T')) : ''; - const endTimePart = event.end.includes('T') ? - event.end.substring(event.end.indexOf('T')) : ''; - - newEvent.start = eventDate + timePart; - newEvent.end = eventDate + endTimePart; - expandedEvents.push(newEvent); - } - day++; - } - } - } - } - else if (rruleStr.includes("FREQ=MONTHLY") && rruleStr.includes("BYDAY")) { - const bydayMatch = rruleStr.match(/BYDAY=([^;]+)/); - if (bydayMatch) { - const intervalMatch = rruleStr.match(/INTERVAL=(\d+)/); - const interval = intervalMatch ? parseInt(intervalMatch[1]) : 1; - const monthsFromStart = (year - startDate.getFullYear()) * 12 + (month - startDate.getMonth()); - if (monthsFromStart < 0 || monthsFromStart % interval !== 0) { - return []; - } - const bydays = bydayMatch[1].split(','); - const dayMap = { - 'MO': 1, 'TU': 2, 'WE': 3, 'TH': 4, 'FR': 5, 'SA': 6, 'SU': 0 - }; - - bydays.forEach(byday => { - const occurrence = parseInt(byday) || 1; - const dayCode = byday.slice(-2); - const dayIndex = dayMap[dayCode]; - - let day = 1; - let count = 0; - - while (day <= rangeEnd.getDate()) { - const testDate = new Date(year, month, day); - if (testDate.getDay() === dayIndex) { - count++; - if (count === occurrence || (occurrence < 0 && day > rangeEnd.getDate() + occurrence * 7)) { - const newEvent = {...event}; - const eventDate = new Date(year, month, day); - - // Preserve time portion from original event - const timePart = event.start.includes('T') ? - event.start.substring(event.start.indexOf('T')) : ''; - const endTimePart = event.end.includes('T') ? - event.end.substring(event.end.indexOf('T')) : ''; - - newEvent.start = formatDateForICS(eventDate) + timePart; - newEvent.end = formatDateForICS(eventDate) + endTimePart; - expandedEvents.push(newEvent); - } - } - day++; - } - }); - } - } - - return expandedEvents.length > 0 ? expandedEvents : [event]; + if (details.endDate.toJSDate() > from) { + add(toOccurrence(details.item, details.startDate, details.endDate)); } - - // Kalender initialisieren - let currentYear, currentMonth; - const currentMonthElem = document.getElementById("current-month"); - const calendarBody = document.getElementById("calendar-body"); - const eventPanel = document.getElementById("event-panel"); - const eventDateElem = document.getElementById("event-date"); - const eventDetailsElem = document.getElementById("event-details"); - - document.getElementById("prev-month").addEventListener("click", function(){ - currentMonth--; - if (currentMonth < 0) { - currentMonth = 11; - currentYear--; - } - updateEventsForMonth(currentYear, currentMonth); - }); - document.getElementById("next-month").addEventListener("click", function(){ - currentMonth++; - if (currentMonth > 11) { - currentMonth = 0; - currentYear++; - } - updateEventsForMonth(currentYear, currentMonth); + } + } else if (event.startDate.toJSDate() < to && event.endDate.toJSDate() > from) { + add(toOccurrence(event, event.startDate, event.endDate)); + } + } + + for (const occurrences of Object.values(byDate)) { + occurrences.sort((a, b) => { + // An all day event has no time of day to sort by, the JS date of its + // start is midnight in the zone of the browser. Put it first instead. + if (a.allDay !== b.allDay) { + return a.allDay ? -1 : 1; + } + + return a.start - b.start; + }); + } + + return byDate; +} + +function updateEventsForMonth(year, month) { + eventsByDate = occurrencesOfMonth(year, month); + renderCalendar(year, month); +} + +function renderCalendar(year, month) { + // Setze die Monatsbeschriftung (in Deutsch) + currentMonthElem.textContent = monthNames[month] + " " + year; + calendarBody.innerHTML = ""; + + let firstDay = new Date(year, month, 1); + let firstDayIndex = (firstDay.getDay() + 6) % 7; // Montag = 0, Dienstag = 1, etc. + let daysInMonth = new Date(year, month + 1, 0).getDate(); + + let row = document.createElement("tr"); + // Leere Zellen vor dem 1. Tag + for (let i = 0; i < firstDayIndex; i++) { + let cell = document.createElement("td"); + row.appendChild(cell); + } + + // Tage hinzufügen + for (let day = 1; day <= daysInMonth; day++) { + if (row.children.length === 7) { + calendarBody.appendChild(row); + row = document.createElement("tr"); + } + let cell = document.createElement("td"); + cell.innerHTML = "" + day + ""; + + let dayStr = day < 10 ? "0" + day : day; + let monthStr = (month + 1) < 10 ? "0" + (month + 1) : (month + 1); + let dateKey = year + "-" + monthStr + "-" + dayStr; + + if (eventsByDate[dateKey]) { + let dotsContainer = document.createElement("div"); + dotsContainer.className = "event-dots-container"; + cell.classList.add("has-event"); + + // Gruppe Events nach Typ + const events = eventsByDate[dateKey]; + const hasMembersOnly = events.some(e => e.summary.toLowerCase().includes("members only")); + const hasSubbotnik = events.some(e => e.summary.toLowerCase().includes("subbotnik")); + const hasBastelabend = events.some(e => e.summary.toLowerCase().includes("bastelabend")); + const hasSpieleabend = events.some(e => e.summary.toLowerCase().includes("spieleabend")); + const hasRegular = events.some(e => { + const title = e.summary.toLowerCase(); + return !title.includes("members only") && + !title.includes("subbotnik") && + !title.includes("bastelabend") && + !title.includes("spieleabend"); + }); + + // Füge Dots entsprechend der Event-Typen hinzu + if (hasMembersOnly) { + let dot = document.createElement("div"); + dot.className = "event-dot event-dot-red"; + dotsContainer.appendChild(dot); + } + if (hasSubbotnik || hasBastelabend || hasSpieleabend) { + let dot = document.createElement("div"); + dot.className = "event-dot event-dot-orange"; + dotsContainer.appendChild(dot); + } + if (hasRegular) { + let dot = document.createElement("div"); + dot.className = "event-dot event-dot-greenyellow"; + dotsContainer.appendChild(dot); + } + + cell.appendChild(dotsContainer); + cell.dataset.dateKey = dateKey; + cell.addEventListener("click", function() { + // Clear previous selections + document.querySelectorAll('.selected-day').forEach(el => { + el.classList.remove('selected-day'); }); - - function updateEventsForMonth(year, month) { - // Clear existing events for this month view - eventsByDate = {}; - - // Process each event, expanding recurring ones - events.forEach(ev => { - if (ev.rrule) { - // For recurring events, expand them for current month - const expandedEvents = expandRecurringEvents(ev, year, month); - expandedEvents.forEach(expandedEv => { - let dateKey = parseDateString(expandedEv.start); - if (dateKey) { - if (!eventsByDate[dateKey]) { - eventsByDate[dateKey] = []; - } - eventsByDate[dateKey].push(expandedEv); - } - }); - } else { - // For regular events, check if they fall in current month - let dateKey = parseDateString(ev.start); - if (dateKey) { - // Check if this event belongs to current month view - const eventYear = parseInt(dateKey.split('-')[0]); - const eventMonth = parseInt(dateKey.split('-')[1]) - 1; - - if (eventYear === year && eventMonth === month) { - if (!eventsByDate[dateKey]) { - eventsByDate[dateKey] = []; - } - eventsByDate[dateKey].push(ev); - } - } - } - }); - - renderCalendar(year, month); - } - - function renderCalendar(year, month) { - // Setze die Monatsbeschriftung (in Deutsch) - const monthNames = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; - currentMonthElem.textContent = monthNames[month] + " " + year; - calendarBody.innerHTML = ""; - - let firstDay = new Date(year, month, 1); - let firstDayIndex = (firstDay.getDay() + 6) % 7; // Montag = 0, Dienstag = 1, etc. - let daysInMonth = new Date(year, month + 1, 0).getDate(); - - let row = document.createElement("tr"); - // Leere Zellen vor dem 1. Tag - for (let i = 0; i < firstDayIndex; i++){ - let cell = document.createElement("td"); - row.appendChild(cell); - } - - // Tage hinzufügen - for (let day = 1; day <= daysInMonth; day++){ - if (row.children.length === 7) { - calendarBody.appendChild(row); - row = document.createElement("tr"); - } - let cell = document.createElement("td"); - cell.innerHTML = "" + day + ""; - - let dayStr = day < 10 ? "0" + day : day; - let monthStr = (month + 1) < 10 ? "0" + (month + 1) : (month + 1); - let dateKey = year + "-" + monthStr + "-" + dayStr; - - if (eventsByDate[dateKey]) { - let dotsContainer = document.createElement("div"); - dotsContainer.className = "event-dots-container"; - cell.classList.add("has-event"); - - // Gruppe Events nach Typ - const events = eventsByDate[dateKey]; - const hasMembersOnly = events.some(e => e.summary.toLowerCase().includes("members only")); - const hasSubbotnik = events.some(e => e.summary.toLowerCase().includes("subbotnik")); - const hasBastelabend = events.some(e => e.summary.toLowerCase().includes("bastelabend")); - const hasSpieleabend = events.some(e => e.summary.toLowerCase().includes("spieleabend")); - const hasRegular = events.some(e => { - const title = e.summary.toLowerCase(); - return !title.includes("members only") && - !title.includes("subbotnik") && - !title.includes("bastelabend") && - !title.includes("spieleabend"); - }); - - // Füge Dots entsprechend der Event-Typen hinzu - if (hasMembersOnly) { - let dot = document.createElement("div"); - dot.className = "event-dot event-dot-red"; - dotsContainer.appendChild(dot); - } - if (hasSubbotnik || hasBastelabend || hasSpieleabend) { - let dot = document.createElement("div"); - dot.className = "event-dot event-dot-orange"; - dotsContainer.appendChild(dot); - } - if (hasRegular) { - let dot = document.createElement("div"); - dot.className = "event-dot event-dot-greenyellow"; - dotsContainer.appendChild(dot); - } - - cell.appendChild(dotsContainer); - cell.dataset.dateKey = dateKey; - cell.addEventListener("click", function() { - // Clear previous selections - document.querySelectorAll('.selected-day').forEach(el => { - el.classList.remove('selected-day'); - }); - cell.classList.add('selected-day'); - showEventDetails(dateKey); - }); - } - row.appendChild(cell); - } - // Falls die letzte Zeile nicht komplett ist - while (row.children.length < 7) { - let cell = document.createElement("td"); - row.appendChild(cell); - } - calendarBody.appendChild(row); - } - - function createEventLink(eventTitle) { - if (eventTitle.startsWith("Datengarten")) { - // Extract the number after "Datengarten " - const match = eventTitle.match(/Datengarten\s+(\d+)/i); - if (match && match[1]) { - return `https://berlin.ccc.de/datengarten/${match[1]}/`; - } - } - - // For other titles, convert to lowercase and use as path - const slug = eventTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, ''); - return `https://berlin.ccc.de/page/${slug}/`; - } - - function showEventDetails(dateKey) { - const events = eventsByDate[dateKey]; - eventDateElem.textContent = formatDate(dateKey); - eventDetailsElem.innerHTML = ""; - - if (events && events.length > 0) { - events.forEach(ev => { - let eventItem = document.createElement("div"); - eventItem.className = "event-item"; - - let eventTitle = document.createElement("div"); - eventTitle.className = "event-title"; - - // Create a link for the event title - let titleLink = document.createElement("h"); - titleLink.textContent = ev.summary; - titleLink.target = "_blank"; - eventTitle.appendChild(titleLink); - - eventItem.appendChild(eventTitle); - - let eventTime = document.createElement("div"); - eventTime.className = "event-time"; - eventTime.textContent = `Start: ${formatTime(ev.start)}, End: ${formatTime(ev.end)}`; - eventItem.appendChild(eventTime); - - if (ev.description) { - let eventDescription = document.createElement("div"); - eventDescription.className = "event-description"; - - // Check if the description is a URL and make it a clickable link - if (ev.description.trim().startsWith('http')) { - let linkElement = document.createElement("a"); - linkElement.href = ev.description.trim(); - linkElement.textContent = ev.description.trim(); - linkElement.target = "_blank"; - eventDescription.innerHTML = ''; - eventDescription.appendChild(linkElement); - } else { - eventDescription.textContent = ev.description; - } - - eventItem.appendChild(eventDescription); - } - - eventDetailsElem.appendChild(eventItem); - }); - } else { - let noEvents = document.createElement("div"); - noEvents.className = "no-events"; - noEvents.textContent = "Keine Veranstaltungen an diesem Tag."; - eventDetailsElem.appendChild(noEvents); - } - - eventPanel.style.display = "block"; - } - - function formatDate(dateStr) { - // Convert YYYY-MM-DD to DD.MM.YYYY - const parts = dateStr.split("-"); - return `${parts[2]}.${parts[1]}.${parts[0]}`; - } - - function formatTime(icsTimeStr) { - // Format time for display - if (!icsTimeStr) return ""; - - if (icsTimeStr.length === 8) { - // All-day event - return "Ganztägig"; - } else if (icsTimeStr.includes("T")) { - // Time-specific event (with or without timezone) - const timeStart = icsTimeStr.indexOf("T") + 1; - const hour = icsTimeStr.substring(timeStart, timeStart + 2); - const minute = icsTimeStr.substring(timeStart + 2, timeStart + 4); - return `${hour}:${minute}`; - } - return icsTimeStr; - } - - function formatDateForICS(date) { - const year = date.getFullYear(); - const month = (date.getMonth() + 1).toString().padStart(2, '0'); - const day = date.getDate().toString().padStart(2, '0'); - return `${year}${month}${day}`; - } - - // ICS-Datei abrufen und Events verarbeiten - fetch('/calendars/all.ics') - .then(response => response.text()) - .then(data => { - events = parseICS(data); - - // Initialize with current date - let today = new Date(); - currentYear = today.getFullYear(); - currentMonth = today.getMonth(); - - // Process events for current month - updateEventsForMonth(currentYear, currentMonth); - }) - .catch(err => console.error('Fehler beim Laden der ICS-Datei:', err)); - })(); + cell.classList.add('selected-day'); + showEventDetails(dateKey); + }); + } + row.appendChild(cell); + } + // Falls die letzte Zeile nicht komplett ist + while (row.children.length < 7) { + let cell = document.createElement("td"); + row.appendChild(cell); + } + calendarBody.appendChild(row); +} + +/** + * Build the entry of a single event in the detail panel. + * + * @param {Object} occurrence The occurrence to show + * @returns {HTMLElement} The entry + */ +function renderEventItem(occurrence) { + const item = document.createElement("div"); + item.className = "event-item"; + + const title = document.createElement("div"); + title.className = "event-title"; + + if (occurrence.url) { + const link = document.createElement("a"); + link.href = occurrence.url; + link.textContent = occurrence.summary; + title.appendChild(link); + } else { + title.textContent = occurrence.summary; + } + + item.appendChild(title); + + const time = document.createElement("div"); + time.className = "event-time"; + time.textContent = formatTimeRange(occurrence); + item.appendChild(time); + + if (occurrence.description) { + const description = document.createElement("div"); + description.className = "event-description"; + description.textContent = occurrence.description; + item.appendChild(description); + } + + return item; +} + +function showEventDetails(dateKey) { + const occurrences = eventsByDate[dateKey]; + eventDateElem.textContent = formatDate(dateKey); + eventDetailsElem.innerHTML = ""; + + if (occurrences && occurrences.length > 0) { + for (const occurrence of occurrences) { + eventDetailsElem.appendChild(renderEventItem(occurrence)); + } + } else { + let noEvents = document.createElement("div"); + noEvents.className = "no-events"; + noEvents.textContent = "Keine Veranstaltungen an diesem Tag."; + eventDetailsElem.appendChild(noEvents); + } + + eventPanel.style.display = "block"; +} + +function formatDate(dateStr) { + // Convert YYYY-MM-DD to DD.MM.YYYY + const parts = dateStr.split("-"); + return `${parts[2]}.${parts[1]}.${parts[0]}`; +} + +/** + * Describe when an occurrence takes place, in Berlin time. + * + * @param {Object} occurrence The occurrence to describe + * @returns {string} The description + */ +function formatTimeRange(occurrence) { + if (occurrence.allDay) { + return "Ganztägig"; + } + + const start = timeOfDayFormat.format(occurrence.start); + const end = timeOfDayFormat.format(occurrence.end); + + return `Beginn: ${start}, Ende: ${end}`; +} + +document.addEventListener("DOMContentLoaded", function() { + currentMonthElem = document.getElementById("current-month"); + calendarBody = document.getElementById("calendar-body"); + eventPanel = document.getElementById("event-panel"); + eventDateElem = document.getElementById("event-date"); + eventDetailsElem = document.getElementById("event-details"); + + document.getElementById("prev-month").addEventListener("click", function() { + currentMonth--; + if (currentMonth < 0) { + currentMonth = 11; + currentYear--; + } + updateEventsForMonth(currentYear, currentMonth); + }); + document.getElementById("next-month").addEventListener("click", function() { + currentMonth++; + if (currentMonth > 11) { + currentMonth = 0; + currentYear++; + } + updateEventsForMonth(currentYear, currentMonth); + }); + + // Show the grid of the current month right away, the events are filled in + // once the calendar has been loaded. + const today = new Date(); + currentYear = today.getFullYear(); + currentMonth = today.getMonth(); + updateEventsForMonth(currentYear, currentMonth); + + fetch(icsUrl) + .then(response => { + // Without this an error page would be handed to the parser below, which + // then fails with a confusing complaint about the calendar syntax. + if (!response.ok) { + throw new Error(`${icsUrl}: ${response.status} ${response.statusText}`); + } + + return response.text(); + }) + .then(icsText => { + calendar = new ICAL.Component(ICAL.parse(icsText)); + updateEventsForMonth(currentYear, currentMonth); + }) + .catch(err => console.error("Fehler beim Laden der ICS-Datei:", err)); }); diff --git a/layouts/shortcodes/calendar.html b/layouts/shortcodes/calendar.html index 52812c7..3965301 100644 --- a/layouts/shortcodes/calendar.html +++ b/layouts/shortcodes/calendar.html @@ -1,12 +1,12 @@ -{{ $js := resources.Get "js/calendar.js" }} -{{ $css := resources.Get "css/calendar.css" }} +{{ $js := resources.Get "js/calendar.js" | js.Build (dict "minify" true "format" "esm" "target" "es2020") | fingerprint }} +{{ $css := resources.Get "css/calendar.css" | minify | fingerprint }}
{{ with $css }} - + {{ end }} {{ with $js }} - + {{ end }}
From 75dd9ca9970ae33995c3ed38e2e0126c47fa72ec Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 22 Aug 2026 20:23:00 +0200 Subject: [PATCH 11/18] Separate date and name in the upcoming events table The two columns of the table on the start page touched each other, so the entry read "Donnerstag, 27.08., 19:00 UhrClub Discordia". The table is created with the classes "table table-condensed", which no stylesheet of the site defines, and the table styling that the theme applies inside prose addresses "tbody td". The table is delivered empty and its rows are added through the DOM, where a tr appended to a table stays a direct child instead of being put into a tbody the way the HTML parser would. The rows are therefore outside of any tbody and the padding of the theme never applied. Give the column holding the date its own padding, and keep the date on one line, it is one piece of information and reads badly broken after the weekday. The padding alone does not fit, though. The table stands in a prose column that the theme limits to 65 characters so that running text stays readable, and a date and the name of an event next to each other are wider than that, so the names would be wrapped over several lines. Lift the limit off the column and put it back on everything in it except the table, which leaves the table room to grow while the heading and the paragraph around it keep their width. That much space then has to be filled sensibly. The theme lays a table out as a block, "table { display: block; overflow: auto }", so that a wide one can be scrolled sideways, and a block fills its parent instead of shrinking to its content the way a table does. Spanning the page the entries would all sit at its left edge. Ask for the width of the content with fit-content, which the automatic margins then centre. Addressing the table by its id keeps all of this to the start page and takes precedence over the theme, whose prose rules are written with :where() and carry no specificity. Measured in a browser at 1280, 768 and 500 pixels: date and name share one line at the first two, the table is 602 pixels wide with the same distance left and right, and at 500 the column is narrower than the table, so the table fills it and only the longest name wraps. The page never scrolls sideways. Fixes: c28f04c6e85c ("switch to ics files; make calendars work; fix some minor issues") Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- assets/css/upcoming.css | 36 ++++++++++++++++++++++++++++++++ layouts/shortcodes/upcoming.html | 2 ++ 2 files changed, 38 insertions(+) create mode 100644 assets/css/upcoming.css diff --git a/assets/css/upcoming.css b/assets/css/upcoming.css new file mode 100644 index 0000000..05b096d --- /dev/null +++ b/assets/css/upcoming.css @@ -0,0 +1,36 @@ +/* The rows of the table are added by JavaScript and end up as direct children + of the table, so the table styling of the theme, which addresses tbody, does + not reach them. Separate the date from the name of the event ourselves, and + keep the date on one line, it is one piece of information and reads badly + broken after the weekday. */ +#upcoming td:first-child { + padding-inline-end: 1em; + white-space: nowrap; +} + +/* The table stands in a prose column, which the theme limits to 65 characters + so that running text stays readable. A date and the name of an event next to + each other do not fit into that, so the names were wrapped over several + lines. Lift the limit off the column and put it back on everything in it + except the table, which leaves the table room to grow while the text around + it keeps its width. */ +section.prose:has(> #upcoming) { + max-width: none; +} + +section.prose:has(> #upcoming) > :not(#upcoming) { + max-width: 65ch; + margin-inline: auto; +} + +/* The theme lays a table out as a block, "table { display: block; overflow: + auto }", so that a wide one can be scrolled sideways. A block fills its + parent instead of shrinking to its content the way a table does, so across + the whole width of the page the entries would stay at its left edge. + fit-content asks for the width of the content, which the automatic margins + then centre, and it never exceeds the column, so a display too narrow for + the table still wraps the names instead of overflowing. */ +#upcoming { + width: fit-content; + margin-inline: auto; +} diff --git a/layouts/shortcodes/upcoming.html b/layouts/shortcodes/upcoming.html index 18173b3..d0cc46d 100644 --- a/layouts/shortcodes/upcoming.html +++ b/layouts/shortcodes/upcoming.html @@ -1,3 +1,5 @@ +{{- $css := resources.Get "css/upcoming.css" | minify | fingerprint -}} {{- $js := resources.Get "js/upcoming.js" | js.Build (dict "minify" true "format" "esm" "target" "es2020") | fingerprint -}} +
From 6782da49d47049d953f18ad6b2c2c0afea8ce394 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 23 Aug 2026 00:54:58 +0200 Subject: [PATCH 12/18] Move what the two calendar views share into one module Both views read the same file and ask it the same question, only the answer is presented differently: the start page lists the next few occurrences, the calendar page marks the occurrences of one month. Since they were taught to read a calendar properly they also carry the same code for it, twice and word for word, some 130 lines of `eventUrl()`, `exceptionsByUid()`, `iterationEnd()`, the fetch with its check of the response and the walk over the events of the calendar. Every fix so far had to be written twice, and the next one that is only written once leaves the two views disagreeing about the same calendar. Put it into `assets/js/events.js`, which offers what both need: - `loadCalendar()` fetches and parses `/calendars/all.ics` - `occurrencesBetween()` walks the occurrences that touch a window, expanding recurring events and resolving the ones that were modified on their own - `eventUrl()` reads the URL of an event `upcoming.js` and `calendar.js` keep what is really theirs, the shape of their entries and how they are drawn, and both lose their own import of ical.js: it is the concern of the module that reads the calendar now. The two of them shrink from 259 and 549 lines to 105 and 406. Hugo bundles the module into both scripts, so no shortcode changes and no second request. The walk keeps an occurrence when it starts at or before the end of the window and ends after its start. That is the condition the start page used; the calendar page compared against the start of the month with "<" instead of "<=". Its window reaches two days past the month, so the day this can differ on is nowhere near it. No behaviour changes with this: the upcoming list over 120 days and every day of the month view from 2025 to 2028, taken from https://berlin.ccc.de/calendars/all.ics with the name, URL, start, end and all day flag of each entry, are identical before and after, and so are the results of the tests for moved occurrences, for modifications between two series and for all day events in Berlin, Tokyo, Los Angeles and Kiritimati. Assisted-by: Claude:claude-opus-5 Signed-off-by: Hauke Mehrtens --- assets/js/calendar.js | 155 ++------------------------------- assets/js/events.js | 194 ++++++++++++++++++++++++++++++++++++++++++ assets/js/upcoming.js | 184 ++++----------------------------------- 3 files changed, 215 insertions(+), 318 deletions(-) create mode 100644 assets/js/events.js diff --git a/assets/js/calendar.js b/assets/js/calendar.js index 596eca0..b12529c 100644 --- a/assets/js/calendar.js +++ b/assets/js/calendar.js @@ -1,6 +1,4 @@ -import ICAL from "./vendor/ical.js"; - -const icsUrl = "/calendars/all.ics"; +import { eventUrl, loadCalendar, occurrencesBetween } from "./events.js"; // The club is in Berlin, so the calendar shows Berlin days and Berlin times, // no matter which time zone the browser of the visitor is set to. @@ -116,37 +114,6 @@ function daysCovered(start, end) { return days; } -/** - * Read the URL of an event. - * - * ICAL.Event does not expose the URL property, so read it from the component. - * - * The value ends up in the href of a link, and the calendar is exported from a - * CalDAV server, so whoever may write to it decides what that value is. A - * "javascript:" URL there would run on our page as soon as a visitor clicks - * the event, so hand on nothing but http and https. - * - * @param {ICAL.Event} event The event to read the URL of - * @returns {string} The URL, empty when the event has none or it is not http(s) - */ -function eventUrl(event) { - const url = event.component.getFirstPropertyValue("url") ?? ""; - - if (!url) { - return ""; - } - - try { - // A relative URL is resolved against the page and keeps its scheme. - const { protocol } = new URL(url, document.baseURI); - - return protocol === "http:" || protocol === "https:" ? url : ""; - } catch { - // Not a URL at all. - return ""; - } -} - /** * Reduce one occurrence of an event to what the calendar displays. * @@ -169,66 +136,6 @@ function toOccurrence(event, startDate, endDate) { }; } -/** - * Group the occurrences that were modified on their own by the UID of the event - * they belong to. - * - * Unless it is told which exceptions belong to an event, ICAL.Event relates - * every VEVENT with a RECURRENCE-ID in the file to every recurring event, and - * it keys them by the recurrence id alone. Two series that meet at the same - * time would therefore take over each other's modifications. - * - * @param {ICAL.Component[]} components The VEVENTs of the calendar - * @returns {Map} The exceptions per UID - */ -function exceptionsByUid(components) { - const exceptions = new Map(); - - for (const component of components) { - if (!component.hasProperty("recurrence-id")) { - continue; - } - - const uid = component.getFirstPropertyValue("uid"); - const ofEvent = exceptions.get(uid); - - if (ofEvent) { - ofEvent.push(component); - } else { - exceptions.set(uid, [component]); - } - } - - return exceptions; -} - -/** - * How far the recurrences of an event have to be iterated. - * - * The iteration walks the unmodified recurrence times, so an occurrence that - * was moved to an earlier time is only reached through the time it originally - * had, which can lie past the end of the month. Keep going for as long as the - * largest move towards the past can still carry an occurrence into it. - * - * @param {ICAL.Event} event The event whose recurrences are iterated - * @param {Date} to End of the window - * @returns {Date} The recurrence time to stop at - */ -function iterationEnd(event, to) { - let last = to.getTime(); - - for (const exception of Object.values(event.exceptions)) { - const movedBy = exception.recurrenceId.toJSDate().getTime() - - exception.startDate.toJSDate().getTime(); - - if (movedBy > 0) { - last = Math.max(last, to.getTime() + movedBy); - } - } - - return new Date(last); -} - /** * Collect everything that takes place in the given month, keyed by day. * @@ -268,49 +175,8 @@ function occurrencesOfMonth(year, month) { } }; - const components = calendar.getAllSubcomponents("vevent"); - const exceptions = exceptionsByUid(components); - - for (const component of components) { - // Occurrences modified via RECURRENCE-ID are reached through the event they - // belong to, handling them here as well would show them twice. - if (component.hasProperty("recurrence-id")) { - continue; - } - - const event = new ICAL.Event(component, { - exceptions: exceptions.get(component.getFirstPropertyValue("uid")) ?? [], - }); - - if (!event.startDate) { - continue; - } - - if (event.isRecurring()) { - const iterator = event.iterator(); - const iterateUntil = iterationEnd(event, to); - - while (true) { - const occurrence = iterator.next(); - - // Recurrences are chronological, so we are done once one starts after - // the month, and after the occurrences a modification can still move - // back into it. - if (!occurrence || occurrence.toJSDate() >= iterateUntil) { - break; - } - - // Details resolve time, name and URL of an occurrence that was - // modified via RECURRENCE-ID. - const details = event.getOccurrenceDetails(occurrence); - - if (details.endDate.toJSDate() > from) { - add(toOccurrence(details.item, details.startDate, details.endDate)); - } - } - } else if (event.startDate.toJSDate() < to && event.endDate.toJSDate() > from) { - add(toOccurrence(event, event.startDate, event.endDate)); - } + for (const { event, startDate, endDate } of occurrencesBetween(calendar, from, to)) { + add(toOccurrence(event, startDate, endDate)); } for (const occurrences of Object.values(byDate)) { @@ -531,18 +397,9 @@ document.addEventListener("DOMContentLoaded", function() { currentMonth = today.getMonth(); updateEventsForMonth(currentYear, currentMonth); - fetch(icsUrl) - .then(response => { - // Without this an error page would be handed to the parser below, which - // then fails with a confusing complaint about the calendar syntax. - if (!response.ok) { - throw new Error(`${icsUrl}: ${response.status} ${response.statusText}`); - } - - return response.text(); - }) - .then(icsText => { - calendar = new ICAL.Component(ICAL.parse(icsText)); + loadCalendar() + .then(loaded => { + calendar = loaded; updateEventsForMonth(currentYear, currentMonth); }) .catch(err => console.error("Fehler beim Laden der ICS-Datei:", err)); diff --git a/assets/js/events.js b/assets/js/events.js new file mode 100644 index 0000000..0941e26 --- /dev/null +++ b/assets/js/events.js @@ -0,0 +1,194 @@ +import ICAL from "./vendor/ical.js"; + +// The calendar is published next to the site and is not built from this +// repository, see the README. +const icsUrl = "/calendars/all.ics"; + +/** + * Read the URL of an event. + * + * ICAL.Event does not expose the URL property, so read it from the component. + * + * The value ends up in the href of a link, and the calendar is exported from a + * CalDAV server, so whoever may write to it decides what that value is. A + * "javascript:" URL there would run on our page as soon as a visitor clicks + * the event, so hand on nothing but http and https. + * + * @param {ICAL.Event} event The event to read the URL of + * @returns {string} The URL, empty when the event has none or it is not http(s) + */ +export function eventUrl(event) { + const url = event.component.getFirstPropertyValue("url") ?? ""; + + if (!url) { + return ""; + } + + try { + // A relative URL is resolved against the page and keeps its scheme. + const { protocol } = new URL(url, document.baseURI); + + return protocol === "http:" || protocol === "https:" ? url : ""; + } catch { + // Not a URL at all. + return ""; + } +} + +/** + * Group the occurrences that were modified on their own by the UID of the event + * they belong to. + * + * Unless it is told which exceptions belong to an event, ICAL.Event relates + * every VEVENT with a RECURRENCE-ID in the file to every recurring event, and + * it keys them by the recurrence id alone. Two series that meet at the same + * time would therefore take over each other's modifications. + * + * @param {ICAL.Component[]} components The VEVENTs of the calendar + * @returns {Map} The exceptions per UID + */ +function exceptionsByUid(components) { + const exceptions = new Map(); + + for (const component of components) { + if (!component.hasProperty("recurrence-id")) { + continue; + } + + const uid = component.getFirstPropertyValue("uid"); + const ofEvent = exceptions.get(uid); + + if (ofEvent) { + ofEvent.push(component); + } else { + exceptions.set(uid, [component]); + } + } + + return exceptions; +} + +/** + * How far the recurrences of an event have to be iterated. + * + * The iteration walks the unmodified recurrence times, so an occurrence that + * was moved to an earlier time is only reached through the time it originally + * had, which can lie past the end of the window. Keep going for as long as the + * largest move towards the past can still carry an occurrence into it. + * + * @param {ICAL.Event} event The event whose recurrences are iterated + * @param {Date} to End of the window + * @returns {Date} The recurrence time to stop at + */ +function iterationEnd(event, to) { + let last = to.getTime(); + + for (const exception of Object.values(event.exceptions)) { + const movedBy = exception.recurrenceId.toJSDate().getTime() + - exception.startDate.toJSDate().getTime(); + + if (movedBy > 0) { + last = Math.max(last, to.getTime() + movedBy); + } + } + + return new Date(last); +} + +/** + * Whether an occurrence touches a window. + * + * @param {ICAL.Time} startDate Start of the occurrence + * @param {ICAL.Time} endDate End of the occurrence + * @param {Date} from Start of the window + * @param {Date} to End of the window + * @returns {boolean} True when the two overlap + */ +function touches(startDate, endDate, from, to) { + return startDate.toJSDate() <= to && endDate.toJSDate() > from; +} + +/** + * Load and parse the calendar of the club. + * + * @returns {Promise} The calendar + */ +export async function loadCalendar() { + const response = await fetch(icsUrl); + + // Without this an error page would be handed to the parser below, which then + // fails with a confusing complaint about the calendar syntax. + if (!response.ok) { + throw new Error(`${icsUrl}: ${response.status} ${response.statusText}`); + } + + return new ICAL.Component(ICAL.parse(await response.text())); +} + +/** + * Every occurrence of the calendar that touches the given window. + * + * A recurring event is expanded, and an occurrence that was modified on its own + * is reported with the time, the name and the URL of that modification. + * + * @param {ICAL.Component} calendar The parsed calendar + * @param {Date} from An occurrence has to still be running at this time + * @param {Date} to An occurrence has to have started by this time + * @yields {{event: ICAL.Event, startDate: ICAL.Time, endDate: ICAL.Time}} + */ +export function* occurrencesBetween(calendar, from, to) { + const components = calendar.getAllSubcomponents("vevent"); + const exceptions = exceptionsByUid(components); + + for (const component of components) { + // Occurrences modified via RECURRENCE-ID are reached through the event they + // belong to, handling them here as well would report them twice. + if (component.hasProperty("recurrence-id")) { + continue; + } + + const event = new ICAL.Event(component, { + exceptions: exceptions.get(component.getFirstPropertyValue("uid")) ?? [], + }); + + if (!event.startDate) { + continue; + } + + if (!event.isRecurring()) { + if (touches(event.startDate, event.endDate, from, to)) { + yield { event, startDate: event.startDate, endDate: event.endDate }; + } + + continue; + } + + const iterator = event.iterator(); + const iterateUntil = iterationEnd(event, to); + + while (true) { + const occurrence = iterator.next(); + + // Recurrences are chronological, so we are done once one starts after the + // window, and after the occurrences a modification can still move back + // into it. + if (!occurrence || occurrence.toJSDate() > iterateUntil) { + break; + } + + // Details resolve time, name and URL of an occurrence that was modified + // via RECURRENCE-ID. + const details = event.getOccurrenceDetails(occurrence); + + // A modification may have moved the occurrence out of the window, so + // judge it by the time it really takes place at. + if (touches(details.startDate, details.endDate, from, to)) { + yield { + event: details.item, + startDate: details.startDate, + endDate: details.endDate, + }; + } + } + } +} diff --git a/assets/js/upcoming.js b/assets/js/upcoming.js index c55a2e3..7f6d63f 100644 --- a/assets/js/upcoming.js +++ b/assets/js/upcoming.js @@ -1,68 +1,4 @@ -import ICAL from "./vendor/ical.js"; - -/** - * Read the URL of an event. - * - * ICAL.Event does not expose the URL property, so read it from the component. - * - * The value ends up in the href of a link, and the calendar is exported from a - * CalDAV server, so whoever may write to it decides what that value is. A - * "javascript:" URL there would run on our page as soon as a visitor clicks - * the event, so hand on nothing but http and https. - * - * @param {ICAL.Event} event The event to read the URL of - * @returns {string} The URL, empty when the event has none or it is not http(s) - */ -function eventUrl(event) { - const url = event.component.getFirstPropertyValue("url") ?? ""; - - if (!url) { - return ""; - } - - try { - // A relative URL is resolved against the page and keeps its scheme. - const { protocol } = new URL(url, document.baseURI); - - return protocol === "http:" || protocol === "https:" ? url : ""; - } catch { - // Not a URL at all. - return ""; - } -} - -/** - * Group the occurrences that were modified on their own by the UID of the event - * they belong to. - * - * Unless it is told which exceptions belong to an event, ICAL.Event relates - * every VEVENT with a RECURRENCE-ID in the file to every recurring event, and - * it keys them by the recurrence id alone. Two series that meet at the same - * time would therefore take over each other's modifications. - * - * @param {ICAL.Component[]} components The VEVENTs of the calendar - * @returns {Map} The exceptions per UID - */ -function exceptionsByUid(components) { - const exceptions = new Map(); - - for (const component of components) { - if (!component.hasProperty("recurrence-id")) { - continue; - } - - const uid = component.getFirstPropertyValue("uid"); - const ofEvent = exceptions.get(uid); - - if (ofEvent) { - ofEvent.push(component); - } else { - exceptions.set(uid, [component]); - } - } - - return exceptions; -} +import { eventUrl, loadCalendar, occurrencesBetween } from "./events.js"; /** * When an occurrence starts, as a point in time. @@ -85,109 +21,29 @@ function startOf(time) { } /** - * How far the recurrences of an event have to be iterated. + * The upcoming occurrences of a calendar. * - * The iteration walks the unmodified recurrence times, so an occurrence that - * was moved to an earlier time is only reached through the time it originally - * had, which can lie past the end of the window. Keep going for as long as the - * largest move towards the past can still carry an occurrence into it. - * - * @param {ICAL.Event} event The event whose recurrences are iterated - * @param {Date} end End of the window - * @returns {Date} The recurrence time to stop at - */ -function iterationEnd(event, end) { - let last = end.getTime(); - - for (const exception of Object.values(event.exceptions)) { - const movedBy = exception.recurrenceId.toJSDate().getTime() - - exception.startDate.toJSDate().getTime(); - - if (movedBy > 0) { - last = Math.max(last, end.getTime() + movedBy); - } - } - - return new Date(last); -} - -/** - * Parse an ICS calendar and return upcoming event occurrences. - * - * @param {string} icsText The contents of the .ics file + * @param {ICAL.Component} calendar The parsed calendar * @param {Date} now Events must still be running at this date * @param {number} maxEvents Maximum number of events to return * @param {number} maxDays Maximum number of days into the future * @returns {{start: Date, allDay: boolean, name: string, url: string}[]} url is empty when the event has no URL */ -function getUpcomingEvents(icsText, now, maxEvents, maxDays) { - const jcal = ICAL.parse(icsText); - const calendar = new ICAL.Component(jcal); - +function getUpcomingEvents(calendar, now, maxEvents, maxDays) { const end = new Date(now.getTime()); end.setDate(end.getDate() + maxDays); const events = []; - const components = calendar.getAllSubcomponents("vevent"); - const exceptions = exceptionsByUid(components); - - for (const component of components) { - // Occurrences modified via RECURRENCE-ID are reached through the event they - // belong to, listing them here as well would show them twice. - if (component.hasProperty("recurrence-id")) { - continue; - } - - const event = new ICAL.Event(component, { - exceptions: exceptions.get(component.getFirstPropertyValue("uid")) ?? [], + // A running event stays listed until it is over, so the window starts at now + // and the walk keeps everything that has not ended yet. + for (const { event, startDate } of occurrencesBetween(calendar, now, end)) { + events.push({ + start: startOf(startDate), + allDay: startDate.isDate, + name: event.summary ?? "", + url: eventUrl(event), }); - - if (!event.startDate) { - continue; - } - - if (event.isRecurring()) { - const iterator = event.iterator(); - const iterateUntil = iterationEnd(event, end); - - while (true) { - const occurrence = iterator.next(); - - if (!occurrence) { - break; - } - - // Recurrences are chronological, so we're done - // once we pass the end of our search window. - if (occurrence.toJSDate() > iterateUntil) { - break; - } - - // Details resolve time, name and URL of an occurrence that was - // modified via RECURRENCE-ID. - const details = event.getOccurrenceDetails(occurrence); - - // A running event stays listed until it is over, so filter on its end. - // A modification may have moved the occurrence out of the window, so - // judge it by the time it really takes place at. - if (details.startDate.toJSDate() <= end && details.endDate.toJSDate() > now) { - events.push({ - start: startOf(details.startDate), - allDay: details.startDate.isDate, - name: details.item.summary ?? "", - url: eventUrl(details.item), - }); - } - } - } else if (event.startDate.toJSDate() <= end && event.endDate.toJSDate() > now) { - events.push({ - start: startOf(event.startDate), - allDay: event.startDate.isDate, - name: event.summary ?? "", - url: eventUrl(event), - }); - } } // We have occurrences from multiple events, so sort them @@ -198,25 +54,15 @@ function getUpcomingEvents(icsText, now, maxEvents, maxDays) { } document.addEventListener("DOMContentLoaded", () => { - const ics = "/calendars/all.ics"; const max_days = 20; const max_items = 5; const now = new Date(); const table = document.getElementById("upcoming"); - fetch(ics) - .then(response => { - // Without this an error page would be handed to the parser below, which - // then fails with a confusing complaint about the calendar syntax. - if (!response.ok) { - throw new Error(`${ics}: ${response.status} ${response.statusText}`); - } - - return response.text(); - }) - .then(icsText => { - getUpcomingEvents(icsText, now, max_items, max_days).forEach(event => { + loadCalendar() + .then(calendar => { + getUpcomingEvents(calendar, now, max_items, max_days).forEach(event => { const row = document.createElement("tr"); const colBegin = document.createElement("td"); From 4d692c5b48e66f4cd3848ad70832deed6b996d5b Mon Sep 17 00:00:00 2001 From: xengi Date: Tue, 25 Aug 2026 20:45:27 +0200 Subject: [PATCH 13/18] Update .forgejo/workflows/deploy.yaml --- .forgejo/workflows/deploy.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml index 04e8003..f7a5dae 100644 --- a/.forgejo/workflows/deploy.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -38,8 +38,8 @@ jobs: - name: Setup SSH run: | mkdir -p ~/.ssh - printf "%s" "${{ secrets.KNOWN_HOSTS }}" | base64 -d > ~/.ssh/known_hosts - printf "%s" "${{ env.GIT_BRANCH == 'production' && secrets.SSH_PRIVATE_KEY_PRODUCTION || secrets.SSH_PRIVATE_KEY_STAGING }}" | base64 -d > ~/.ssh/id_ed25519 + printf "%s" "${{ secrets.KNOWN_HOSTS }}" > ~/.ssh/known_hosts + printf "%s" "${{ env.GIT_BRANCH == 'production' && secrets.SSH_PRIVATE_KEY_PRODUCTION || secrets.SSH_PRIVATE_KEY_STAGING }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keygen -f ~/.ssh/id_ed25519 -y > ~/.ssh/id_ed25519.pub cat ~/.ssh/id_ed25519.pub From 2d688a14a36f9ace843e65b7e826409000fbe6b0 Mon Sep 17 00:00:00 2001 From: xengi Date: Tue, 25 Aug 2026 20:47:17 +0200 Subject: [PATCH 14/18] Update .forgejo/workflows/deploy.yaml --- .forgejo/workflows/deploy.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml index f7a5dae..04e8003 100644 --- a/.forgejo/workflows/deploy.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -38,8 +38,8 @@ jobs: - name: Setup SSH run: | mkdir -p ~/.ssh - printf "%s" "${{ secrets.KNOWN_HOSTS }}" > ~/.ssh/known_hosts - printf "%s" "${{ env.GIT_BRANCH == 'production' && secrets.SSH_PRIVATE_KEY_PRODUCTION || secrets.SSH_PRIVATE_KEY_STAGING }}" > ~/.ssh/id_ed25519 + printf "%s" "${{ secrets.KNOWN_HOSTS }}" | base64 -d > ~/.ssh/known_hosts + printf "%s" "${{ env.GIT_BRANCH == 'production' && secrets.SSH_PRIVATE_KEY_PRODUCTION || secrets.SSH_PRIVATE_KEY_STAGING }}" | base64 -d > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keygen -f ~/.ssh/id_ed25519 -y > ~/.ssh/id_ed25519.pub cat ~/.ssh/id_ed25519.pub From 3173d0766c9fc0467dd5141b11c1f9e24d03977d Mon Sep 17 00:00:00 2001 From: xengi Date: Tue, 25 Aug 2026 20:57:44 +0200 Subject: [PATCH 15/18] Update .forgejo/workflows/deploy.yaml --- .forgejo/workflows/deploy.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml index 04e8003..229d2f1 100644 --- a/.forgejo/workflows/deploy.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -1,5 +1,10 @@ name: deploy blog +# Create secrets with: +# KNOWN_HOST=$(ssh-keyscan -H www.berlin.ccc.de | grep ssh-ed25519 | base64 -w0) +# SSH_PRIVATE_KEY_PRODUCTION=$(agenix -d id_ed25519_www-production.age | base64 -w0) +# SSH_PRIVATE_KEY_STAGING=$(agenix -d id_ed25519_www-staging.age | base64 -w0) + on: workflow_dispatch: schedule: From d336d02093d9c8ea416cef03ff0ba32d38b00fba Mon Sep 17 00:00:00 2001 From: April John Date: Fri, 28 Aug 2026 16:29:44 +0200 Subject: [PATCH 16/18] woop woop --- .../2026-08-28-normenkontrolle-asog/index.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 content/post/2026-08-28-normenkontrolle-asog/index.md diff --git a/content/post/2026-08-28-normenkontrolle-asog/index.md b/content/post/2026-08-28-normenkontrolle-asog/index.md new file mode 100644 index 0000000..c7e76e3 --- /dev/null +++ b/content/post/2026-08-28-normenkontrolle-asog/index.md @@ -0,0 +1,60 @@ +--- +title: "Linke und Grüne ziehen gegen das Berliner Polizeigesetz vor Gericht" +date: 2026-08-28T12:00:00+02:00 +showHero: false +tags: ["Überwachung", "Polizeigesetz", "ASOG"] +--- + +Als CDU und SPD Ende 2025 das Berliner Polizeigesetz verschärften, war die Kritik laut. Jetzt wird sie juristisch: Am 28. August 2026 haben Bündnis 90/Die Grünen und Die Linke beim Verfassungsgerichtshof des Landes Berlin einen Antrag auf Normenkontrolle eingereicht. Das höchste Berliner Gericht soll nun prüfen, ob die neuen Überwachungsbefugnisse mit der Landesverfassung vereinbar sind oder schlicht zu weit gehen. + +### Vor fünf Tagen war das noch ein Thema im Club + +Am 23. August fand unser [Aktionstag gegen Überwachung](/post/2026/08/11/aktionstag-gegen-überwachung/) statt. Rund 80 Leute kamen, um über KI-Kameras, Verhaltensscanner und das verschärfte Polizeigesetz zu reden. Auch Abgeordnete der Linksfraktion waren dabei und erzählten dort schon, dass sie gegen das Gesetz vorgehen wollen. Ein Normenkontrollantrag war im Gespräch. + +Jetzt liegt er vor. + +### Kurzer Rückblick + +Im Dezember 2025 beschloss die schwarz-rote Koalition eine Novelle des Allgemeinen Sicherheits- und Ordnungsgesetzes (ASOG). Heraus kam ein Gesetzespaket voller neuer digitaler Befugnisse: von Kameras, die Verhalten automatisch analysieren, bis zu einer zentralen Plattform, auf der ganz unterschiedliche Polizeidaten zusammengeführt werden dürfen. + +Die Berliner Datenschutzbeauftragte warnte, die Opposition warnte, unabhängige Sachverständige im Innenausschuss warnten. Passiert ist trotzdem wenig: die Kritik wurde im Verfahren nicht ausgeräumt. Genau hier setzt der Normenkontrollantrag an. + +### Worum es konkret geht + +Die Kanzlei KM8, die die Fraktionen vertritt, zählt in ihrer Begründung fünf Punkte auf, die besonders stechen: + +1. Die Polizei darf künftig mit Spähsoftware auf Smartphones und Computer zugreifen und zwar nicht nur bei schwersten Straftaten, sondern schon zur Verhinderung vergleichsweise kleiner Delikte. Wer solche Software baut, braucht Sicherheitslücken. Das Gesetz setzt also einen Anreiz, Lücken offenzuhalten, statt sie zu stopfen. + +2. Der überwachte öffentliche Raum soll automatisiert ausgewertet werden: Wer sich „auffällig" verhält, löst Alarm aus. Was auffällig ist, entscheidet der Algorithmus - ohne klare Einsatzregeln und ohne echten Schutz gegen Fehler, Diskriminierung oder Missbrauch. + +3. Öffentlich zugängliche Bilder aus dem Internet darf die Polizei in großem Stil biometrisch auswerten. Die Kanzlei spricht von biometrischer Massenüberwachung und von einem Abschreckungseffekt, der vor allem diejenigen trifft, die demonstrieren wollen. + +4. Polizeilich erhobene Daten sollen für einen komplett neuen Zweck weiterverwendet werden dürfen: das Training von KI-Systemen, teilweise sogar unter Weitergabe an private Firmen. Was genau mit welchen Daten passiert, lässt das Gesetz offen. Der Grundsatz, dass Daten nur für den Zweck genutzt werden, für den sie erhoben wurden, wird damit faktisch ausgehebelt. + +5. Verschiedenste Bestände dürfen auf einer zentralen Analyseplattform zusammengeführt und automatisiert ausgewertet werden auch mit KI. Übrig bleibt eine Art Riesendatenbank, in der Daten aus völlig unterschiedlichen Zusammenhängen für neue Zwecke zur Verfügung stehen. Ausgeschlossen ist dabei auch der Einsatz von Palantir nicht. + +### Was eine Normenkontrolle überhaupt ist + +Anders als bei einer konkreten Klage geht es bei der abstrakten Normenkontrolle nicht um einen einzelnen Fall. Das Gericht schaut sich das Gesetz als solches an und prüft, ob es mit der Verfassung vereinbar ist. Antragsberechtigt ist unter anderem ein Viertel der Abgeordneten genau dieses Quorum bringen Die Linke und die Grünen zusammen. Hält das Gericht einzelne Regelungen für verfassungswidrig, erklärt es sie für nichtig. + +### Was die Beteiligten sagen + +Die innenpolitischen Sprecher Vasili Franco (Grüne) und Niklas Schrader (Die Linke) nennen die Novelle einen massiven Ausbau der Überwachung. Zusammen mit der automatisierten Auswertung von Polizeidaten könnte eine „riesige Superdatenbank" entstehen, die „jegliche Grenzen des Rechtsstaates sprengt". Und sie kritisieren: Es sei völlig unklar, welche Daten künftig wofür verarbeitet werden dürfen. Für ein Parlament, das die Polizei kontrollieren soll, sei das nicht hinnehmbar. + +Ihr Kernargument: Polizeigesetze sind keine gewöhnlichen Gesetze. Sie entscheiden, was die Polizei in einem Rechtsstaat darf und das Gewaltmonopol des Staates muss sich an den Grundrechten messen lassen. „Verfassungswidrige Polizeigesetze sind keine guten Polizeigesetze." Deshalb halten sie eine verfassungsrechtliche Prüfung für unabdingbar. + +Rechtsanwalt David Werdermann, der die Fraktionen vertritt, bringt es ähnlich auf den Punkt: Die Novelle bedeute einen grundlegenden Kurswechsel, mit Befugnissen, die aus mehreren Gründen gegen Grundrechte verstoßen. + +### Warum das jetzt wichtig ist + +Der Ball liegt beim Verfassungsgerichtshof. Dessen Entscheidung wird nicht nur über die einzelnen Punkte entscheiden, sondern grundsätzlich darüber, wie viel Überwachung die Landesverfassung überhaupt hergibt – vom Verhaltensscanner im öffentlichen Raum bis zur zentralen Datenanalyse. + +Wie das ausgeht, ist offen. Sicher ist nur: Der Streit um das Polizeigesetz wird nicht mehr allein politisch geführt, sondern jetzt auch vor Gericht. + +### Zum Weiterlesen + +- Linksfraktion Berlin: [Linke und Grüne erheben Normenkontrolle gegen verfassungswidrige Regelungen im schwarz-roten Polizeigesetz](https://www.linksfraktion.berlin/politik/presse/detail/news/linke-und-gruene-erheben-normenkontrolle-gegen-verfassungswidrige-regelungen-im-schwarz-roten-polizeigesetz/) +- Verfassungsblog: [„Try harder hilft selten": die ASOG-Novelle verfassungsrechtlich eingeordnet](https://verfassungsblog.de/berlin-asog-novelle-kbos/) +- taz: [KI-Videoüberwachung in Berlin: Verhaltensscanner bald auch vor dem Abgeordnetenhaus](https://taz.de/KI-Videoueberwachung-in-Berlin/!6160851/) +- netzpolitik.org: [So wehrt man sich gegen Verhaltensscanner](https://netzpolitik.org/2026/ki-gestuetzte-videoueberwachung-in-berlin-so-wehrt-man-sich-gegen-verhaltensscanner/) +- beck-aktuell: [Kameras und KI-Einsatz: Berlin verschärft Polizeigesetz](https://www.beck-aktuell.de/heute-im-recht/rechtspolitik-gesetzgebung/berlin-verschaerfung-polizeigesetz-2025-12-04) From 0291a035e945b00f27009e7475080b472c3625b3 Mon Sep 17 00:00:00 2001 From: April John Date: Fri, 28 Aug 2026 17:15:36 +0200 Subject: [PATCH 17/18] other announcement --- .../2026-08-28-normenkontrolle-asog/index.md | 6 +- .../ki-kamera.jpg | Bin 0 -> 374129 bytes .../2026-09-21-thiel-ante-portas/index.md | 83 ++++++++++++++++++ .../peter-thiel.jpg | Bin 0 -> 109880 bytes content/veranstaltungen/thiel-ante-portas.md | 22 +++++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 content/post/2026-08-28-normenkontrolle-asog/ki-kamera.jpg create mode 100644 content/post/2026-09-21-thiel-ante-portas/index.md create mode 100644 content/post/2026-09-21-thiel-ante-portas/peter-thiel.jpg create mode 100644 content/veranstaltungen/thiel-ante-portas.md diff --git a/content/post/2026-08-28-normenkontrolle-asog/index.md b/content/post/2026-08-28-normenkontrolle-asog/index.md index c7e76e3..a97beef 100644 --- a/content/post/2026-08-28-normenkontrolle-asog/index.md +++ b/content/post/2026-08-28-normenkontrolle-asog/index.md @@ -1,7 +1,9 @@ --- title: "Linke und Grüne ziehen gegen das Berliner Polizeigesetz vor Gericht" date: 2026-08-28T12:00:00+02:00 -showHero: false +showHero: true +featureImage: "ki-kamera.jpg" +featureImageCaption: "Foto: netzpolitik.org, CC BY-NC-SA 4.0" tags: ["Überwachung", "Polizeigesetz", "ASOG"] --- @@ -58,3 +60,5 @@ Wie das ausgeht, ist offen. Sicher ist nur: Der Streit um das Polizeigesetz wird - taz: [KI-Videoüberwachung in Berlin: Verhaltensscanner bald auch vor dem Abgeordnetenhaus](https://taz.de/KI-Videoueberwachung-in-Berlin/!6160851/) - netzpolitik.org: [So wehrt man sich gegen Verhaltensscanner](https://netzpolitik.org/2026/ki-gestuetzte-videoueberwachung-in-berlin-so-wehrt-man-sich-gegen-verhaltensscanner/) - beck-aktuell: [Kameras und KI-Einsatz: Berlin verschärft Polizeigesetz](https://www.beck-aktuell.de/heute-im-recht/rechtspolitik-gesetzgebung/berlin-verschaerfung-polizeigesetz-2025-12-04) + +*Titelbild: [netzpolitik.org](https://netzpolitik.org/), [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.de)* diff --git a/content/post/2026-08-28-normenkontrolle-asog/ki-kamera.jpg b/content/post/2026-08-28-normenkontrolle-asog/ki-kamera.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05dad4aa955428bbee4999754dbf38c070d1ff7e GIT binary patch literal 374129 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 ~JMa`#rb6HZzxC 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ŇF76#$*n%K|4{u>$Af=jZaL3+yKGw>^Gy41=}V6+R&8!# zyZzd<{bTXd=&X2#QckH`8r^Lly!F^_m|EoB_j~rmIh*xJx7>PVF@^jMYffw2{Z+bI z;YyS0T@QuaW5;LR==rhAd4-lU^SnoU{1=t{-Z$T}x@_n6n{yUim zdv)(2bF{C_f%%7Sn$Gpz>beYGL=sj2SA z#U~57H(pjr?ynU7E%n82?UhUUEqQql%QBYk4Rt!q(qR6tZO8tN*2(rqWy{< zyW{?%8!uncmi->5#eKBw)g-}9Ze6^d`8EL_^OPU#ei2{w*!FJz*WTU1OR^pNlcU5w znYr&xo9Ss6P_ut;+}6TJvaU{j+H=&AL{OfLqnV1*d^~rs= z#AC_Kn{IPEUG97Q`gQHd;uto=r>q5rTMJ%ax%N{g%Fn4GBzLQOaVhU=wpkC{CmxiZ z__`}Q;+jU&0tUVZPiAH6yj?OQW{*c|=p~u=T@Tka_OEcZ_{aUquE#J)GkNDhrq;zS zmJ$mp_qUzs5t;X6wc4^(QztG-)na;m&X=XYou%(yh}^QampxUEY58AQvYaevl}OGB z`y=d?5qkYckfH5$X{mK;if#@@{HNANxprKYXkgD;c(rH3rW49`951|Is3KsYaSmC4b2g}zt{8ow2w;Ll)`+{87kec zT%CXIWitQ5dt$GO4}>umxkVp-xAlt6seO@CCf}ERZC5v!N4R^pb;YEdJcm2|KEHxb z7VC6uO7>oN<8AoPr(for`7PqlyJwPgZd}@xGlwl!rftt#&bNiZ>?n7Amh|qK)0cTn zo7B1^hxdBc-b>v!p5G_03$Qs-7_67|Ipj&7hsiPq^&Y8>+1iSqWhS3gT2@`rJT2!* z;eOHhV>8!HRBn^!`1Iz7(#9uBukDNHnKnHOXmW0m-5j!HSH-Wb`@Oa$ibSwX+;@1^ z=8q;5Z$&xUe7j$9W|nBg1D@}HHe_-8O=ewt$Nb%zbs-OAzdYMjoYQktI%rpgMb0aB zNl~YF9HR3~Cni@4JkLF6v6^+}m8Kg3rD>b2f{$N$zb;QD*VSg@wleM4UB|*E#>E_d z7#-oY?3qJ|p?veb1snG6?D|xp!g6>{LhtFaKfMvJYAqK`vRj;YOG+&u;GgOFHyO+O z?nb|VD;YV_G_!c)analJzZUPi_H5^W20qs^DZT|ZHq5_6%vE#VE}iIPvt8)9Lgw+; zKArhj)V){SPYYCtE2y`cB!&s{MqywBEyd3)jO zkf+-|KAd$gPj=J1D?whtUYn;dKP$3dY7@d=`5uo3wRyYD(y&T<|#0|5#-&Puqi?C zP31~HCZ?Mw9#nY#F)ub1KVi)HW7#@wCThhB~>!H^UrVNFi1*smF=lX4ISlq&1?DNT>@y0RlmJ@Pc zZ5mx>IUc$cJb7id$3ojZ+b1q8JMfORM4s#9qDm!(9)?4kJq?aGxJB>v{&4qIeV=FU z`rwYuJ=d3iT>q`;XYJ?y${$HFi~edaTW9{zbAP+|rQHJAZ|>LK*MIeJiDYoVtxD(q zs*Sf+AKtQV%lwF$?<4LDADzm3Yfto})diQ%?Cz1dzN^MrYb34YkAhmI&V_65&?1?+SEQ@SVHO>E<<&qGt^4`Ia z&0}$RT76BSSLPONlR|d8W6L-s{Z~G}aM`3qmc#IUFl*VAHB6D>#kcng8SR_)q)P6J zzuHO@kA{TYmyS|eXWp^RbuNADYpA_yg+dPhQm23EiL1G9NKJBDXgYc04X%b`auFYQ z$o!hMOv2|tdUBuPz1hbu&C{0Es>{zxm6J%*ZV5hK)%RPIxs7qrgsQOC^>P9aGNd+6 zaIacjlst9f;t4C+FD>w%k?f-NaSp?R=J{7bWZk~`&A*b|{_c{m%pQsFm%pz4v2k@^ z?K9Of4m}Aor;kw+_HDhoWT8#JSF1{E{E^t%qAIBz>0x(f9nGqitl4<3)^?Rs&5ZXi zLnmbx+zTzS+iIbDIgV-8F+J`u19y|3Yz7fL7c`Z54u29=NsLZgrX(Jylf&_LYw-%M z^GbsEXT7R1@?&S(`TK|6+sY*=ukM@f(>6W$cm0>=JAYJ3Uyc7Y=fHo4yNS(z*P)Nt~-CkuZp&n9EfJV@obOQjgB)pOQwYde_g-)$M#>>CqJ8a z%k0C+%+m67gUd}a{A(lo({7~S+q%zi`}Y3~f-nC%-C+E_I>+*B>VJmMU1vI8GCF-e zX}fxBlAe>>T)R2p?jNrGb-QK1@UQmFZR-2JUiqWWw|nbkb?tq%tEJY5zYK2eVUAi^ z;&JEE&efJB4W{{Ft?#7guG*Zuxa;$s5ZkCfu9xytuCR5)Jo&3FoB!qen)y9dGrJ$k zt-7`4Kf~r7&#xy22l-U;AMWwiySroUihYU|Rde^Y1ZcWX_C9fZ?(Q)4!!BD+_kG=a zSx5JH(8p8HJY=TYHm*0X|6OHgzqVw>&1tId*Mu*MxFgT#ck{UDvuW$%-YNd8xt`5? zv)4dsPucs+OSA6Z=eG7-cYr6sS%G(($BMOfSFKVmwCvkda{K%ewy2Z4jY_?%yESS) zotIY9{JKtieM#Kn3ppwCehGC-Fk9a2Twng^*VN-rCf!+KcWKvtmsfxDkH09Jc)PVh zWz(Y8k9=$9Jf6e#Y^`EETljPdIoFuH=<9YZ_yX?3_}Y5mSOzWS@+;T+LTY_Yr3 z_J+RvQTcqvT-}3VSH7H2TQ24CU2Vbd3(8WvgSVbz^Zc})AuRT3w?UMawS@}DclG<1 zR(E^8Q`f%dc6;Y)?#g9%C${-4vHP08^wfr#>kB{W%{cfk`Dkpu>P$&l*CW%smoYf&%O2$&=5z{a@ppJRbt0nCI=fn{uXP{4v@_K5`!b2cIeZmo4RzvR>fE-7S+{)r7fjTJ!!CJ-ha_ za6@tL_EpzyO}w5(TiU(1`X#Si7n*up`=i$v*S%e-{30g~zcRAd+QQ$#X!=z1iohM# zoE!Jdj(dDEl)3h||5&-L?KQjA(l%8aQUchgU(dSoT4wi;yBp{XZ(B3A2n zex;M@=9wu$mh1&}Q)^fZgzB{XOpY?Q~#{MqV?q%y|c}B)=sEc}j_iMj>y|~dEcE|A7wn2~A`Yc%`ETZtS)uw-K z$tD9S?}C{8fRf!FZ{950?%3kkzt+2A=k}U9!4=ivW?>FT&Dkd8EZV-6qh?M(`F{qM zukvyi*UsGTr@idtdgC8y{~6xZy4jddJ;z%WkZ?*uwqv#J&abSi8c$p}?xEHpkXgRi z=<(royOtmLcGn`R^yy|}&Lyl|Os}}-$UNGyZ)xVY*s?RZ&u3jd@pHlid*`_BEBj8{ z$^V$7eS7vq-Mx?Qot2oTyj)A>vBLHFrT!c4Efk*q@^6%;U_~U`%{br`iIXxuD!n^`a#Z%waY&rT(|$B{C52g zE0)#b0aNZBkUq2N%_+Mb_jY>g_wRbTdePb+lf!Q8xKo$%J~rI(chIJ330CjjHt*ry zbZQl=ZU5pr{vXEgHP(XV0Kwo4~JA8F7w{1u+N zV)BkvGmiaO&YhoZn8T63(0-qG;fX8R!jF#fUSd3d(nj|`!M)6LdD@lFO$sJtKMEuGLE$8Vc2Wr^3Qwa@qbktYgew>FA>RaV{5!}{UXE8 z{mub#f6A;plCM>X2W@fSTN!8*!chL{dhl)8m2=qLdJm)|I0o-fei=}yGdFta*Pl!F zy%gqLtCBxMQ9^z0%AQoWtowmK>h3>0-I?=Np-($);*ws5V`pyuZFTNhue8_ZZ}#~+ z&Qn>K%$A1+6zmZ3V_CiLT&TAn*Bl%*7didjq0DB&3xy1&V0?k z<&D>@j59woE2Upo&N}sJ|2~U_3AS2}lQ-T77CkO~t;My#NON=JGnOkm-gbHIzHlVU zZGri{iK+otc7>jJyR4f*tvt}A-J-Hazo!n#eAZ=pnga?%# zl9CUutT#5F@R)s{Mx0x%_UhXv0;djs-U*uR($<(@7NBO5zE_OXX}LGUzaTa~4be?+ zT5|RTvur!kuPCWwn{B>2iZxftZKm-YsXZHatteHPVpDbHdtvRPD^p`OJZf%z^-b+1 zkM3%3HIc?oTMPDyZ1^#8zOmaa&#&tPcXS9V zn>MHPaU=^{)ED~(tHq^yGu8cy-rFuz^|anpZa=m1fv+T=Yut<2Fu(4rZ`X^S(wZyO z_+#Qu(VklV_Wk+6!4GBfvOG4o^yE<(@vYenrm*%V)uB)b6o4T)Ydsn?6R*~EEF#@t#wqa z*x>eP``McR45xm4{_V0vaEIlsg%h4I@lAeb9IRn^EW<(a;C-3utH+x|=kO}D1@2{I z3|hh#_Mq>o^~3fVjBg#1Kio9C)@AOMxXR6Nt=k5Xq70@7+a~|IvQD&l%DKr0Ou5{i zYRP`O8MH z39S9o3;)Hw%#!=hur#YwyY_5T%IYra}<*;Kn#Sy{q2Hg}2Lo2u_66>=x| z(lV*6oV2OpSq&v``@Tq(tt@%mJj-2fs*m%si7~vZe3fR;D_bVfqhT{A;Kj<4OOIwK zX=M1+UA3F@DKkMzV%fD7r`x>R;^s=PpHX*p!D**(n+qon?s_p{-!Heisb^zqbgrB8 z1YI)=wccQ%w)^Ikw~YaZvxJ^mZW5o^pp~d+**EpF*y#tGIek^`Hk92-D~y|1u+&Sh zo?)F;(fLbzcyg**D(&_kJO3*@wdB{b1hdOW)2?=HUQu$;G{&XOYE`-A0)>!F$=u%X zxw8+|zN(K}U0^6ImGGcWCtqhO`^_7-a(7O6@A@&Og;UFa^V5vS1@3zOrt_rs`~5Rd zb?!Y7{8#(foAez!c64}r%Jg`W>$$D$!SxMumTs9O+!9h|?-Sm?^^SnMdb573!nU#x zx0H;Z*uGqSrXnUorPY&RlBeae-y58K{B>0Qils&Ge_FJa#ZmIx%F^P4y64yo!^74^ z{_*`N+RdDMZC#%wpYwl)sM{NV2fUv4&h_out*`jR&n*ACF0uW&U-zuDlm1S=d|Ait z=ELn8QF@Eh_dP!HQTY41d8gmDajz9Tcx6}VG1Y#qTV6;Oy*~1t}B1^bmiUt zrMY#N*2KC@7Yj=Mxps!v{;h@fS@qJM>;W%r;}`0j`_`?tUP_E>=kdg|l`=*#k#ob! z%f*gg)8w=Fy0rbr>qp%V3*TS+rm*8;u|VRluEGzW&tCd7?eE^~H_un!FYVuaZ~N7} z)K1mvXP0Ga8;=$6GZ#nHCZ*=_7TdGcc$Z$On)@VNz?tbdw||G9$dd-MwR{W9*Qr|` zTw8H6&-DEE`fmb@96!q5yusci_`c!nzpce@z0$fLE^TwU@V+4B{6^{Uxqs)>F7p0R zd-c6fh0e3>duFET>$GyoTHKfEdRb@pV_}`&91o_C{xrXd0Soj-}5hPJ5%~|EWWYt4Vo3W&NQ6o zl&Q?GkV6trChU|vE_e0#{$)QSdLGU4EGYIVu)bP7)9`4)#0yKNy0e=`oL%yS_pfGi zmgQSNrGr<@k7vC-lXk^C^)#oNHJ_%_#9eL9jjx0Kq&(jWH;;FTv z@kz(Znxbs2Crd7+RdTY56-Le`tcNO_+-Ba}Y`ez! z@=Vp4ZzbpcQEtsC(n^YnF>1X;6;lHug!{NWtFz)qVlmjCu#3?-I`LYVAZtn zX5GH6#kHzyJr+{>W+ODI( z*lN95A*9dBx86T%`F9qhwy7I6EV<4`JzMxFG_-G z`M`UPl~KjqUiRk4uItJ!TilHA{i_|7v^bV+w$9U%`R02a)TS=2OmnR`o#?*c>uR%a zfnLAv_D|e!_}bDv4Sye5T$#_iFYDehL6g<88_S%R`W*;Wt2CJ`p(5wLHsh=ohe?m& zd66y0ChksIoNUc=Wm?@Om$|z4-)+=Zj1(xyIyqsZ>UYr~?kgEeJHu7ub6xT@AMftn z#N9maPq^IA+Z!*%_#G2iTo6&XuRdxu>ydDN1$Ulgi&Ga}bPMjuRDZYIvj65)kB|_) zf|5_ZMVq#+7fwoPQd4Ho zSh-arXz{u53prVmi#lAMtT_23ZP_w~j+2&G4s-Wwtk@^BDOz?Ou+6{{Kh zCLG*g=*-d(>vXu`RZ;f#qs7ato?pIQCo=sx;77Rf_RN z)z9OV&S#4(F#@T7#wEtkD?>Y2o0cdbmjV_OOqJjs9StKO9)CpI_kPnhLvy|wKxJx-@eZOmD5 zP;&LhZ5vx{q?TWPI$<$qsOZ7N37^9kyZByV3|_x^lG%&YNWUvNkHqbqPPv;zssz8% zSe*wq+MJ}i=-r0RbrHR*Y zlDr^u)0yL^3Xcj(Tv@e1Up-5x)GuKDRJYRVEBv;*_RZ!0H22_&BNMq>ogNwa1*Gp^ zmU&~vxn&ohJ-;>CVL@hzyX2L&6>7dg9?^~OJ+EX4o-kdxyyB{}G23B2e~2r|MMtO)fZ*gwtqaECt3QEwfO1zOY3dqk4$nZ72F`V_}c1HkDFUudEN^1>KPax zH&xLuG+xu^=xbpibKU>i=8ngm_a08Xp`m=jU$p9$jQbLvi3izdv2Fe6pz}(!^6Sb& zix?(O&EnN}Cs4nHmt$ zHkH|&Vc^sx+YS+m&p1*u+ zPxf2!CG#eJOugsyV$Xku3?Dh;jelR?{_!_;}sVZO`#lBwl`G+S?MQbwGm9M$Br1aWn4Xc%BFWlPPa@rXZt9WRRrjBrI&{(RlUGdNFZcfpb3*2)rvEWudeXe(82{4JYv)!= z7N2~6Z^!xem^D7(^Q&GhoPK&qPuJ&~d#|@2|8n(ZW%h{^_iL^_*o8>p}<5}*Oi80A_+01X{AFn>QF*Edd%eWHR0uv*Z;(M8WeGy{JQd?l6!At*DK597yG8p znq<;$EjTA-)&`d*hUceO?<-$sem>W1ZfaS^C*i;l_BqU3GbE+7BNC6#exCEqv_I|U zY$L-X+0(w;O-;Bf86AD%rp@nbHF14aao+7$S7&v3uhlc2e`;Y@;+*eamQ7f3@n(zO86f zd49V}OX%gE<4^OiO<x=c3RA4vWOMTg}^U z%UX&UymD&Z_ixLAN7LKaTlr~r{WP5WqFv?j>p+28Er**7K?%{P*q=Mbc1X*%uVt4! z_ElLyd&!gEmpiUA@b+0>6nxOe!qe|%8f%>*^WH_=|v*XrJL8w+=(OV};j zZOb(>?Q7hhDGqS#IRhDPY@{&De5n)%k4A4|CEPuJ!Ie z+M&blKaI6jbmG_Ln^WFK?z>~>reN!(fWd2%vp-Wd?WB2B|(COtL z%l(=cZ4Yj9);M;te}=qI_{4i(rQdg3o%*rJQ_k(u#GW4hrG9C9{^nHgoqOs|#O+hY z%UpQ&?Y^>8l-+HccV54Yx$r9gye5N|cR%iD&6soH$OZGJgNyAFZi>E=<@=idt0a%( zgy_?(2l7kH?3wQWoOkuyowZq2$t&K3O!S}ZHN9%bF^jzA7pty^y!aa?*Lo%B(EInF zE9V;jSbg}P(vSSN@(VqVy|XCU&kyI1*p}&c{wm%3=DVw0F2D419lry=xUBbYiCcZSYUluy@e7ZxDL5`E8vZD6@rTCOLbtxgO*mWNbmH<6uU9O^ zo+fGQkIm=5&tx^g>SXqM$>hE z;YSlf}`?Hy2KE%|ErT`M2qh{`FsHi#I=#n{B%G zOpJB!tnKqAN8cCw&+u<=iQ5qogter~lXrX6>)K?slc4Hbnl` z=3b4jZ69Wxdj6lG)o${ewOfn-Gsym(`^WNQiO%03G0*9p$rf2JcAbec_uav4HPxm0 z6<_8%rM!igjyEbTJ}I{(O;YmsQZIl1xmDM1=zQG0-SgEvjX&B}`MEDIr8b3V$tGa#>m(|rSf4TB$w*4>T zR(~u1Snm6Jnh?jk-t` ztuC4PVC&PB&ono&Z(Q@>+>gV{|2{jLmn>PaQ|{`KA32MwzG^-aKCF_vBlU7zWqrnn z7;o-6u>-%VuE+QNn^WEM$j@RK^XWPNt{OV9{j~Qg4G8Xf^`zPJeAcP^2b{uuhV7?+lnP!j(s;wB1@Ml8lF}X?EM(vai&F-;lca2 zVd?)=&OHCf>$FgC!_^J2@{{n zo{yPnLQMVgXAIBsO?dEj`^L5VJ9Yix{_u5N z^SAn|(|#{Gd1;x|vMr|%&-*yfwZy8xpyJDVt(Uf5dA(PZ_Bs^Gopby-;q%t2(>B42 z&gUImG_h2fk5}IN@or{Gi(}Iln`)~rs{k*G^($Ct?p7hB&W`4XT)sKqT@5~c_>?>t{A696-$9MU!tGDyJt*UuE^b+l# z1>C>1(=?VjD@Uj}YVM8Cr9b3FfAziN+jx0hh>7{Pcl@~#tDALKuJxZ5K6(Aey~l&Muhlx#{^+;3#4PUa;@7>|zqQ~zFU{JZjc-+zXsk*S4yzS=$5q-pl$ zz^_Y|Uq#oZ|7WNKAPB;1D`NsBT@GK$DJ5uZmk6GNC<}2pP;>Rf+ z)S%_n6Y=(ktGI5L#X+IxISl1%7Yn&+Uw-3p=WNaL*Uyq;V^6ZBoj6;pY8w4T^xbvE zjsF=+&z4MA_|d<;>Tz<0{Izz+1P|+rCpZ266{2+`=h>pgifzTA>-OK-8l8UL)a&d1 zmMa&Z*GrhOOf|px>(zFhq9V^#^TqcqDZID-4};e&Cf4+6>o0GgxiuoT$xQ51`hNz- z^^!lD9^HGtB&L1B>rUCkiuru^d|oPF+S|P1j)Ya{@7#&mn%{m(?eSk*>LI__E4A_3 z^LOjks<*KjEaCn8D)jlwC*K}aXnt9)y-)M)x7NBTE+JR>W;uEs7y0{Ac4OnLj5LOI zhEBWZuK2jsY))agL+0(jS?0bD4etB0(hi)s+F+&qSe@ydU^!ypKq{z4L;onkwm;SwC z`$1l*FZOh8hGc_;y2skjePzF|ZQXwCZ{00nY3b-C>4qjceRxvy{MGkrN-`Agn^d)cMaLQJ*3HfcJm#4g^x@BB}+ zG`Fx&$Y74wa<59i1GDaLE{G5A=~}Eh`BvQdT;cugB5UXFytn4inR^kp{r(=UT)k(u z>CWs0ZZ&s!SKaU0hxvlxhXRK|E2fwYl z#CBeCb?!5JuX>(v&X;>bBQ`!g@av*h=HsgQ4&N7j`1T;|=gMUJAKjBG)la_-TU&Io zH{!&N$6MVC1#=qw{Hv@3l6CxU^*z3{bfs;_iLj#PhMmd1n_q^k&x<=3Saw3f;NrGp zTU5gYeNNq!@@9OMJ@3^#-S@sin>QI0IDA>I-RTl8>lo*`k*D$o^X+?6=E?4DzTI_sd_DbQo*!6mNWR?dR{bYpt!nQfEgLJ&j(PGf;>}j)KW6tAeR;vUC&3_L36tN|e{pE)9izP z)ZJYcaqZQ!vneO#WOmiB&5XJc`6WAEs&27PXTP@BgZ}psvcZpJ;wmQJ_OsDfWU2SM z*uLt^?HiX|UrrCMn4Ok!ZmPVq&wqxs=`X{Vm0F+vw^sFv*lF7hp|M_%Cmc7u;&Vxa z#YNmEZDka9#cZ>0ADw!PJFal;*Xg_VadTzO9lmVan|0H?+BEB)N@g}&Pdn9MzUr)f z==>E2K1Hk%bL6%*X;yjMwXwEf+9k=QVVC7ZJ)TVdH#K=h#s1=o$BL>Y$2=cxwA;E= z!&uuXWcT8oHIK8lypY)N{AF;o+r%hmi5qSW0m_ZiTMAw!A6&U;@_YtK$=J4XhP2&_ z*2qj)yDsMus!arIckZRW1b8J-rsMy56AUq*crjCK+5 zZaY7___cFc%QBIM=Usayx=U?fKV|XN)M0tI<<##74@e%3^htHhx_DY?XHs?Y*7&A- z9;QM!&)qOpa+3<5lRJM(XiL)RHf7V?YbhINerK6E)=pU66mrt&^@mhD@S7VpRnI{jL zvNWtX)%^3~q#k{C(ZCJyUZ41$Us^M1*D=3;Q$w##UCN-fQd&Ohy4<>@-wj{w=Qz7I zp!o#bUZ=zV)@*$u&m1GRZR`DFsjjd4CjDC5TKk`&@4eJdd!2I|t7ddng(Mx=amxJC zp8JoblaglpU)!tlXW5SVow`TbTx<;1%`vWjeN6xH#Vg+b8LR>{7(RyoQ`r7{@0lDn zH?P0i7G{6aKd%R`*I3m6fGK!Y7{8sZyAJSmAS*(gOyEdu?SU%^Ej! zvd>!H?%TC7S;(cNJ+0=|IjvVc&8xS|eVv`Hv}TEQ(~TR~nkGF~nfzttox`(Vs>PcB zoN~cqSHbH!a;{!$LW{d{Gq{;*?oBic7`~9>HHhy(MibLYXN%3mBMRhqH)_%~RfHAhPb1#(c9^oOXf10yanc7#=N{ z>v}||nMMAH|F5tuz6y~Bbx9WYlLMn~spuSF@D5m!@xV@-M_)Rm*(2eMQ%~`%Sv#5@ z$>vSUlv9Yw(|n-hF*Bs$K!H}~l3>onXJ3?7M%8cbRGT5ndwgx|*Pf+ZE_{-nIUyIs zCaHYxJ@(*pfbOvkmz|DY_cO>?va9W$>eQF!^>8$KRsti_87l{ceSc={}0Dyy+z+9t=aGTK5l*6^T5+P zH$E5lv;S7Ugn0wclm85lRu#zlXdQic-u0#TZJqnm|1-FRX4qvMYA`(a^-JN?V^cU+ zxjMc+TNZ2D6TlkWcDZNn>q(pcGt@McThI4;@itAcVduH8v#w-D%tR9*JyS7{mF#;ENpWy;r7|GsG=+A~!>_w}Uz4AT21 zrcJYMQBHMnhFSmJeeAd^uT7FIjMuPKdUzP4r{5q+C&G3E5 zCyBI9j;l>Y{H6tSlO59{WmGaBsds*6K6dA?R%ZU091h>C-8tpQSFBktekyjZ#Ey#_ z4j$htQ&kh1DX$n^{HM7`K5E9DcgNm@XG}$m!pJX>ot`K7n#jokhyMy(0uzk-*{>WInxy3AbThlGhkZqJh{uKu9O2hSOvyYh0W z1^d?(87(>C3Ownv(p>qM-<~y5`egsD376iS@|St*%HK5KOQl`+Ea#_f6OPE#h4^YZ zu1LPrw7IFrQ93xWIbq$sohxT_N_=PE%E>Mh;N&*(bK0bpIhmH~Usm#&JZ4&CuWu9B z#dIensbx~(HoGlvk1`hd{l0KzpBmfa(_dGpN=1ksoBS#>MX>M6k91#_=d!PJE=x)@ z94^Q_Jui!;fHSB-{MM3_pYyaW&UGKL{8?X>8=~#+W727tr+IjS(ekegFHbsrYlbHG zKF!X>LX(!BH+hu9*iampo~7VnwQZS{>4Xn%|8_3==>GTNvFa--4MrYIB6t$meqHAE zfAr*I*ZRt=>77fjh)UZB9b|Ee%eXMK25YmNEyuFc{>n_hJ; zz2jbRm`5VvUubDV^8RJnTA!Dz%;Y)FY{8}VxIK7Xn91E+$JZ$tt`NR&YVP-X_2u>c z0nr)PGN$~T>sGh*{F3iwUOqvSdVj>%{AbA8GS}@|I$K4YCf7^7?jvyUD>Uw8Mr z=Z|BTUPYw75;}9)S=(UZ6ai-j>#Fe7{A;^vAEn)U$99}KfaTxTN4%*rtKy`$ObqpA zm6lp}$x5&2Xa`Gf%zuVno5e2-$|bZMzbIUr@4Qzm)=ixEsk-O-xetG|uZ*&q@ot^+ zajtfTYe%Qwa*x`U!yei9ex2{|p}IHYQ5B z7hZn5E;)A7frW{$w-v_f*ngR_=|to&o>TRw3zq+Sw0^t3_^K~uOuyG^TKs3oX8-CK zSmT_YSf6(>?pE}ZtsWin{N+J*m`#D?B0&PScUqk=XEMSn3tEn zo{^vYy72aigow*W{O5+eDUOMK+kSYnA8&j3-Uj)pdB5v=!+!1gwtcSjk|_0vM%B&k zy-V&qKf5(@zQOLERefm18mmne;_OnfZujR_UaDPGa(k(L^@c5b4jyg`*!e4TcYN2s zbETbn|D>%hPwU+BZ^r5^|FnKdKN63g->yH;EX=)O)5K%iZdboX9k{nq@$c%B)8B4> z7`e-4uAX$7~G&e^Z^znGu9WcMpUXB&U<&PR%2 z(y!#BX3R4^{dY-CnjP=i2S8} zllQw;mw#0BY?Qq4SmFAln$QpF2g-|2KXdBIya7Mb1|Y+yIjciQF74tuv^V3*9||$PKXqH8=fW=E!$gi z)D?TSOcLJb=2n|&8@zI}T>WyE#(h^Kdz;JQYfYQZRp!%A-9hoE^eFXYIJ3vfU;D($UVv6-d@jz-c82N0(%m8q*8lW zO!GVzPd+<`@kR(sa;p4VLB@iv1M@G0)~#iVEy-K7%j4{3gYQ~qtN%&W9Q72@74Ky| zV)64~0sFcu>Py64=`AMTs=rs$Aa;M=7g|C+X# zY9vHtKg!~bX#2 z-m%ue4wl|_i?^;1H(p_vxca_7CNQvZlCu;O+nj`pt7ft-TAY7vuHRIx1BN#8UL0Lh zE-*DLPpZ{8wVH9`pS~++b{%UzDw4e<zJhX* z^+_KeCRrZK>|Ce6CQ|i`j+&0~=DM12?t&h-MKdb)OyWtl{v0>6mSd8nMCI(BYG-v2xAYjFAHCohGBAKiL#fM3;8`M&7$ z6OVOT1Ww=Rt7}_V(zo2)?bWrrUQDG26%IX5;y3LDuicB9S~BVMiQ6Wxp0G)$^y{ik zlU~yI?B?eDqJ2to1$<9xi?^~dNSa*V{B^PZgph5|FZJ3S_s%H{T)k4U?Z$Ja{(ONQ zDjWZ@3LWVv@sgh-BVV=WiKxWmTbmnCJ>S1Hdg~PP57Jf*H-26FSz)jJ=<7y{tj;sD z8eL;#JI{SpU=cnT{8OsdI&Is}Ta6ctws-6}^&n}rcgLqC6B{=^TkGTJ^f)*2tlPb` zU!UK)mZh~+ef0NT9x453U-EaRrS~RC-1zv~d4(S1Nz)Rcrs_*i%a$ygVQ}!-ESA*v z{Ywo${oBL1*Usa?)qQi*ZQnj}&sWJ*oAhf=YS~xOl-r$G=bX;kv}xn94Sa?DKQFg2 zJPu^O-G6Pjrd7yXuOrcSjT|*{pENSEEqS@uESh81J@5T{-EYPjnEYp`dVT)L&+UKu z^)&K#B+e^acxd9SUD^K`+TW+`$?ouN>EIJnGHL$0{8g;jDeJOncC+3qJ=bQmi+>+{ za9_Ro9cFGhZfQ`|{&^hbcUl%|cbJ z6Woew&6fA1uF!XzZM|uy{6W+8*A}(43H`Ba_^9}w;bZ#m>&|N4+x*Jcgm#CAz1XPn zlcm4^_o8ho5)=D#uIuKCv?Q(mk!o5wbMrCRh^lo_ixyQauk&v?d~4m-;Qh)6vzpKB z(=Xcj>)P=HT44v$FKw*T&vp2lUHqV_?#Y7hqLx{I&GxBJUGyV+^{KV}T!$Y1eEuUh z-sm z(V@Fx|3|5aJ%5!#6&WNJEm?emy(Z{=L^kiTse+cvRxXps-*_Wnmf5{#wv`qB}bXZpTu%myL18?>H1K%!IguOX>m~jQq&+Nlh zBC5ZpL>(5rI%l5o*Y#yT^jtC?My4t{YB9)N&HdVQK54h%yu}r#ZZ&(|?pnL@PeOQt z<+90U*M*PtsMr}w-nKZeHq*n{B6(}2Zq?6UxwriuxI}0~ipzU#E##QE$muzkLCL&q zGsegLoZBQMjw@|h6Umawd0p#yk>z^(xY13fsYO`{Z&Y?Dxd&YNl#7Z1^#%LP8 zHZCUGCwJ0~J@1!(mV4~Ke{aU&?=#}=oJe*}J-v$Wi_1aXGoK}*JWE<*P4`=BwpJT9 zFK2Z*^HwfE?zr66_=nG@u03>T;k8v<^Pkymu}wQyw@`KI7LSYTYTodRE*9Opb&;#k zoEev8o?QJjV^UIoz{}&S?kwK5SatslZNC2uQ9F|hrY|`3pp~8B*X85W!XrI=wokt| zMQk7AH4FBvv#-;FZC{I_GCI@1$$LKDZ(_v5j-i zalwgh%ha!JJexcFT2<-YGrYyAH5YssuB2Ex_Ghj9@Sh>z)pTFm=>egWG9v0F-KSo^ zeQ&#-uHx>khCWY24_sfIb2a<)ie0tu{kLyv;h5#)AzB7H(c}7>bn$hvTUESv>J=Q2 zW99MtYFkRTDJ?D+q*3<4P6Bi55&(kXQb>QUOCK}%8C9X2*#D+C#$!sN=X2B4xyec9 zDsQ(YU7Z~2G*x41pY`Pzfg7CM*G638xRSwnJ9qWGEo<(@Yc>B2$!TO0E<0YeX~mH& zQ|Xubo8G%#HJVqnJSj_415M4wPqaege+B)TO`--{Biw1L+_{m3`+IoE^AjheqFv|?GvFx>qJ(3S?QX4 z=I-jLKiXt@9Pfnts0Mkci=HoC;J0Q{_HyIf;;-dgKi04s_cqjAH{fgTJ-7DX)H^ka z`LioeNWPCra45L3e)`Wn&rf{+ryhMwQu-WwepLUe6H43k*bes;2WvgNLb>hYeiy1Dl ztlk(rp-l97smB=(_OO3brXG?vE6@mynCmPdx8;-B!AK+CbjG8lGHVrB=CXfX^2x1u zVo%itwRX+y)``s7_;nF)a>zEWdA_E+$3H$$oG{lW z|E$NW(}MS=OjgR|s=Vv8pLLTx?Rc^+-=-$fw1x z?`@rAuWe>?_V=~5E#H#57yL-+4Owt9X-SjVl#W-c7f(L%WwA%oN_K@==a+3Xuxc~q zkJH+6$SgI|uW8w{r$u*kV+|M5VWgU5qkVFi&buU!i_9+f`9Ai3f(*D8iP z$=4>YtG*m8Sz9F_cQ5euGt=&mQrz>~cCArw&Q$o@TVfmQd~=_hR~~Pwt4w&{nBIXr}HHKW^p*rlvp=k;a%muHKnVKFIOFX+qS%9+k_=m zyEUxqu8MG&^1qA^i=DJ*{+{f}97oZ$%$YHh_om%kA;G{L<-)LI&AKJ?p3Zopanv(c z`Q4ctYO53y%2zArm91>sw9nwxe}>|hej6vHOnAv`yEpsXn#PY#6F)tk_w{m3qVb*h zABHcFIM<)=dVWzwTua4)(c*;Y<(V%}{oe5=XUT^J?2-~IqiX9Md%v&Ru)*6!zH8Ex zJi}R^fBe24S(Gdi7wv3&NBG<+i8|h6*+%bI*au8Gt*B75YX0k}*udQ8O>0-}Ioejh zZ#qw*x4XxLh1aoob=J3n=ha`k9&TREQa}A)$-U&MpQ=KRNhVu5sl-2ve;cTII?v?V zj7#y;(T8n0KW0QN9%bZQgr(GpgPIxhh{Jywav}aMzRy?V$Zr#W0u>M4zq2Joi!aagrGd4ZC-X)Tv z7*MI6l=XG(t0_|3PTaq>@o?JQ*lkwZ^6pJJ?pJ;6!=BRoUvKVl5NAKuPv>e|0H6Pcdks@ zoh0hsK53PQbn#iA(&ta}UCpXL9^WeDdw`|C>Ui7NBRNiUCO%Cn`>S;%ywXL;;7aAU z6>raz?OfvAewZKik2<9#PqJ%QRKyecLr`h-UhvLV`l4Jbbb2cF26U<39aWPMKyb!dU(%Q zbso6fbHRNzdlgd=r*`j;CC|C|t-r0fd0hJ9xl8AMymgSbo~qQcEu7)9p=x!l)}xG* zF)2A2q1)6iHT3kp+*IVA9OY|zXvzc&yRgUqN)lGa^nO0;sy~x!9=qHZ&Z$8=7fWqi zqxp5|x`jLr>U#}pJ55aOHtn?SuVT6v6H;|j;^a|l0nUSGgbJSEt*N>awZZWGQp1UEhl^insVy~HXJo{_*6MWQ@%N#73Rfm8`(;_G zU5I3pE}T=u8nRbM^7AB4l`F;GpL$*W+zLbEYCNS{HT)dz>)iYCHsJ4rX@`+OR>{@6-h zoT`u@xGk${=VSD=QUF=IXnm~`FU!GjnPMMMUT9~eVQC6j_vj0I4{B&lYXz~twgTs z9(%otV^?f;9_2Q3%#qR0kBZAp;k(KxuHiSy;~lTTfd?8#&F<^{__{Elc&Fr-)h|9R z`q}XI*;!TPaCV6U_xCC`_B`LK%ItZ!aGr6vQm)a)1NT1$wjDSj7kutdfB>6j=57Cn zi+H1x_?Akp460O;>~r&K;o)^>*6rbPjAmd}ncQTnIkD_N!_|#f@Y2NtN_9(w|#u@ONpAzett%s=KVxtVV|N*H*^-Ni}_K zet*qdy*uyMxt{!+%^}8;=y05A+Ttad5(=O8O`Uxtt7fm;qtbg*6$9;EnpFN}bO!$p zxe)uuu1InBD>2;@7mjX>`DpRH(PM6M#JdG^x3k-X>~VX3zCQ2M={0c@)m!!GWC;Y-3!s}S*-sy`cu+B`$Bt<$wyy&6MA)b z?PdF=A{Bifn?C%@{T){CFjsov&2_B)E^J()36Mdha-|Bkg)#d}KsGl+3${EDtG z^jlsf>)Q5PO5hEj+3KFFQ-fE`-M+}kwb za?WF=&W^;UG7(P&-)o(E8~#bS=XGsp+`9M3#R=7wXJa#B!&S15hP}{!c>21+W7pqi zwq0$jpS)pv@GG#C^XkJ*%sn3i-v=9M#`+a5uX!%NmU)Hy)yd0cf<;b0Ib8hKc{$UP z0F^s|ng8TYaj<`0rO4%RzA7z%GiL4&yRDW14wnk&6<93LvI}E*-0XTJaHc`Y+qu2z zliq(UURN-&7&CJP-0?z6Wm;Iy~+Bi7!i4 zEAsOKEwb@l3-yi6eqjZY`^J=%Fj#j>}P(eeJR z9XG!GiQUWm=K0DW+pgOxWlG1WA8n9-s;uf-%45V~9X{#H>6caUf!kkc6(rSc=%42G zb;~5{-5&1~lCFK{k~4e9zJIUbmpZ#`jAaZ=g>UaIWoYA^Q1+xSkRgPXS>ns$u!JJR zuC*_kA9fsg)GM))kB`?Zw6B11>8Zwh6Rn%{FeZqFao?4n-y-U-;Vyd6usd}LA0_$eoviV_Vu%MN!P2(OSVnh z9AoA2@rbEGPin(A*|UlKTl!n0`xYA{pD^3RWUr)czr1#N$;r2~@)l=TCabu6x5g%H zU+{i@o_6=^zj@bJcKmy*9W$Z$aZKczpvM0U0(SXlLXSMN&0hY;`Qol)Vy9Q#im|+z z9DaE63z7E$cmG(Y78}mwx!}24W#JXRpAW82`J`%}ATeM_xP z*(ejT=eS?>p8pJMi(~6<-EN$0x z2LwVGZ;L+rsTO|wKZE?|xTka3gN655F25gEw(Nk~M7c1#rVYRNEC7+lvpQAv-b)`g%J}1Bv;6bQ(%@_N zQoLHs47XqF?ke6da>ImO+>}2^{hhh9x|GS43y*EC$OcSIwm7cp{>nA`%emi2%2dxE zDU&?Lx@DI8a?uTLn+`nM_;!PxPN)0dxwF$h*Z&M#nQtuh=w-u1_O+pPS!dRGybbkS zw!%Z=*@~|WHp+Wrsuo_^eaT-;%Afo&ek88K|Mz}@eMn-wj+RhIr}8Sxpi_LzjIUqE`~O{H8Q<_v(e~_O{Z|hE zzJ87=JI&R&Vxvsj#_XUf&Ks9PkDL5B$6lqdC*PGl=hCs8%O5=6YU*$#SgP*P?76=~ zO{E)OXjqym9{(I5B~#FHP2>M7p-f4_@m+FKWWB^8i`+y zR=FP*pXjLKt^87PQ}v@gj~8yNp3))PaNkrVUf@o2Y4naGPqcQ1*tTkYmi;^3*W=gw zh#iyM3RQk3f1bm5?%wPPTBjQyPZD`4({ok6&8lP1wk9>zcM;iB9$$HqAO4h0GbO=s zz3RSuD_ssvU3V|i7I1*~^eO)Lw+j}QpDGw8; z=;8IH`;xA->mB(#Yj3tf{q!8ZuXBzVd^Fx0yYaMM$z#*=D<|%Y;_$T0vt4@99yPju#-rgy?XUoBj_vVV9c5N{75G`~#tvjD8JX`0p z_MuQ;_=R7g;SI+d&fOEZ&t-0EAUQLk&HZG80fX$TRnd#RHtM7{SRM0cTXUi<+>ND$ z%R{!6b&h7?f3<$U+hP#Ktox+@S?~|{YinH7 zu5J6|snV_UN#^wz(WqAv3tstZoVc<>-EwvKb+c(yp|H{E~s-&^ovuA}KQQ~7~4*S3{SdZxXlVDsEa>BqO$m$FVh)LprU*T2c>)q$1E`wfg!WVz=i zU)!k1adcNjGLL}9!amKf9zCZ{ot=7X)#1X&x804h6;H-kJ-Bk{Yt+q%)hBoIGi_ zWhhk7vC&k)QBEZ_!MZl5|Cnb2m+ke2z+3@ICM9du6(FThC4nZ*6Vf zjX@`F%@LIg{rYU@jXT>ol#|b~G90)%vFBr;er|H} z`;aAVM#oi~uU_C42tVgGi&G+3s^5IA_3fDk`;=F_eeYMwR=n}JXsMJv+li#z^Nbsg zI{*9nR#q(3OhN42)?-&6*7JM4zUDl)*)3@A=7(uQ(QeWk-o|Ht*!w4c{!ioI+11N! zemQB))m99_Y z&(~-6tN)m3EOMekBfF``(68e0y}inhDjKdBZsS;Ql9W90!kmocu8(yk-`A%)S+W?$;UX7PxP#c2BE#e5uC4H~UM_>tv}- zFBJ>VI_pewHx}Ps-o4pRV zx|Q(c=6P3h8~coIp3~Ch$>Z7*74pxZ?5~!a)O62B%bcp*`cil&g*;Bu65CU8cVgdO z?FrViwskaQDmRAw>Jfa^_e7vy;@F-yS-<$wyF4ZZNxID8$y^sHc<%?VEBeigwTq6j zWqnd}^L5N`Ak_8dq<866SwYT*+Fk zH{zMwW&eBPuVY$XZa1m0sB7p&IJjr?wU z%|GJtzOO5#+j{-n7*5=;lFVcAekxh~KJt*8@5j$Fx&DtO`F@;GXO}peesHbyADhV@ zmuAk5>|66IH2Gq_ur6n~yx#5HFoiucn3m41*`e@${<*cc1RU=Y8#Sx@Xc3-lGOJy|=m-T{#un zCd26BC+_jHZuf=s-d3H|4~1POGgE85ijNANZ7Mo!ajY;v&*^D{$dks&H~wu=_dIgE zhv)hAtQj$Fp}7eOKie!E+}&hQuQgZi=1ngH$;ocN zb0ZT!9=qZbm*By5B>!cw^xPXa#b=iCn7xa+^5~;cxpm?Dh^W*2{K2d_S+f5bl!Mm1 zi`jUSuevb!=%t!%RvK!Iks(~$^Paqm$o#Ud=<>_B6RewJWaibLdgyQziypZ;gK?Q-_dltT&9x_bk} zW7a+CE4-a0y8B4te+HXS?>nmxZYrGUF=5e4=_bJl?JSEMd|LjpdrqA`&TeyAsAT5S z(1P~h>PymBI5l*8ze%!hT=el&{_?QDE8CWpz72etU~|LXOLc-rIZIuMYDYjsruqb4 z-{ALck6$~KNx$#&&vJ8MW<0)^ZLLG!@giHTN12=fh5?7|mQ7padGP*TZZXC7>GFG- zh1Oh>>21(rSH3pmSZ}0X;lzDkUW6zxJQ48t&oI|1LTFFx)j3zP6@v_1W}TbhaMaM$ zZd3i;2fx-A|GcneV(ZV6{6kmjG!%}mP_8$#^J+LDBJShacRDKR%k<-kiUrI4)^E|_{CuWZS# z$a6DJ6dfpbkZI#F*l|wWQlU1}>~O#_!_^Ak{(U)?Yt;~1qp&Jkp<3|Yltg(QX5;Ty zx7m9MaB8p4b?EI+_A|-zI=lr*VW66O0Sc=jLV-lzYN^8EkfwXL=C)d}32!twg3sLIFnRgN1@|2ci&t*^m-LoNAp=92II93)jf zZ&fk~-FD;AM4pq4{pVITDzk1dw>>L1$&cgj%k4Qre(uU!?U?iYUpjMW)@v|4`Soam zRdMsDxi2RdS?AuHp&8_H@cbE#reoY~%mEKBGnJ+0nw(*@ZYXwHY@NbWb%7&(3in`VXl%-OxNDkOcvp}~?}j5G?5EqW z+%99UDw1G7W;9dEHsi{xJ-gfg`_^h)}??3+2ZGZDii!bk`&ZLA_cLeW$TIrJ58Dzj; z^^vdl}F|Sw=^8}W6Y_(d?_Wm#p`e^^ivFfRi8YPD|6mG^s4S2}H#*{wOpw=o|4wzl%R-hScP zU#>?o9#p9d`KexawNI|(;g6N!D`K?XvBsme6PykHTxb6k`Zlum z;H?b{_GkQ4o#mG5I_s=Rf6&tXSvR)t?!5DAszYAwsy9XZ`Gdc#z4raZ_1wS;L za6eMG`e_Q=s?zVhzf2z;I_%&$XYRRwQw#k+JbL_u`*+wj!^i2j3|if%_3$vb6=X~i zJjQF7$24(kj6*|6PO;zW)|-tdzbsSVpQS&|^iFP|)5HxE*|q$Btl8gw`+azA-Fr!) zdlg##i}bX!*zC0CGT%&jWfv!Wk2@$dC&_7-AefA92Ux0ua^E8Zv1+f7l|F%A-y zH#G6uoz&GUVrXgFeoZ98xw0TU$enrLe+I8xaejZo%#R2Cz5n3fQmct;7YnSg{p@wP zx9O(Z3$yL4GM(3Tw5RXhHc96M`&66dw#P5+mAkzBc=m-|Ia)Khb7pNmsgjpH<@L7g zyrX^o4|Dj!uWd|UTl(W&xRu++H`?2NTfIuFSoY%5rfEK&dC@mr8cuuKrPf&!P13&%M2=?|$q)^>xv4%X5!!O>?{V<>MXq%GCTTxsq|x9mf{_ zS$l5=LwNJV_rY-|-(@tX)Mi|+>MWBkTk$UM?3%rnf~B)(&gA&QP=6*kY#md`YsV&S zKN~CU-otfQXHH)3DgCQ!bD|!5o8OV#sOQVOKkc)fEtV2v>Qoxq*v3lPk`*Ue&APb+_`@p%k)w6V}FBiKWUSYRrSANTt zzsDZ_XP6bke`)8`1INBzs!=UiCOtc*;iTHed5`zzKl)v<-z@rLO!Vvj4Ezy)Jd?gn z_d4;bVDs_M$780z|6@93wPXkT)JEk3?ZrR3A7}S> z3v(O;xuM?pkeYEx%ctbKR~xcU_lWYQ?B}X zYt<4Drk+`!_HX*PXxrYR=gWPSR^2(eR{ZMq`md(13V%*d(z?-Ao4ci?`|+J4r}(e! zXup}g>Bqz`CDHw#H>tmm$=UHH`{bv;`@a7;`B#_W+wIr>%JsZ2Or^xtJ>?$lJbrn9 z)E8@sFHwgjZ@Xk^o%<@)WcDQ{WL0(e=FXQto4bgYdU@YWA+5QXol$5Yp!ix zH|4zgtxdlo^gsFsC%6e+Q~dR6t@Hb>g{2M;5`JGT4wGAG%90ymHUIbGFKgM?+*{(` zcKh3+$EW}4CazYVkiGUth+xuwugCv1ZaFOfxq9=D)RG(PvWma14%v4pMf-z%%=wB? z`*7*&=gzdte_p@P?y73YZ~NEm)>Av`f4Hunx54bz&TG#vWM(cgV6W0@;8=Fa?B1Ma z-w@8*y)XRk1WL(gDfqfQ)^cBWRq^{$p0vzIJ^b@rL_W_85!Q}?<*I&$Kd)PVU;F7|3w!T`dDd5db4s2#sG@h{ z(F&y&n@JL(uML=gmZtPfytVQA<-lcY8(o`UX&CIPzA|@nTx^Nz&&)YOJ47NyB-NTM zBb%Bo$?%EGT-f9DX>mH2xWw1RlN9_GF($s!NWC)QsiO|x?F(*~w9aii%;M3mZow>b zwOZ2Yz@_J0YeI6*@}AK;#%{GK<#4U7R(6M=jYM0Rs8xq(p=sl_cXxk1-QLKupdz)# zX-AOfWBa|aTe^L(%u-MIlwd44!LDic%9xqIuI}AX+`-;;?`LpV^U@`s?k+iFV{v2d z=DlVA8D5>*`aW>NSK&;Ki9ITvDy0XqF74X!VNH~?c;C5_1~&(h?+Gf&VBb{J{eH4m z4;%MR(3vD8Jom4rvA^tXKl z5FLGM%K_G_2cLWl)p?gX(dRqMuKC}qYT4!2`im`%X-wT8sPgcl+au%quY+R@4l$HG z_@uSmXUFbW;=+42&PeM1Q72bCIV>&YM9@vEO}4z8P7!WL`%=zbIrXGd;`66}A-9?r z)(fykwH}#t>y+~*A(JOzJ6prUBDq^*`_A~9?%L?o+ka}7QXp58iEOL4m`nTV?fF%A zQ@$5<PWwnBj8iFWNiRJ?Hn8Rqk!!RnxiW`WY2&H4;63ddHLN_PI%$4nBNU zwQeEjoSU+fHol!M>*B$8#!PZ;*SG6aj>t!?tTpPGDG_>VPB+q%k~D5jy;E0ee&}zQ-)4!*gx`w= z=USeB9rc}?XJcalWAAMF`AdVhy!_~H?3=PoVYx)yqwQz!6-%7YO|>{a`&Oq}+La}L zGm<2IWY0<-N}a9JclEfeOM{`s2@%iz)&VQi4j!NKZBfT+v6y#!|E^9*mz1zrDZ!*= z8gHiM+Pm}o^h>K`1u_$F%}`LbxD)*H;IYh$8=`CeT{SE@B_ey2W1>o0+@nR_3$;C$ zw^)2RE2QAbdAGYLt8MqCjpAJXmuH=y#MwO4guVOc?rY7KSKJjozYW}NQFMSu>e@8p zx9`4aR?2pZ9h>hp^W8epnib~%vTEgY`efPa^0YD?r1&*sV7 zCjPpnAKi1bGGF6C6K|GNY)a02#Z|V2HQv6Na|8FeRbPFoJ?qD}J9lg3>lX-}5R2hY zJGox}<;A(o(tWksx9Z-@{+)Ae(|?BDv($R`eljzCA||$GnMdR%<+6_Lf7B(9@2%c1 z_k8*EC-b+Ro#N=!xI;9hd8;dnn!zegi`9(Tm!7YahrAzT9*5QFZ$IHAZKaOj;+hRU%Y{|LZDOKd)^^ zWSYB7!w%*P|C4(4War|1{mY*he)zn*?rNN6n$zJp$DA(1vQtYoEaF+_7*Mf5>#5(g zgI|wI-8tg-oaI;7#8|#xjiO;y4)?SgoPQSYSaM!TNcr-!pQ}#xMx^(~ebE;P%eB68 zIP}q;NftLw$jamul&N1@TD?#q;1>sbFq`CAwHrUGiq`JGH1mPfR;!-gV|Q1!E!{rr zmbp>wUCE2(smG`PzBVc5#;INLjK+s~!gwYy9XxO_c;}K=hZ&{)%5GQ9*mZmU@{-@J zmo^^xDf56i@^Xzq-@4>eyb(vzx36`4WRZLM>0{YfuCF#9Ieu2D$t-bS=F|Z5!<$zd z9WN*_k4+X0{pI>=LH@3$9X}^rdlH)!a4TZXtTskw$(72l3q)8SO_8ga{r;uD){G}z zR?mZW%`bia(#e41q)K>-o>lEJkqt?^GxP4x4VkilNSo6F3gs z>&Uyeb(x*Kl%(tN*%K#*K7AQ{SlDA-AH$o%u1i_-ejanRNT~d~vg>idDNpI&K@4mb zL0d8&{%L96XWeC%8+mnk?Kcsr{uRql95*#AiH!N#oKVKrr983Ms{0LJ#fs8QpPJ*_ zv|N)MPAdP+>|U9ea&?{4(F$gpz%8FV7*4Ys)?2lHRwS#N+3~90tV^d?mS1Y@GrPfH zar@qqzM|P)XIn4#Di`-%UJZNrwXLij7qhMs+PyQ?mCn$DS~fo6j1}6mMdi zuc4AMzbdJ6opokxL{fATGjro>=SO`vUB1=;*Bpa?? zGRx_w|A&|DlP)S49f@^3cVPb4g(rfXc^+=wxT18)#tjoaFO)DjzCS7N<)C2~GtJUk zwn5~`C$+R5wnHa4C2n{1MRFZG<|)xLal`jT6F01#$;DSZOU&n)deY6L60OG~X;+Fi zI$YfJ)9irkoX!xWRC<%c+_jhdz5O zoAirsN$kfZ`9961$DB58dr(#Avgc{L^&Gh?>_}H~UfeEuK)LbH&1D*VOBKv+Ce_cjJh6ziV@iq<<7&&h z{>%5etvMR9@aCgS68{`#uyF(qb(gkHa65ACXhQPBHx5KXdWHks# zo9l2tKt#w@zQ~lvQ)6l~1bidddwyNc;xX-c z`NibG)XOW1-yXGOpVJe{6q2cYwyE;0AhSw?!>`LS4|tQ=yJ|$4Elhk3@5pxkdD&NZ z;QX~YPd;}gtvc#AM?U_&o8Q9*35Mrg5hvgJ_MZP)v2>-$w5!_+=LG1deOmU@_T>pF z$9H_sCTXztEpp_Mw)+#X;0k{Y4}YBU}E54=_zn! zR2B>D_xp0VfbH-R>3kPQ=7~gy==pu&pBCISQ~pe*+LF?W`-cm6C~r0M z+cSCY#_elWb&R*acZ#-~8-Lhd{;S?(i$2e&XJWaBcU-bJj$3+RpYF@OgdR=Zl@nNdb{QaMjl_>f8tf`z6s}BiGR!+J zYAhrBZN0&d=(pNOdvkuR?}%l)EY4hCpY>(MyWIB*ZO?9nOp^=_+BD}$^)IP@f7x^U zCTG2Okzfu?);{^^{ny1Ta#stl3yGg+YFFGm(dWpoq{fK!S<6<&XsgF;oNX7jZIbfW zEBwE%^|wnVIq^IeonPDfN>(lG+|(V0bE*XD|3zKoVSf4j*`{+Er4gU=mFF~=JpZ~n zzG9YXjMsCI_kmxF|1<1X=iG7P`Rkw~tHqp`ElIiYeX;rDXMdM%-#f8=_WZ0#)<3RK zRj>D2DEuR38?R4a#Dlr3t0P{2+`0O7b*`fQ5iTtU!3mXDo^Q)GT*SN5u=f1Y?Aa$`UV4guz7e+d+@Dz2CbqNlEEgR6q7-`0R8v06^@OB!f7H5o zcMYxw4X(zk)hZV081}q%damV}+h3)(+CXtecB>q*-J76>!zM5JvT?yafQ6v`TnQt z&ab}Hk-JXskFB>nLsiHU&nCl@IH{|P`u@0Yj>z;RNvFIHZ&P2s;f8vhq&60ldDlDK>I>D!S-G7FsriSl- z?7CsVG(TK#6yGfrz-66O{dw2wTdUSMY)QKHpnl>B)A@zTm6?-^vvsmJ z=r|l$@2rrtu}&kOfAJ{`o)?S%GlRHJ`ssjGZ>N-2YQpYy(}r{|S^*_S`BCMa%Bt$ksv$$qxmo9459dSw4&iv5>W z#Wjjo1UK`1`&?~4aldo;kJa<-=YNd9E$*STWXs;!%VWA{Z19pjC~vS@s6=md9^YDyUz85?floRa`rzg|IbjiQ+pm;vfY1% zPwVv8mCo;4vn%wv=c~Vp>;7b%ayepws0`CI%1Q)}mJ*O5W||@fJTKUy{+yI_X}G z5WnQQ`zPhC*B|?7`Mclnhr@RNAJ-1%KQ?=_?&6d>=BWq%7RO!8b8>$seVw2EfGm@A zV`=5}CA;SsoseB8>ZyE3>czV{wU^gU{;~AEv%fV-x~_8R&&1=8Yv#rrsTYsY`tl?9 zaOKk}mhrBlCpX3wxkm2aKkwheb$U#%l{vZ(tXjv+Bi#Hl&Trk_y8e%L`i~y-t$yz= zlNPBQ|7@!G_Z8DGtt;7b^-8YDJE@ZY3|E8a?g%`yA{Uxn0&tLMg``hmR{|w9bdOTrD zX{`UFu%6lG^L^3x^4X`vA8_B9Gr5rM{=X05Eds^|o|~Tj-uu~%rEyuyN0%?R9F9dx z{&}UxFe@k5FLOJCfaB^FT*({k&-y#vzUr{;Yx2^?rhoFx1y)4r}{7u)iKK^6XZmRo}zi4sd@pAV>|l73 zKI?h@vX9FaSJ{S~K5DP5v}f(Z{|p?YCf4ba6u=4BkQ0te$uU%9eCmd*eJ!`$p z%c7^rsRyhl7&}~E-)X|-A>~<z1&b_ZEotkf7P1~&b{h>Y0Zt>Iz^3-HgEBMCbw)Ib8gnVHU~Z<*JRV% zkza$A7Yd%+6;eNItMy+s_SHU*B%bUDl-v1n$@>X>R~J@_UJv$IymhYbBj2Yv?|+7w zA8C3!?Pl+8BNw-r>W|Ta_YUW?pR~r>{a$WyixjX=(}Be%)*4d zHk?&vz4|0BYrW^L%6F<~xJ>L!mOXU;b>(lueF+}1i=8T^itdRq8`rWsZr{lkeS5Nb zXOZ#4-8rjY*lPP9o2NNbOx5u-Z*G$>>z+xjqFWcnKbjgFcZB!V(o?TrdkV8%NIqB1 zCR4X%S&zZ`1i(*s+JzyI{UeSFm&&sJr>i@&e+uJ_x% zeQR`z%9L1z$^O-aDz$MIF%y|xCow!+rM|F)Wh z>%E;;z_5@(&nV+b&lxWBDd}HVJPlg%Y{g=miO1LPpKTqQ-C4+(lCb3Mj&om4kJu#{ z{t78{l6hHsq3W7Xvb|60RP|Yzs*`i7!#CF`8|^w){8_{F>2$5A7@o|)tySU&zH?o> zc0{IEvG~jSl|RhCeEjG0Z`YUG0h`ZDGp^`K`M{cc-T3h-(I86(_9VlzB^{m){ub*O z*4>kI4T$laaUs)Ja_NPkt>f+-F!A-KI1pLz*+96d;VSVUD9ND?)beKvoeK?qwO{(#oRZM>)} zj+0RvRWdHMYb-tf_^ix*rQQgIq~#MEf+h(*x%Bwb9HyNtDMfshc2hni2Pb45cyi&y zifcbqCw_jqGR#+j;p&vbmo*p}8N<~Jw6t61GW=7p`>G|DU}SS|YYEHB2}Rz?^;MG; zr5k=vyWBI;ujP4|TVdB+hQen|8$0^l)+C-gZa>xZP1d(}J8p{%kJclqK}UFwI^!Gf0UUR`(@?#>SZy1ZC}s(vF^Bg;PyR| zM^?9e)BgMV`iJY zuG!)H<$=_rey>-Cy>VRL^9rtB`{Qlj%B6QRJ;3;d<*IMtVQ;v8tdh2o`&#)seYvKN z@d3tJ7eCLdT+ne)L-2`m_1oB+ohsd)R@e7ghozo(+cIauMa}$Y(o!$i)#>Hj*qrV% zgQ568gBIKNsZ*x)mdrb}{$9z=wauQn`m-;#WgF>jRq;~VwXHPcnC#{HTWfYrlf2N* zty0N;`^mpAEDSp&17B%XT5a9j+|JM+_n*Pb!f~F$SplvLEwO^7M~*se;9@_u`2Mw} z;z6sY1g=kRvcB57*=b3eVmnhyL~4DzvUc-H5g!-*W0T^O%x_=6wA6f}(UV?xi4(V0 zOGhRhG<#)a5b5W(uDGkSt-*9fK&{4FffE;-B#Y-12hO;fMaHZ34)!M=Wj?y%)oG811)SD(QyKTnv*=XyJ1}8!&&BSyZQ;cm zzb#XkC(glEb7FUGmfH6FPEE@do}2353%ohKrg3BLX1|oi({3{J&E|Sk=lTe=%viE; zX~-2vt;fYbFDT9ty>Lf%`vKErhl8qrT;Dbyb$a>7M!;y#ueuQ7<5!;c&YXQtdS!Z*&6hW{+dH3OKaSOWbOZ zZ9ijt{Ljl?j;w<>ax%ZYbvTmHKjq)Cj`{W+izO~u{>^Nd(&hC;rcZOR)CSSU+=$D4 z_jWD|`_%l}IY?9e%nrLN5C5F9^Iz*`bCY?$$j|#$wJWYI3ulkyDcN?b>p#O%$q6C_ zEBnnB_IowQ%`5x+^6H1>%$CYuR`zCv6)3A)N_F1J(>%5(lh5g~P0F-CFSuW&B{v*- zep_Ugqw=o}_b-ITdOm6>5OtZsb+k?6OpkJ!T##+~iYSNJ*`5c#SYN6U%`v<2XqnX9 z**dr8x`{K?3EfE-Y2K4=C$uuSVWA%@M@r%IgWOM3&gY~};Be5{nP#0n*XI3upTMbx zbxe}hdIjcxUx-c$RX-P@`Dx?1fH$}QGk6t+Yb7U$tMG0Yc`!AVr?fpL$6|%h55skH z`Q?*#oK%qAz9{L)G{w8KwVxhW|EuAp?UBq^(t4wLTJX#F&JVLKbr_g)Hx<8h)z{>2 zz4D;$%c&y*i;P=OKbhxWe`#W*jeBWF&xsJX^4nJ~`pYy1Ox0L!J!{tqVbx=yf$kDk z`?Dqqtg1Gedf)!?YsZyE242>cf*a@j{v9ZK`r(8P7A(y7ufGm;Z~5roc52v7-D|TmOZAedvaljvbC`cQ)D^IuVAB-E1H~B z+YTf&hN-wrbb6u8uAq0|va(Lgxy39`J#7zsTl8pO}Qv`cI6#;B}TD7*4`QF^V z=QX^RpWnE$bohyM3QMG&d~j{jfvGa-;q7fKx%0DxpB{5#Zhn_>YV!2Eg&SFlY%{y2 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≫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 z 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̂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, dass im neuen Berliner Polizeigesetz der Einsatz von Palantir ausdrücklich nicht ausgeschlossen ist. Die zentrale Analyseplattform, die dieses Gesetz vorsieht, ist genau das Geschäftsmodell von Palantir. + +### Thiels Weltbild + +Thiel ist nicht nur Geschäftsmann. Er hat eine klare politische Agenda, und die ist erklärtermaßen antidemokratisch. 2009 schrieb er in einem Essay: „I no longer believe that freedom and democracy are compatible." Zu Deutsch: Ich glaube nicht mehr daran, dass Freiheit und Demokratie vereinbar sind. Im selben Text machte er das Wahlrecht für Frauen und den Sozialstaat dafür verantwortlich, dass die liberale Demokratie seiner Ansicht nach gescheitert ist. + +Er steht dem Umfeld der sogenannten Neoreaktion nahe, einer Denkrichtung, die die Demokratie für gescheitert hält und stattdessen autoritäre Strukturen anstrebt. Ein Vordenker dieser Szene, Curtis Yarvin, träumt öffentlich von der Abschaffung des Parlamentarismus und von einem Staat, der wie ein Unternehmen geführt wird, mit einem Chef an der Spitze statt gewählter Vertreter:innen. Thiel hat Yarvin über Jahre gefördert und gepriesen. + +Thiels Geld fließt auch in die Politik. Er unterstützte Donald Trump bereits 2016 und finanzierte 2022 mit 15 Millionen Dollar die Senatskampagne von JD Vance, dem heutigen Vizepräsidenten der USA. Es war damals die größte Einzelspende an einen Senatskandidaten. Und mit dem Seasteading Institute wollte er schwimmende Stadtstaaten errichten, die sich staatlicher Regeln komplett entziehen. + +Kurz gesagt: Hier geht es um jemanden, der die Demokratie nicht nur kritisiert, sondern sie abschaffen will. + +### Thiels Glaube und der Antichrist + +Was viele bei Thiel übersehen: Seine Weltsicht ist tief religiös geprägt, allerdings auf eine sehr eigene Art. Thiel ist gläubiger Christ, aber weit entfernt vom Mainstream. Sein Denken ist stark von dem französischen Philosophen René Girard beeinflusst, dessen Theorie um Nachahmung, Sündenböcke und Apokalypse kreist. Thiel hat Girard über Jahre studiert und dessen apokalyptische Grundhaltung übernommen. + +Das zeigt sich besonders bei einem Thema, über das Thiel immer wieder spricht: den Antichristen. Thiel nimmt das wörtlich. In Interviews beschreibt er den Antichristen als eine Figur, die einen weltweiten Einheitsstaat errichtet, einen falschen Frieden verspricht und dabei jede Freiheit abschafft. Zentrale Datenmacht, allgegenwärtige Überwachung und Dinge wie das chinesische Social-Credit-System ordnet er in dieses Endzeitszenario ein. Er beschreibt sich selbst als jemand, der die Zeichen dafür überall erkennt. + +An dieser Stelle lohnt es sich, kurz innezuhalten. Denn hier steckt ein bemerkenswerter Widerspruch: Thiel warnt vor einem totalitären Überwachungsstaat als Vorboten des Antichristen, während er gleichzeitig mit Palantir das leistungsfähigste Überwachungsunternehmen der Welt aufbaut und an genau die Staaten verkauft, vor denen er angeblich warnt. Ob man das nun für aufrichtige Angst, für Zynismus oder für beides hält: Es sagt eine Menge über diesen Mann aus, dass sein Geschäft genau das herstellt, was sein Glaube verdammt. + +### Der Axel-Springer-Award + +Vor diesem Hintergrund ist es bemerkenswert, dass ausgerechnet Axel Springer diesen Mann auszeichnet. Axel Springer ist einer der größten Medienkonzerte Europas und gibt Blätter wie Bild und Welt heraus. Den Axel-Springer-Award verleiht der Konzern seit Jahren an Persönlichkeiten der Digitalwirtschaft, unter den bisherigen Preisträgern waren Mark Zuckerberg, Jeff Bezos und Elon Musk. + +Mit Peter Thiel ehrt Axel Springer nun einen Mann, der offen erklärt hat, dass er Demokratie und Freiheit für unvereinbar hält. Die Verleihung am 24. September in Berlin ist eine Bühne. Wir finden: Sie sollte nicht unwidersprochen bleiben. Deshalb laden wir drei Tage vorher in den Club ein. + +### Programm + +**19:00 Uhr: Vortrag** \ +Wer ist Peter Thiel? Was macht Palantir? Welche Netzwerke, welches Weltbild und welcher Glaube stecken dahinter? Und warum ist das alles gefährlich? + +**Anschließend: Austausch** \ +Diskussion und offener Austausch, offenes Ende. + +Ihr braucht kein Vorwissen. Kommt einfach vorbei. + +### Wo? + +📍 **Chaos Computer Club Berlin, Marienstraße 11, 10117 Berlin** + +🚈 Etwa 5 Minuten ab dem S-Bahnhof Friedrichstraße + +### Wann? + +**📆 Montag, 21. September 2026** \ +**ab 19:00 Uhr** + +### Zum Weiterlesen + +- Wikipedia: [Peter Thiel](https://de.wikipedia.org/wiki/Peter_Thiel) +- Wikipedia: [Palantir Technologies](https://de.wikipedia.org/wiki/Palantir_Technologies) +- Wikipedia: [Axel Springer SE](https://de.wikipedia.org/wiki/Axel_Springer_SE) + +*Titelbild: [Gage Skidmore](https://commons.wikimedia.org/wiki/File:Peter_Thiel_(51876930225).jpg), [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/deed.en)* diff --git a/content/post/2026-09-21-thiel-ante-portas/peter-thiel.jpg b/content/post/2026-09-21-thiel-ante-portas/peter-thiel.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2726e6cfb40ab0d4bf4fed60b5280f06ec093e0 GIT binary patch literal 109880 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

=@WS2BzQ_`{x<$gC1wf7sEvMCL-6 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 Date: Fri, 28 Aug 2026 17:24:09 +0200 Subject: [PATCH 18/18] fix shit --- .../{ki-kamera.jpg => feature-ki-kamera.jpg} | Bin .../post/2026-08-28-normenkontrolle-asog/index.md | 12 +++++++----- .../{peter-thiel.jpg => feature-peter-thiel.jpg} | Bin content/post/2026-09-21-thiel-ante-portas/index.md | 12 +++++++----- 4 files changed, 14 insertions(+), 10 deletions(-) rename content/post/2026-08-28-normenkontrolle-asog/{ki-kamera.jpg => feature-ki-kamera.jpg} (100%) rename content/post/2026-09-21-thiel-ante-portas/{peter-thiel.jpg => feature-peter-thiel.jpg} (100%) diff --git a/content/post/2026-08-28-normenkontrolle-asog/ki-kamera.jpg b/content/post/2026-08-28-normenkontrolle-asog/feature-ki-kamera.jpg similarity index 100% rename from content/post/2026-08-28-normenkontrolle-asog/ki-kamera.jpg rename to content/post/2026-08-28-normenkontrolle-asog/feature-ki-kamera.jpg diff --git a/content/post/2026-08-28-normenkontrolle-asog/index.md b/content/post/2026-08-28-normenkontrolle-asog/index.md index a97beef..6746d47 100644 --- a/content/post/2026-08-28-normenkontrolle-asog/index.md +++ b/content/post/2026-08-28-normenkontrolle-asog/index.md @@ -1,12 +1,16 @@ --- title: "Linke und Grüne ziehen gegen das Berliner Polizeigesetz vor Gericht" date: 2026-08-28T12:00:00+02:00 -showHero: true -featureImage: "ki-kamera.jpg" -featureImageCaption: "Foto: netzpolitik.org, CC BY-NC-SA 4.0" +showHero: false tags: ["Überwachung", "Polizeigesetz", "ASOG"] --- +{{< figure + src="feature-ki-kamera.jpg" + alt="KI-Überwachungskamera" + caption="KI-Überwachungskamera. Foto: netzpolitik.org, CC BY-NC-SA 4.0" +>}} + Als CDU und SPD Ende 2025 das Berliner Polizeigesetz verschärften, war die Kritik laut. Jetzt wird sie juristisch: Am 28. August 2026 haben Bündnis 90/Die Grünen und Die Linke beim Verfassungsgerichtshof des Landes Berlin einen Antrag auf Normenkontrolle eingereicht. Das höchste Berliner Gericht soll nun prüfen, ob die neuen Überwachungsbefugnisse mit der Landesverfassung vereinbar sind oder schlicht zu weit gehen. ### Vor fünf Tagen war das noch ein Thema im Club @@ -60,5 +64,3 @@ Wie das ausgeht, ist offen. Sicher ist nur: Der Streit um das Polizeigesetz wird - taz: [KI-Videoüberwachung in Berlin: Verhaltensscanner bald auch vor dem Abgeordnetenhaus](https://taz.de/KI-Videoueberwachung-in-Berlin/!6160851/) - netzpolitik.org: [So wehrt man sich gegen Verhaltensscanner](https://netzpolitik.org/2026/ki-gestuetzte-videoueberwachung-in-berlin-so-wehrt-man-sich-gegen-verhaltensscanner/) - beck-aktuell: [Kameras und KI-Einsatz: Berlin verschärft Polizeigesetz](https://www.beck-aktuell.de/heute-im-recht/rechtspolitik-gesetzgebung/berlin-verschaerfung-polizeigesetz-2025-12-04) - -*Titelbild: [netzpolitik.org](https://netzpolitik.org/), [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.de)* diff --git a/content/post/2026-09-21-thiel-ante-portas/peter-thiel.jpg b/content/post/2026-09-21-thiel-ante-portas/feature-peter-thiel.jpg similarity index 100% rename from content/post/2026-09-21-thiel-ante-portas/peter-thiel.jpg rename to content/post/2026-09-21-thiel-ante-portas/feature-peter-thiel.jpg diff --git a/content/post/2026-09-21-thiel-ante-portas/index.md b/content/post/2026-09-21-thiel-ante-portas/index.md index 7306366..df5643f 100644 --- a/content/post/2026-09-21-thiel-ante-portas/index.md +++ b/content/post/2026-09-21-thiel-ante-portas/index.md @@ -1,12 +1,16 @@ --- title: "Peter Thiel ante portas" date: 2026-08-28T12:00:00+02:00 -showHero: true -featureImage: "peter-thiel.jpg" -featureImageCaption: "Foto: Gage Skidmore, CC BY-SA 2.0" +showHero: false tags: ["Überwachung", "Palantir", "Ankündigung"] --- +{{< figure + src="feature-peter-thiel.jpg" + alt="Peter Thiel" + caption="Peter Thiel. Foto: Gage Skidmore, CC BY-SA 2.0" +>}} + ### Was? Am 24. September nimmt Peter Thiel in Berlin den Axel-Springer-Award entgegen. Drei Tage vorher, am 21. September, schauen wir uns im Club an, wer da eigentlich geehrt wird. Denn der Mann, den Axel Springer da auszeichnet, ist kein harmloser Tech-Unternehmer. @@ -79,5 +83,3 @@ Ihr braucht kein Vorwissen. Kommt einfach vorbei. - Wikipedia: [Peter Thiel](https://de.wikipedia.org/wiki/Peter_Thiel) - Wikipedia: [Palantir Technologies](https://de.wikipedia.org/wiki/Palantir_Technologies) - Wikipedia: [Axel Springer SE](https://de.wikipedia.org/wiki/Axel_Springer_SE) - -*Titelbild: [Gage Skidmore](https://commons.wikimedia.org/wiki/File:Peter_Thiel_(51876930225).jpg), [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/deed.en)*