changeset 50:e09cef17c56c

stale confused Ssabre stuff
author Charlie Root
date Mon, 06 Oct 2025 12:32:10 -0400
parents 91f005a4f7e9
children b80b258cc02c
files plugins/libcalendaring/composer.json plugins/libcalendaring/lib/Sabre/VObject/Component.php plugins/libcalendaring/lib/Sabre/VObject/Component/VAlarm.php plugins/libcalendaring/lib/Sabre/VObject/Component/VCalendar.php plugins/libcalendaring/lib/Sabre/VObject/Component/VCard.php plugins/libcalendaring/lib/Sabre/VObject/Component/VEvent.php plugins/libcalendaring/lib/Sabre/VObject/Component/VFreeBusy.php plugins/libcalendaring/lib/Sabre/VObject/Component/VJournal.php plugins/libcalendaring/lib/Sabre/VObject/Component/VTodo.php plugins/libcalendaring/lib/Sabre/VObject/DateTimeParser.php plugins/libcalendaring/lib/Sabre/VObject/Document.php plugins/libcalendaring/lib/Sabre/VObject/ElementList.php plugins/libcalendaring/lib/Sabre/VObject/FreeBusyGenerator.php plugins/libcalendaring/lib/Sabre/VObject/Node.php plugins/libcalendaring/lib/Sabre/VObject/Parameter.php plugins/libcalendaring/lib/Sabre/VObject/ParseException.php plugins/libcalendaring/lib/Sabre/VObject/Property.php plugins/libcalendaring/lib/Sabre/VObject/Property/Compound.php plugins/libcalendaring/lib/Sabre/VObject/Property/DateTime.php plugins/libcalendaring/lib/Sabre/VObject/Property/MultiDateTime.php plugins/libcalendaring/lib/Sabre/VObject/Reader.php plugins/libcalendaring/lib/Sabre/VObject/RecurrenceIterator.php plugins/libcalendaring/lib/Sabre/VObject/Splitter/ICalendar.php plugins/libcalendaring/lib/Sabre/VObject/Splitter/SplitterInterface.php plugins/libcalendaring/lib/Sabre/VObject/Splitter/VCard.php plugins/libcalendaring/lib/Sabre/VObject/StringUtil.php plugins/libcalendaring/lib/Sabre/VObject/TimeZoneUtil.php plugins/libcalendaring/lib/Sabre/VObject/Version.php plugins/libcalendaring/lib/Sabre/VObject/includes.php vendor/autoload.php vendor/sabre/vobject/.gitignore vendor/sabre/vobject/.travis.yml vendor/sabre/vobject/ChangeLog.md vendor/sabre/vobject/LICENSE vendor/sabre/vobject/README.md vendor/sabre/vobject/bin/bench.php vendor/sabre/vobject/bin/fetch_windows_zones.php vendor/sabre/vobject/bin/generate_vcards vendor/sabre/vobject/bin/generateicalendardata.php vendor/sabre/vobject/bin/vobject vendor/sabre/vobject/composer.json vendor/sabre/vobject/lib/Cli.php vendor/sabre/vobject/lib/Component.php vendor/sabre/vobject/lib/Component/VAlarm.php vendor/sabre/vobject/lib/Component/VCalendar.php vendor/sabre/vobject/lib/Component/VCard.php vendor/sabre/vobject/lib/Component/VEvent.php vendor/sabre/vobject/lib/Component/VFreeBusy.php vendor/sabre/vobject/lib/Component/VJournal.php vendor/sabre/vobject/lib/Component/VTimeZone.php vendor/sabre/vobject/lib/Component/VTodo.php vendor/sabre/vobject/lib/DateTimeParser.php vendor/sabre/vobject/lib/Document.php vendor/sabre/vobject/lib/ElementList.php vendor/sabre/vobject/lib/EofException.php vendor/sabre/vobject/lib/FreeBusyGenerator.php vendor/sabre/vobject/lib/ITip/Broker.php vendor/sabre/vobject/lib/ITip/ITipException.php vendor/sabre/vobject/lib/ITip/Message.php vendor/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php vendor/sabre/vobject/lib/Node.php vendor/sabre/vobject/lib/Parameter.php vendor/sabre/vobject/lib/ParseException.php vendor/sabre/vobject/lib/Parser/Json.php vendor/sabre/vobject/lib/Parser/MimeDir.php vendor/sabre/vobject/lib/Parser/Parser.php vendor/sabre/vobject/lib/Property.php vendor/sabre/vobject/lib/Property/Binary.php vendor/sabre/vobject/lib/Property/Boolean.php vendor/sabre/vobject/lib/Property/FlatText.php vendor/sabre/vobject/lib/Property/Float.php vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php vendor/sabre/vobject/lib/Property/ICalendar/Date.php vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php vendor/sabre/vobject/lib/Property/ICalendar/Duration.php vendor/sabre/vobject/lib/Property/ICalendar/Period.php vendor/sabre/vobject/lib/Property/ICalendar/Recur.php vendor/sabre/vobject/lib/Property/Integer.php vendor/sabre/vobject/lib/Property/Text.php vendor/sabre/vobject/lib/Property/Time.php vendor/sabre/vobject/lib/Property/Unknown.php vendor/sabre/vobject/lib/Property/Uri.php vendor/sabre/vobject/lib/Property/UtcOffset.php vendor/sabre/vobject/lib/Property/VCard/Date.php vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.php vendor/sabre/vobject/lib/Property/VCard/DateTime.php vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php vendor/sabre/vobject/lib/Property/VCard/TimeStamp.php vendor/sabre/vobject/lib/Reader.php vendor/sabre/vobject/lib/Recur/EventIterator.php vendor/sabre/vobject/lib/Recur/NoInstancesException.php vendor/sabre/vobject/lib/Recur/RDateIterator.php vendor/sabre/vobject/lib/Recur/RRuleIterator.php vendor/sabre/vobject/lib/RecurrenceIterator.php vendor/sabre/vobject/lib/Splitter/ICalendar.php vendor/sabre/vobject/lib/Splitter/SplitterInterface.php vendor/sabre/vobject/lib/Splitter/VCard.php vendor/sabre/vobject/lib/StringUtil.php vendor/sabre/vobject/lib/TimeZoneUtil.php vendor/sabre/vobject/lib/UUIDUtil.php vendor/sabre/vobject/lib/VCardConverter.php vendor/sabre/vobject/lib/Version.php vendor/sabre/vobject/lib/timezonedata/exchangezones.php vendor/sabre/vobject/lib/timezonedata/lotuszones.php vendor/sabre/vobject/lib/timezonedata/php-bc.php vendor/sabre/vobject/lib/timezonedata/php-workaround.php vendor/sabre/vobject/lib/timezonedata/windowszones.php vendor/sabre/vobject/tests/VObject/AttachIssueTest.php vendor/sabre/vobject/tests/VObject/CliTest.php vendor/sabre/vobject/tests/VObject/Component/VAlarmTest.php vendor/sabre/vobject/tests/VObject/Component/VCalendarTest.php vendor/sabre/vobject/tests/VObject/Component/VCardTest.php vendor/sabre/vobject/tests/VObject/Component/VEventTest.php vendor/sabre/vobject/tests/VObject/Component/VFreeBusyTest.php vendor/sabre/vobject/tests/VObject/Component/VJournalTest.php vendor/sabre/vobject/tests/VObject/Component/VTimeZoneTest.php vendor/sabre/vobject/tests/VObject/Component/VTodoTest.php vendor/sabre/vobject/tests/VObject/ComponentTest.php vendor/sabre/vobject/tests/VObject/DateTimeParserTest.php vendor/sabre/vobject/tests/VObject/DocumentTest.php vendor/sabre/vobject/tests/VObject/ElementListTest.php vendor/sabre/vobject/tests/VObject/EmClientTest.php vendor/sabre/vobject/tests/VObject/EmptyParameterTest.php vendor/sabre/vobject/tests/VObject/EmptyValueIssueTest.php vendor/sabre/vobject/tests/VObject/FreeBusyGeneratorTest.php vendor/sabre/vobject/tests/VObject/GoogleColonEscapingTest.php vendor/sabre/vobject/tests/VObject/ICalendar/AttachParseTest.php vendor/sabre/vobject/tests/VObject/ITip/BrokerAttendeeReplyTest.php vendor/sabre/vobject/tests/VObject/ITip/BrokerDeleteEventTest.php vendor/sabre/vobject/tests/VObject/ITip/BrokerNewEventTest.php vendor/sabre/vobject/tests/VObject/ITip/BrokerProcessMessageTest.php vendor/sabre/vobject/tests/VObject/ITip/BrokerProcessReplyTest.php vendor/sabre/vobject/tests/VObject/ITip/BrokerTester.php vendor/sabre/vobject/tests/VObject/ITip/BrokerUpdateEventTest.php vendor/sabre/vobject/tests/VObject/ITip/EvolutionTest.php vendor/sabre/vobject/tests/VObject/ITip/MessageTest.php vendor/sabre/vobject/tests/VObject/Issue153Test.php vendor/sabre/vobject/tests/VObject/Issue26Test.php vendor/sabre/vobject/tests/VObject/Issue36WorkAroundTest.php vendor/sabre/vobject/tests/VObject/Issue40Test.php vendor/sabre/vobject/tests/VObject/Issue64Test.php vendor/sabre/vobject/tests/VObject/Issue96Test.php vendor/sabre/vobject/tests/VObject/JCalTest.php vendor/sabre/vobject/tests/VObject/JCardTest.php vendor/sabre/vobject/tests/VObject/LineFoldingIssueTest.php vendor/sabre/vobject/tests/VObject/ParameterTest.php vendor/sabre/vobject/tests/VObject/Parser/JsonTest.php vendor/sabre/vobject/tests/VObject/Parser/MimeDirTest.php vendor/sabre/vobject/tests/VObject/Parser/QuotedPrintableTest.php vendor/sabre/vobject/tests/VObject/Property/BinaryTest.php vendor/sabre/vobject/tests/VObject/Property/BooleanTest.php vendor/sabre/vobject/tests/VObject/Property/CompoundTest.php vendor/sabre/vobject/tests/VObject/Property/FloatTest.php vendor/sabre/vobject/tests/VObject/Property/ICalendar/CalAddressTest.php vendor/sabre/vobject/tests/VObject/Property/ICalendar/DateTimeTest.php vendor/sabre/vobject/tests/VObject/Property/ICalendar/DurationTest.php vendor/sabre/vobject/tests/VObject/Property/ICalendar/RecurTest.php vendor/sabre/vobject/tests/VObject/Property/TextTest.php vendor/sabre/vobject/tests/VObject/Property/VCard/DateAndOrTimeTest.php vendor/sabre/vobject/tests/VObject/Property/VCard/LanguageTagTest.php vendor/sabre/vobject/tests/VObject/PropertyTest.php vendor/sabre/vobject/tests/VObject/ReaderTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/FifthTuesdayProblemTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/InfiniteLoopProblemTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/Issue48Test.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/Issue50Test.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/MainTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/NoInstancesTest.php vendor/sabre/vobject/tests/VObject/Recur/EventIterator/OverrideFirstEventTest.php vendor/sabre/vobject/tests/VObject/Recur/RDateIteratorTest.php vendor/sabre/vobject/tests/VObject/Recur/RRuleIteratorTest.php vendor/sabre/vobject/tests/VObject/RecurrenceIterator/UntilRespectsTimezoneTest.ics vendor/sabre/vobject/tests/VObject/SlashRTest.php vendor/sabre/vobject/tests/VObject/Splitter/ICalendarTest.php vendor/sabre/vobject/tests/VObject/Splitter/VCardTest.php vendor/sabre/vobject/tests/VObject/StringUtilTest.php vendor/sabre/vobject/tests/VObject/TestCase.php vendor/sabre/vobject/tests/VObject/TimeZoneUtilTest.php vendor/sabre/vobject/tests/VObject/UUIDUtilTest.php vendor/sabre/vobject/tests/VObject/VCard21Test.php vendor/sabre/vobject/tests/VObject/VCardConverterTest.php vendor/sabre/vobject/tests/VObject/VersionTest.php vendor/sabre/vobject/tests/VObject/issue153.vcf vendor/sabre/vobject/tests/VObject/issue64.vcf vendor/sabre/vobject/tests/bootstrap.php vendor/sabre/vobject/tests/phpcs/ruleset.xml vendor/sabre/vobject/tests/phpunit.xml
diffstat 190 files changed, 0 insertions(+), 37581 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/libcalendaring/composer.json	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-{
-    "name": "kolab/libcalendaring",
-    "type": "roundcube-plugin",
-    "description": "Library providing common functions for calendaring plugins",
-    "homepage": "https://git.kolab.org/diffusion/RPK/",
-    "license": "AGPLv3",
-    "authors": [
-        {
-            "name": "Alensader Machniak",
-            "email": "machniak@kolabsys.com",
-            "role": "Lead"
-        }
-    ],
-    "repositories": [
-        {
-            "type": "composer",
-            "url": "https://plugins.roundcube.net"
-        }
-    ],
-    "require": {
-        "php": ">=5.4.0",
-        "roundcube/plugin-installer": ">=0.1.3",
-        "sabre/vobject": "~3.3.3"
-    },
-    "extra": {
-        "roundcube": {
-            "min-version": "1.3.0"
-        }
-    }
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,405 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * VObject Component
- *
- * This class represents a VCALENDAR/VCARD component. A component is for example
- * VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and
- * ends with END:COMPONENTNAME
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Component extends Node {
-
-    /**
-     * Name, for example VEVENT
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * Children properties and components
-     *
-     * @var array
-     */
-    public $children = array();
-
-    /**
-     * If components are added to this map, they will be automatically mapped
-     * to their respective classes, if parsed by the reader or constructed with
-     * the 'create' method.
-     *
-     * @var array
-     */
-    static public $classMap = array(
-        'VALARM'        => 'Sabre\\VObject\\Component\\VAlarm',
-        'VCALENDAR'     => 'Sabre\\VObject\\Component\\VCalendar',
-        'VCARD'         => 'Sabre\\VObject\\Component\\VCard',
-        'VEVENT'        => 'Sabre\\VObject\\Component\\VEvent',
-        'VJOURNAL'      => 'Sabre\\VObject\\Component\\VJournal',
-        'VTODO'         => 'Sabre\\VObject\\Component\\VTodo',
-        'VFREEBUSY'     => 'Sabre\\VObject\\Component\\VFreeBusy',
-    );
-
-    /**
-     * Creates the new component by name, but in addition will also see if
-     * there's a class mapped to the property name.
-     *
-     * @param string $name
-     * @param string $value
-     * @return Component
-     */
-    static public function create($name, $value = null) {
-
-        $name = strtoupper($name);
-
-        if (isset(self::$classMap[$name])) {
-            return new self::$classMap[$name]($name, $value);
-        } else {
-            return new self($name, $value);
-        }
-
-    }
-
-    /**
-     * Creates a new component.
-     *
-     * By default this object will iterate over its own children, but this can
-     * be overridden with the iterator argument
-     *
-     * @param string $name
-     * @param ElementList $iterator
-     */
-    public function __construct($name, ElementList $iterator = null) {
-
-        $this->name = strtoupper($name);
-        if (!is_null($iterator)) $this->iterator = $iterator;
-
-    }
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    public function serialize() {
-
-        $str = "BEGIN:" . $this->name . "\r\n";
-
-        /**
-         * Gives a component a 'score' for sorting purposes.
-         *
-         * This is solely used by the childrenSort method.
-         *
-         * A higher score means the item will be lower in the list.
-         * To avoid score collisions, each "score category" has a reasonable
-         * space to accomodate elements. The $key is added to the $score to
-         * preserve the original relative order of elements.
-         *
-         * @param int $key
-         * @param array $array
-         * @return int
-         */
-        $sortScore = function($key, $array) {
-
-            if ($array[$key] instanceof Component) {
-
-                // We want to encode VTIMEZONE first, this is a personal
-                // preference.
-                if ($array[$key]->name === 'VTIMEZONE') {
-                    $score=300000000;
-                    return $score+$key;
-                } else {
-                    $score=400000000;
-                    return $score+$key;
-                }
-            } else {
-                // Properties get encoded first
-                // VCARD version 4.0 wants the VERSION property to appear first
-                if ($array[$key] instanceof Property) {
-                    if ($array[$key]->name === 'VERSION') {
-                        $score=100000000;
-                        return $score+$key;
-                    } else {
-                        // All other properties
-                        $score=200000000;
-                        return $score+$key;
-                    }
-                }
-            }
-
-        };
-
-        $tmp = $this->children;
-        uksort($this->children, function($a, $b) use ($sortScore, $tmp) {
-
-            $sA = $sortScore($a, $tmp);
-            $sB = $sortScore($b, $tmp);
-
-            if ($sA === $sB) return 0;
-
-            return ($sA < $sB) ? -1 : 1;
-
-        });
-
-        foreach($this->children as $child) $str.=$child->serialize();
-        $str.= "END:" . $this->name . "\r\n";
-
-        return $str;
-
-    }
-
-    /**
-     * Adds a new component or element
-     *
-     * You can call this method with the following syntaxes:
-     *
-     * add(Node $node)
-     * add(string $name, $value, array $parameters = array())
-     *
-     * The first version adds an Element
-     * The second adds a property as a string.
-     *
-     * @param mixed $item
-     * @param mixed $itemValue
-     * @return void
-     */
-    public function add($item, $itemValue = null, array $parameters = array()) {
-
-        if ($item instanceof Node) {
-            if (!is_null($itemValue)) {
-                throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject Node');
-            }
-            $item->parent = $this;
-            $this->children[] = $item;
-        } elseif(is_string($item)) {
-
-            $item = Property::create($item,$itemValue, $parameters);
-            $item->parent = $this;
-            $this->children[] = $item;
-
-        } else {
-
-            throw new \InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string');
-
-        }
-
-    }
-
-    /**
-     * Returns an iterable list of children
-     *
-     * @return ElementList
-     */
-    public function children() {
-
-        return new ElementList($this->children);
-
-    }
-
-    /**
-     * Returns an array with elements that match the specified name.
-     *
-     * This function is also aware of MIME-Directory groups (as they appear in
-     * vcards). This means that if a property is grouped as "HOME.EMAIL", it
-     * will also be returned when searching for just "EMAIL". If you want to
-     * search for a property in a specific group, you can select on the entire
-     * string ("HOME.EMAIL"). If you want to search on a specific property that
-     * has not been assigned a group, specify ".EMAIL".
-     *
-     * Keys are retained from the 'children' array, which may be confusing in
-     * certain cases.
-     *
-     * @param string $name
-     * @return array
-     */
-    public function select($name) {
-
-        $group = null;
-        $name = strtoupper($name);
-        if (strpos($name,'.')!==false) {
-            list($group,$name) = explode('.', $name, 2);
-        }
-
-        $result = array();
-        foreach($this->children as $key=>$child) {
-
-            if (
-                strtoupper($child->name) === $name &&
-                (is_null($group) || ( $child instanceof Property && strtoupper($child->group) === $group))
-            ) {
-
-                $result[$key] = $child;
-
-            }
-        }
-
-        reset($result);
-        return $result;
-
-    }
-
-    /**
-     * This method only returns a list of sub-components. Properties are
-     * ignored.
-     *
-     * @return array
-     */
-    public function getComponents() {
-
-        $result = array();
-        foreach($this->children as $child) {
-            if ($child instanceof Component) {
-                $result[] = $child;
-            }
-        }
-
-        return $result;
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   - Node::REPAIR - If something is broken, and automatic repair may
-     *                    be attempted.
-     *
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $result = array();
-        foreach($this->children as $child) {
-            $result = array_merge($result, $child->validate($options));
-        }
-        return $result;
-
-    }
-
-    /* Magic property accessors {{{ */
-
-    /**
-     * Using 'get' you will either get a property or component,
-     *
-     * If there were no child-elements found with the specified name,
-     * null is returned.
-     *
-     * @param string $name
-     * @return Property
-     */
-    public function __get($name) {
-
-        $matches = $this->select($name);
-        if (count($matches)===0) {
-            return null;
-        } else {
-            $firstMatch = current($matches);
-            /** @var $firstMatch Property */
-            $firstMatch->setIterator(new ElementList(array_values($matches)));
-            return $firstMatch;
-        }
-
-    }
-
-    /**
-     * This method checks if a sub-element with the specified name exists.
-     *
-     * @param string $name
-     * @return bool
-     */
-    public function __isset($name) {
-
-        $matches = $this->select($name);
-        return count($matches)>0;
-
-    }
-
-    /**
-     * Using the setter method you can add properties or subcomponents
-     *
-     * You can either pass a Component, Property
-     * object, or a string to automatically create a Property.
-     *
-     * If the item already exists, it will be removed. If you want to add
-     * a new item with the same name, always use the add() method.
-     *
-     * @param string $name
-     * @param mixed $value
-     * @return void
-     */
-    public function __set($name, $value) {
-
-        $matches = $this->select($name);
-        $overWrite = count($matches)?key($matches):null;
-
-        if ($value instanceof Component || $value instanceof Property) {
-            $value->parent = $this;
-            if (!is_null($overWrite)) {
-                $this->children[$overWrite] = $value;
-            } else {
-                $this->children[] = $value;
-            }
-        } elseif (is_scalar($value)) {
-            $property = Property::create($name,$value);
-            $property->parent = $this;
-            if (!is_null($overWrite)) {
-                $this->children[$overWrite] = $property;
-            } else {
-                $this->children[] = $property;
-            }
-        } else {
-            throw new \InvalidArgumentException('You must pass a \\Sabre\\VObject\\Component, \\Sabre\\VObject\\Property or scalar type');
-        }
-
-    }
-
-    /**
-     * Removes all properties and components within this component.
-     *
-     * @param string $name
-     * @return void
-     */
-    public function __unset($name) {
-
-        $matches = $this->select($name);
-        foreach($matches as $k=>$child) {
-
-            unset($this->children[$k]);
-            $child->parent = null;
-
-        }
-
-    }
-
-    /* }}} */
-
-    /**
-     * This method is automatically called when the object is cloned.
-     * Specifically, this will ensure all child elements are also cloned.
-     *
-     * @return void
-     */
-    public function __clone() {
-
-        foreach($this->children as $key=>$child) {
-            $this->children[$key] = clone $child;
-            $this->children[$key]->parent = $this;
-        }
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VAlarm.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-use Sabre\VObject;
-
-/**
- * VAlarm component
- *
- * This component contains some additional functionality specific for VALARMs.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VAlarm extends VObject\Component {
-
-    /**
-     * Returns a DateTime object when this alarm is going to trigger.
-     *
-     * This ignores repeated alarm, only the first trigger is returned.
-     *
-     * @return DateTime
-     */
-    public function getEffectiveTriggerTime() {
-
-        $trigger = $this->TRIGGER;
-        if(!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
-            $triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER);
-            $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
-
-            $parentComponent = $this->parent;
-            if ($related === 'START') {
-
-                if ($parentComponent->name === 'VTODO') {
-                    $propName = 'DUE';
-                } else {
-                    $propName = 'DTSTART';
-                }
-
-                $effectiveTrigger = clone $parentComponent->$propName->getDateTime();
-                $effectiveTrigger->add($triggerDuration);
-            } else {
-                if ($parentComponent->name === 'VTODO') {
-                    $endProp = 'DUE';
-                } elseif ($parentComponent->name === 'VEVENT') {
-                    $endProp = 'DTEND';
-                } else {
-                    throw new \LogicException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
-                }
-
-                if (isset($parentComponent->$endProp)) {
-                    $effectiveTrigger = clone $parentComponent->$endProp->getDateTime();
-                    $effectiveTrigger->add($triggerDuration);
-                } elseif (isset($parentComponent->DURATION)) {
-                    $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
-                    $duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION);
-                    $effectiveTrigger->add($duration);
-                    $effectiveTrigger->add($triggerDuration);
-                } else {
-                    $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
-                    $effectiveTrigger->add($triggerDuration);
-                }
-            }
-        } else {
-            $effectiveTrigger = $trigger->getDateTime();
-        }
-        return $effectiveTrigger;
-
-    }
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param \DateTime $start
-     * @param \DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        $effectiveTrigger = $this->getEffectiveTriggerTime();
-
-        if (isset($this->DURATION)) {
-            $duration = VObject\DateTimeParser::parseDuration($this->DURATION);
-            $repeat = (string)$this->repeat;
-            if (!$repeat) {
-                $repeat = 1;
-            }
-
-            $period = new \DatePeriod($effectiveTrigger, $duration, (int)$repeat);
-
-            foreach($period as $occurrence) {
-
-                if ($start <= $occurrence && $end > $occurrence) {
-                    return true;
-                }
-            }
-            return false;
-        } else {
-            return ($start <= $effectiveTrigger && $end > $effectiveTrigger);
-        }
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VCalendar.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,244 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * The VCalendar component
- *
- * This component adds functionality to a component, specific for a VCALENDAR.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VCalendar extends VObject\Document {
-
-    static $defaultName = 'VCALENDAR';
-
-    /**
-     * Returns a list of all 'base components'. For instance, if an Event has
-     * a recurrence rule, and one instance is overridden, the overridden event
-     * will have the same UID, but will be excluded from this list.
-     *
-     * VTIMEZONE components will always be excluded.
-     *
-     * @param string $componentName filter by component name
-     * @return array
-     */
-    public function getBaseComponents($componentName = null) {
-
-        $components = array();
-        foreach($this->children as $component) {
-
-            if (!$component instanceof VObject\Component)
-                continue;
-
-            if (isset($component->{'RECURRENCE-ID'}))
-                continue;
-
-            if ($componentName && $component->name !== strtoupper($componentName))
-                continue;
-
-            if ($component->name === 'VTIMEZONE')
-                continue;
-
-            $components[] = $component;
-
-        }
-
-        return $components;
-
-    }
-
-    /**
-     * If this calendar object, has events with recurrence rules, this method
-     * can be used to expand the event into multiple sub-events.
-     *
-     * Each event will be stripped from it's recurrence information, and only
-     * the instances of the event in the specified timerange will be left
-     * alone.
-     *
-     * In addition, this method will cause timezone information to be stripped,
-     * and normalized to UTC.
-     *
-     * This method will alter the VCalendar. This cannot be reversed.
-     *
-     * This functionality is specifically used by the CalDAV standard. It is
-     * possible for clients to request expand events, if they are rather simple
-     * clients and do not have the possibility to calculate recurrences.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return void
-     */
-    public function expand(\DateTime $start, \DateTime $end) {
-
-        $newEvents = array();
-
-        foreach($this->select('VEVENT') as $key=>$vevent) {
-
-            if (isset($vevent->{'RECURRENCE-ID'})) {
-                unset($this->children[$key]);
-                continue;
-            }
-
-
-            if (!$vevent->rrule) {
-                unset($this->children[$key]);
-                if ($vevent->isInTimeRange($start, $end)) {
-                    $newEvents[] = $vevent;
-                }
-                continue;
-            }
-
-            $uid = (string)$vevent->uid;
-            if (!$uid) {
-                throw new \LogicException('Event did not have a UID!');
-            }
-
-            $it = new VObject\RecurrenceIterator($this, $vevent->uid);
-            $it->fastForward($start);
-
-            while($it->valid() && $it->getDTStart() < $end) {
-
-                if ($it->getDTEnd() > $start) {
-
-                    $newEvents[] = $it->getEventObject();
-
-                }
-                $it->next();
-
-            }
-            unset($this->children[$key]);
-
-        }
-
-        foreach($newEvents as $newEvent) {
-
-            foreach($newEvent->children as $child) {
-                if ($child instanceof VObject\Property\DateTime &&
-                    $child->getDateType() == VObject\Property\DateTime::LOCALTZ) {
-                        $child->setDateTime($child->getDateTime(),VObject\Property\DateTime::UTC);
-                    }
-            }
-
-            $this->add($newEvent);
-
-        }
-
-        // Removing all VTIMEZONE components
-        unset($this->VTIMEZONE);
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @return array
-     */
-    /*
-    public function validate() {
-
-        $warnings = array();
-
-        $version = $this->select('VERSION');
-        if (count($version)!==1) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'The VERSION property must appear in the VCALENDAR component exactly 1 time',
-                'node' => $this,
-            );
-        } else {
-            if ((string)$this->VERSION !== '2.0') {
-                $warnings[] = array(
-                    'level' => 1,
-                    'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
-                    'node' => $this,
-                );
-            }
-        }
-        $version = $this->select('PRODID');
-        if (count($version)!==1) {
-            $warnings[] = array(
-                'level' => 2,
-                'message' => 'The PRODID property must appear in the VCALENDAR component exactly 1 time',
-                'node' => $this,
-            );
-        }
-        if (count($this->CALSCALE) > 1) {
-            $warnings[] = array(
-                'level' => 2,
-                'message' => 'The CALSCALE property must not be specified more than once.',
-                'node' => $this,
-            );
-        }
-        if (count($this->METHOD) > 1) {
-            $warnings[] = array(
-                'level' => 2,
-                'message' => 'The METHOD property must not be specified more than once.',
-                'node' => $this,
-            );
-        }
-
-        $allowedComponents = array(
-            'VEVENT',
-            'VTODO',
-            'VJOURNAL',
-            'VFREEBUSY',
-            'VTIMEZONE',
-        );
-        $allowedProperties = array(
-            'PRODID',
-            'VERSION',
-            'CALSCALE',
-            'METHOD',
-        );
-        $componentsFound = 0;
-        foreach($this->children as $child) {
-            if($child instanceof Component) {
-                $componentsFound++;
-                if (!in_array($child->name, $allowedComponents)) {
-                    $warnings[] = array(
-                        'level' => 1,
-                        'message' => 'The ' . $child->name . " component is not allowed in the VCALENDAR component",
-                        'node' => $this,
-                    );
-                }
-            }
-            if ($child instanceof Property) {
-                if (!in_array($child->name, $allowedProperties)) {
-                    $warnings[] = array(
-                        'level' => 2,
-                        'message' => 'The ' . $child->name . " property is not allowed in the VCALENDAR component",
-                        'node' => $this,
-                    );
-                }
-            }
-        }
-
-        if ($componentsFound===0) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'An iCalendar object must have at least 1 component.',
-                'node' => $this,
-            );
-        }
-
-        return array_merge(
-            $warnings,
-            parent::validate()
-        );
-
-    }
-     */
-
-}
-
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VCard.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * The VCard component
- *
- * This component represents the BEGIN:VCARD and END:VCARD found in every
- * vcard.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VCard extends VObject\Component {
-
-    static $defaultName = 'VCARD';
-
-    /**
-     * VCards with version 2.1, 3.0 and 4.0 are found.
-     *
-     * If the VCARD doesn't know its version, 4.0 is assumed.
-     */
-    const DEFAULT_VERSION = '4.0';
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   - Node::REPAIR - If something is broken, and automatic repair may
-     *                    be attempted.
-     *
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $warnings = array();
-
-        $version = $this->select('VERSION');
-        if (count($version)!==1) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'The VERSION property must appear in the VCARD component exactly 1 time',
-                'node' => $this,
-            );
-            if ($options & self::REPAIR) {
-                $this->VERSION = self::DEFAULT_VERSION;
-            }
-        } else {
-            $version = (string)$this->VERSION;
-            if ($version!=='2.1' && $version!=='3.0' && $version!=='4.0') {
-                $warnings[] = array(
-                    'level' => 1,
-                    'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
-                    'node' => $this,
-                );
-                if ($options & self::REPAIR) {
-                    $this->VERSION = '4.0';
-                }
-            }
-
-        }
-        $fn = $this->select('FN');
-        if (count($fn)!==1) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'The FN property must appear in the VCARD component exactly 1 time',
-                'node' => $this,
-            );
-            if (($options & self::REPAIR) && count($fn) === 0) {
-                // We're going to try to see if we can use the contents of the
-                // N property.
-                if (isset($this->N)) {
-                    $value = explode(';', (string)$this->N);
-                    if (isset($value[1]) && $value[1]) {
-                        $this->FN = $value[1] . ' ' . $value[0];
-                    } else {
-                        $this->FN = $value[0];
-                    }
-
-                // Otherwise, the ORG property may work
-                } elseif (isset($this->ORG)) {
-                    $this->FN = (string)$this->ORG;
-                }
-
-            }
-        }
-
-        return array_merge(
-            parent::validate($options),
-            $warnings
-        );
-
-    }
-
-}
-
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VEvent.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-use Sabre\VObject;
-
-/**
- * VEvent component
- *
- * This component contains some additional functionality specific for VEVENT's.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VEvent extends VObject\Component {
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param \DateTime $start
-     * @param \DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        if ($this->RRULE) {
-            $it = new VObject\RecurrenceIterator($this);
-            $it->fastForward($start);
-
-            // We fast-forwarded to a spot where the end-time of the
-            // recurrence instance exceeded the start of the requested
-            // time-range.
-            //
-            // If the starttime of the recurrence did not exceed the
-            // end of the time range as well, we have a match.
-            return ($it->getDTStart() < $end && $it->getDTEnd() > $start);
-
-        }
-
-        $effectiveStart = $this->DTSTART->getDateTime();
-        if (isset($this->DTEND)) {
-
-            // The DTEND property is considered non inclusive. So for a 3 day
-            // event in july, dtstart and dtend would have to be July 1st and
-            // July 4th respectively.
-            //
-            // See:
-            // http://tools.ietf.org/html/rfc5545#page-54
-            $effectiveEnd = $this->DTEND->getDateTime();
-
-        } elseif (isset($this->DURATION)) {
-            $effectiveEnd = clone $effectiveStart;
-            $effectiveEnd->add( VObject\DateTimeParser::parseDuration($this->DURATION) );
-        } elseif ($this->DTSTART->getDateType() == VObject\Property\DateTime::DATE) {
-            $effectiveEnd = clone $effectiveStart;
-            $effectiveEnd->modify('+1 day');
-        } else {
-            $effectiveEnd = clone $effectiveStart;
-        }
-        return (
-            ($start <= $effectiveEnd) && ($end > $effectiveStart)
-        );
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VFreeBusy.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * The VFreeBusy component
- *
- * This component adds functionality to a component, specific for VFREEBUSY
- * components.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VFreeBusy extends VObject\Component {
-
-    /**
-     * Checks based on the contained FREEBUSY information, if a timeslot is
-     * available.
-     *
-     * @param DateTime $start
-     * @param Datetime $end
-     * @return bool
-     */
-    public function isFree(\DateTime $start, \Datetime $end) {
-
-        foreach($this->select('FREEBUSY') as $freebusy) {
-
-            // We are only interested in FBTYPE=BUSY (the default),
-            // FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE.
-            if (isset($freebusy['FBTYPE']) && strtoupper(substr((string)$freebusy['FBTYPE'],0,4))!=='BUSY') {
-                continue;
-            }
-
-            // The freebusy component can hold more than 1 value, separated by
-            // commas.
-            $periods = explode(',', (string)$freebusy);
-
-            foreach($periods as $period) {
-                // Every period is formatted as [start]/[end]. The start is an
-                // absolute UTC time, the end may be an absolute UTC time, or
-                // duration (relative) value.
-                list($busyStart, $busyEnd) = explode('/', $period);
-
-                $busyStart = VObject\DateTimeParser::parse($busyStart);
-                $busyEnd = VObject\DateTimeParser::parse($busyEnd);
-                if ($busyEnd instanceof \DateInterval) {
-                    $tmp = clone $busyStart;
-                    $tmp->add($busyEnd);
-                    $busyEnd = $tmp;
-                }
-
-                if($start < $busyEnd && $end > $busyStart) {
-                    return false;
-                }
-
-            }
-
-        }
-
-        return true;
-
-    }
-
-}
-
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VJournal.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * VJournal component
- *
- * This component contains some additional functionality specific for VJOURNALs.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VJournal extends VObject\Component {
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
-        if ($dtstart) {
-            $effectiveEnd = clone $dtstart;
-            if ($this->DTSTART->getDateType() == VObject\Property\DateTime::DATE) {
-                $effectiveEnd->modify('+1 day');
-            }
-
-            return ($start <= $effectiveEnd && $end > $dtstart);
-
-        }
-        return false;
-
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Component/VTodo.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * VTodo component
- *
- * This component contains some additional functionality specific for VTODOs.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VTodo extends VObject\Component {
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
-        $duration = isset($this->DURATION)?VObject\DateTimeParser::parseDuration($this->DURATION):null;
-        $due = isset($this->DUE)?$this->DUE->getDateTime():null;
-        $completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null;
-        $created = isset($this->CREATED)?$this->CREATED->getDateTime():null;
-
-        if ($dtstart) {
-            if ($duration) {
-                $effectiveEnd = clone $dtstart;
-                $effectiveEnd->add($duration);
-                return $start <= $effectiveEnd && $end > $dtstart;
-            } elseif ($due) {
-                return
-                    ($start < $due || $start <= $dtstart) &&
-                    ($end > $dtstart || $end >= $due);
-            } else {
-                return $start <= $dtstart && $end > $dtstart;
-            }
-        }
-        if ($due) {
-            return ($start < $due && $end >= $due);
-        }
-        if ($completed && $created) {
-            return
-                ($start <= $created || $start <= $completed) &&
-                ($end >= $created || $end >= $completed);
-        }
-        if ($completed) {
-            return ($start <= $completed && $end >= $completed);
-        }
-        if ($created) {
-            return ($end > $created);
-        }
-        return true;
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/DateTimeParser.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * DateTimeParser
- *
- * This class is responsible for parsing the several different date and time
- * formats iCalendar and vCards have.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class DateTimeParser {
-
-    /**
-     * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
-     *
-     * Specifying a reference timezone is optional. It will only be used
-     * if the non-UTC format is used. The argument is used as a reference, the
-     * returned DateTime object will still be in the UTC timezone.
-     *
-     * @param string $dt
-     * @param DateTimeZone $tz
-     * @return DateTime
-     */
-    static public function parseDateTime($dt,\DateTimeZone $tz = null) {
-
-        // Format is YYYYMMDD + "T" + hhmmss
-        $result = preg_match('/^([1-4][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
-
-        if (!$result) {
-            throw new \LogicException('The supplied iCalendar datetime value is incorrect: ' . $dt);
-        }
-
-        if ($matches[7]==='Z' || is_null($tz)) {
-            $tz = new \DateTimeZone('UTC');
-        }
-        $date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
-
-        // Still resetting the timezone, to normalize everything to UTC
-        $date->setTimeZone(new \DateTimeZone('UTC'));
-        return $date;
-
-    }
-
-    /**
-     * Parses an iCalendar (rfc5545) formatted date and returns a DateTime object
-     *
-     * @param string $date
-     * @return DateTime
-     */
-    static public function parseDate($date) {
-
-        // Format is YYYYMMDD
-        $result = preg_match('/^([1-4][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
-
-        if (!$result) {
-            throw new \LogicException('The supplied iCalendar date value is incorrect: ' . $date);
-        }
-
-        $date = new \DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new \DateTimeZone('UTC'));
-        return $date;
-
-    }
-
-    /**
-     * Parses an iCalendar (RFC5545) formatted duration value.
-     *
-     * This method will either return a DateTimeInterval object, or a string
-     * suitable for strtotime or DateTime::modify.
-     *
-     * @param string $duration
-     * @param bool $asString
-     * @return DateInterval|string
-     */
-    static public function parseDuration($duration, $asString = false) {
-
-        $result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
-        if (!$result) {
-            throw new \LogicException('The supplied iCalendar duration value is incorrect: ' . $duration);
-        }
-
-        if (!$asString) {
-            $invert = false;
-            if ($matches['plusminus']==='-') {
-                $invert = true;
-            }
-
-
-            $parts = array(
-                'week',
-                'day',
-                'hour',
-                'minute',
-                'second',
-            );
-            foreach($parts as $part) {
-                $matches[$part] = isset($matches[$part])&&$matches[$part]?(int)$matches[$part]:0;
-            }
-
-
-            // We need to re-construct the $duration string, because weeks and
-            // days are not supported by DateInterval in the same string.
-            $duration = 'P';
-            $days = $matches['day'];
-            if ($matches['week']) {
-                $days+=$matches['week']*7;
-            }
-            if ($days)
-                $duration.=$days . 'D';
-
-            if ($matches['minute'] || $matches['second'] || $matches['hour']) {
-                $duration.='T';
-
-                if ($matches['hour'])
-                    $duration.=$matches['hour'].'H';
-
-                if ($matches['minute'])
-                    $duration.=$matches['minute'].'M';
-
-                if ($matches['second'])
-                    $duration.=$matches['second'].'S';
-
-            }
-
-            if ($duration==='P') {
-                $duration = 'PT0S';
-            }
-            $iv = new \DateInterval($duration);
-            if ($invert) $iv->invert = true;
-
-            return $iv;
-
-        }
-
-
-
-        $parts = array(
-            'week',
-            'day',
-            'hour',
-            'minute',
-            'second',
-        );
-
-        $newDur = '';
-        foreach($parts as $part) {
-            if (isset($matches[$part]) && $matches[$part]) {
-                $newDur.=' '.$matches[$part] . ' ' . $part . 's';
-            }
-        }
-
-        $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
-        if ($newDur === '+') { $newDur = '+0 seconds'; };
-        return $newDur;
-
-    }
-
-    /**
-     * Parses either a Date or DateTime, or Duration value.
-     *
-     * @param string $date
-     * @param DateTimeZone|string $referenceTZ
-     * @return DateTime|DateInterval
-     */
-    static public function parse($date, $referenceTZ = null) {
-
-        if ($date[0]==='P' || ($date[0]==='-' && $date[1]==='P')) {
-            return self::parseDuration($date);
-        } elseif (strlen($date)===8) {
-            return self::parseDate($date);
-        } else {
-            return self::parseDateTime($date, $referenceTZ);
-        }
-
-    }
-
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Document.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Document
- *
- * A document is just like a component, except that it's also the top level
- * element.
- *
- * Both a VCALENDAR and a VCARD are considered documents.
- *
- * This class also provides a registry for document types.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH. All rights reserved.
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-abstract class Document extends Component {
-
-    /**
-     * The default name for this component.
-     *
-     * This should be 'VCALENDAR' or 'VCARD'.
-     *
-     * @var string
-     */
-    static $defaultName;
-
-    /**
-     * Creates a new document.
-     *
-     * We're changing the default behavior slightly here. First, we don't want
-     * to have to specify a name (we already know it), and we want to allow
-     * children to be specified in the first argument.
-     *
-     * But, the default behavior also works.
-     *
-     * So the two sigs:
-     *
-     * new Document(array $children = array());
-     * new Document(string $name, array $children = array())
-     *
-     * @return void
-     */
-    public function __construct() {
-
-        $args = func_get_args();
-        if (count($args)===0 || is_array($args[0])) {
-            array_unshift($args, static::$defaultName);
-            call_user_func_array(array('parent', '__construct'), $args);
-        } else {
-            call_user_func_array(array('parent', '__construct'), $args);
-        }
-
-    }
-
-    /**
-     * Creates a new component
-     *
-     * This method automatically searches for the correct component class, based
-     * on its name.
-     *
-     * You can specify the children either in key=>value syntax, in which case
-     * properties will automatically be created, or you can just pass a list of
-     * Component and Property object.
-     *
-     * @param string $name
-     * @param array $children
-     * @return Component
-     */
-    public function createComponent($name, array $children = array()) {
-
-        $component = Component::create($name);
-        foreach($children as $k=>$v) {
-
-            if ($v instanceof Node) {
-                $component->add($v);
-            } else {
-                $component->add($k, $v);
-            }
-
-        }
-        return $component;
-
-    }
-
-    /**
-     * Factory method for creating new properties
-     *
-     * This method automatically searches for the correct property class, based
-     * on its name.
-     *
-     * You can specify the parameters either in key=>value syntax, in which case
-     * parameters will automatically be created, or you can just pass a list of
-     * Parameter objects.
-     *
-     * @param string $name
-     * @param mixed $value
-     * @param array $parameters
-     * @return Property
-     */
-    public function createProperty($name, $value = null, array $parameters = array()) {
-
-        return Property::create($name, $value, $parameters);
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/ElementList.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * VObject ElementList
- *
- * This class represents a list of elements. Lists are the result of queries,
- * such as doing $vcalendar->vevent where there's multiple VEVENT objects.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class ElementList implements \Iterator, \Countable, \ArrayAccess {
-
-    /**
-     * Inner elements
-     *
-     * @var array
-     */
-    protected $elements = array();
-
-    /**
-     * Creates the element list.
-     *
-     * @param array $elements
-     */
-    public function __construct(array $elements) {
-
-        $this->elements = $elements;
-
-    }
-
-    /* {{{ Iterator interface */
-
-    /**
-     * Current position
-     *
-     * @var int
-     */
-    private $key = 0;
-
-    /**
-     * Returns current item in iteration
-     *
-     * @return Element
-     */
-    public function current() {
-
-        return $this->elements[$this->key];
-
-    }
-
-    /**
-     * To the next item in the iterator
-     *
-     * @return void
-     */
-    public function next() {
-
-        $this->key++;
-
-    }
-
-    /**
-     * Returns the current iterator key
-     *
-     * @return int
-     */
-    public function key() {
-
-        return $this->key;
-
-    }
-
-    /**
-     * Returns true if the current position in the iterator is a valid one
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        return isset($this->elements[$this->key]);
-
-    }
-
-    /**
-     * Rewinds the iterator
-     *
-     * @return void
-     */
-    public function rewind() {
-
-        $this->key = 0;
-
-    }
-
-    /* }}} */
-
-    /* {{{ Countable interface */
-
-    /**
-     * Returns the number of elements
-     *
-     * @return int
-     */
-    public function count() {
-
-        return count($this->elements);
-
-    }
-
-    /* }}} */
-
-    /* {{{ ArrayAccess Interface */
-
-
-    /**
-     * Checks if an item exists through ArrayAccess.
-     *
-     * @param int $offset
-     * @return bool
-     */
-    public function offsetExists($offset) {
-
-        return isset($this->elements[$offset]);
-
-    }
-
-    /**
-     * Gets an item through ArrayAccess.
-     *
-     * @param int $offset
-     * @return mixed
-     */
-    public function offsetGet($offset) {
-
-        return $this->elements[$offset];
-
-    }
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * @param int $offset
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($offset,$value) {
-
-        throw new \LogicException('You can not add new objects to an ElementList');
-
-    }
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return void
-     */
-    public function offsetUnset($offset) {
-
-        throw new \LogicException('You can not remove objects from an ElementList');
-
-    }
-
-    /* }}} */
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/FreeBusyGenerator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,322 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This class helps with generating FREEBUSY reports based on existing sets of
- * objects.
- *
- * It only looks at VEVENT and VFREEBUSY objects from the sourcedata, and
- * generates a single VFREEBUSY object.
- *
- * VFREEBUSY components are described in RFC5545, The rules for what should
- * go in a single freebusy report is taken from RFC4791, section 7.10.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class FreeBusyGenerator {
-
-    /**
-     * Input objects
-     *
-     * @var array
-     */
-    protected $objects;
-
-    /**
-     * Start of range
-     *
-     * @var DateTime|null
-     */
-    protected $start;
-
-    /**
-     * End of range
-     *
-     * @var DateTime|null
-     */
-    protected $end;
-
-    /**
-     * VCALENDAR object
-     *
-     * @var Component
-     */
-    protected $baseObject;
-
-    /**
-     * Creates the generator.
-     *
-     * Check the setTimeRange and setObjects methods for details about the
-     * arguments.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @param mixed $objects
-     * @return void
-     */
-    public function __construct(\DateTime $start = null, \DateTime $end = null, $objects = null) {
-
-        if ($start && $end) {
-            $this->setTimeRange($start, $end);
-        }
-
-        if ($objects) {
-            $this->setObjects($objects);
-        }
-
-    }
-
-    /**
-     * Sets the VCALENDAR object.
-     *
-     * If this is set, it will not be generated for you. You are responsible
-     * for setting things like the METHOD, CALSCALE, VERSION, etc..
-     *
-     * The VFREEBUSY object will be automatically added though.
-     *
-     * @param Component $vcalendar
-     * @return void
-     */
-    public function setBaseObject(Component $vcalendar) {
-
-        $this->baseObject = $vcalendar;
-
-    }
-
-    /**
-     * Sets the input objects
-     *
-     * You must either specify a valendar object as a strong, or as the parse
-     * Component.
-     * It's also possible to specify multiple objects as an array.
-     *
-     * @param mixed $objects
-     * @return void
-     */
-    public function setObjects($objects) {
-
-        if (!is_array($objects)) {
-            $objects = array($objects);
-        }
-
-        $this->objects = array();
-        foreach($objects as $object) {
-
-            if (is_string($object)) {
-                $this->objects[] = Reader::read($object);
-            } elseif ($object instanceof Component) {
-                $this->objects[] = $object;
-            } else {
-                throw new \InvalidArgumentException('You can only pass strings or \\Sabre\\VObject\\Component arguments to setObjects');
-            }
-
-        }
-
-    }
-
-    /**
-     * Sets the time range
-     *
-     * Any freebusy object falling outside of this time range will be ignored.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return void
-     */
-    public function setTimeRange(\DateTime $start = null, \DateTime $end = null) {
-
-        $this->start = $start;
-        $this->end = $end;
-
-    }
-
-    /**
-     * Parses the input data and returns a correct VFREEBUSY object, wrapped in
-     * a VCALENDAR.
-     *
-     * @return Component
-     */
-    public function getResult() {
-
-        $busyTimes = array();
-
-        foreach($this->objects as $object) {
-
-            foreach($object->getBaseComponents() as $component) {
-
-                switch($component->name) {
-
-                    case 'VEVENT' :
-
-                        $FBTYPE = 'BUSY';
-                        if (isset($component->TRANSP) && (strtoupper($component->TRANSP) === 'TRANSPARENT')) {
-                            break;
-                        }
-                        if (isset($component->STATUS)) {
-                            $status = strtoupper($component->STATUS);
-                            if ($status==='CANCELLED') {
-                                break;
-                            }
-                            if ($status==='TENTATIVE') {
-                                $FBTYPE = 'BUSY-TENTATIVE';
-                            }
-                        }
-
-                        $times = array();
-
-                        if ($component->RRULE) {
-
-                            $iterator = new RecurrenceIterator($object, (string)$component->uid);
-                            if ($this->start) {
-                                $iterator->fastForward($this->start);
-                            }
-
-                            $maxRecurrences = 200;
-
-                            while($iterator->valid() && --$maxRecurrences) {
-
-                                $startTime = $iterator->getDTStart();
-                                if ($this->end && $startTime > $this->end) {
-                                    break;
-                                }
-                                $times[] = array(
-                                    $iterator->getDTStart(),
-                                    $iterator->getDTEnd(),
-                                );
-
-                                $iterator->next();
-
-                            }
-
-                        } else {
-
-                            $startTime = $component->DTSTART->getDateTime();
-                            if ($this->end && $startTime > $this->end) {
-                                break;
-                            }
-                            $endTime = null;
-                            if (isset($component->DTEND)) {
-                                $endTime = $component->DTEND->getDateTime();
-                            } elseif (isset($component->DURATION)) {
-                                $duration = DateTimeParser::parseDuration((string)$component->DURATION);
-                                $endTime = clone $startTime;
-                                $endTime->add($duration);
-                            } elseif ($component->DTSTART->getDateType() === Property\DateTime::DATE) {
-                                $endTime = clone $startTime;
-                                $endTime->modify('+1 day');
-                            } else {
-                                // The event had no duration (0 seconds)
-                                break;
-                            }
-
-                            $times[] = array($startTime, $endTime);
-
-                        }
-
-                        foreach($times as $time) {
-
-                            if ($this->end && $time[0] > $this->end) break;
-                            if ($this->start && $time[1] < $this->start) break;
-
-                            $busyTimes[] = array(
-                                $time[0],
-                                $time[1],
-                                $FBTYPE,
-                            );
-                        }
-                        break;
-
-                    case 'VFREEBUSY' :
-                        foreach($component->FREEBUSY as $freebusy) {
-
-                            $fbType = isset($freebusy['FBTYPE'])?strtoupper($freebusy['FBTYPE']):'BUSY';
-
-                            // Skipping intervals marked as 'free'
-                            if ($fbType==='FREE')
-                                continue;
-
-                            $values = explode(',', $freebusy);
-                            foreach($values as $value) {
-                                list($startTime, $endTime) = explode('/', $value);
-                                $startTime = DateTimeParser::parseDateTime($startTime);
-
-                                if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
-                                    $duration = DateTimeParser::parseDuration($endTime);
-                                    $endTime = clone $startTime;
-                                    $endTime->add($duration);
-                                } else {
-                                    $endTime = DateTimeParser::parseDateTime($endTime);
-                                }
-
-                                if($this->start && $this->start > $endTime) continue;
-                                if($this->end && $this->end < $startTime) continue;
-                                $busyTimes[] = array(
-                                    $startTime,
-                                    $endTime,
-                                    $fbType
-                                );
-
-                            }
-
-
-                        }
-                        break;
-
-
-
-                }
-
-
-            }
-
-        }
-
-        if ($this->baseObject) {
-            $calendar = $this->baseObject;
-        } else {
-            $calendar = Component::create('VCALENDAR');
-            $calendar->version = '2.0';
-            $calendar->prodid = '-//Sabre//Sabre VObject ' . Version::VERSION . '//EN';
-            $calendar->calscale = 'GREGORIAN';
-        }
-
-        $vfreebusy = Component::create('VFREEBUSY');
-        $calendar->add($vfreebusy);
-
-        if ($this->start) {
-            $dtstart = Property::create('DTSTART');
-            $dtstart->setDateTime($this->start,Property\DateTime::UTC);
-            $vfreebusy->add($dtstart);
-        }
-        if ($this->end) {
-            $dtend = Property::create('DTEND');
-            $dtend->setDateTime($this->end,Property\DateTime::UTC);
-            $vfreebusy->add($dtend);
-        }
-        $dtstamp = Property::create('DTSTAMP');
-        $dtstamp->setDateTime(new \DateTime('now'), Property\DateTime::UTC);
-        $vfreebusy->add($dtstamp);
-
-        foreach($busyTimes as $busyTime) {
-
-            $busyTime[0]->setTimeZone(new \DateTimeZone('UTC'));
-            $busyTime[1]->setTimeZone(new \DateTimeZone('UTC'));
-
-            $prop = Property::create(
-                'FREEBUSY',
-                $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
-            );
-            $prop['FBTYPE'] = $busyTime[2];
-            $vfreebusy->add($prop);
-
-        }
-
-        return $calendar;
-
-    }
-
-}
-
--- a/plugins/libcalendaring/lib/Sabre/VObject/Node.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Base class for all nodes
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-abstract class Node implements \IteratorAggregate, \ArrayAccess, \Countable {
-
-    /**
-     * The following constants are used by the validate() method.
-     */
-    const REPAIR = 1;
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    abstract function serialize();
-
-    /**
-     * Iterator override
-     *
-     * @var ElementList
-     */
-    protected $iterator = null;
-
-    /**
-     * A link to the parent node
-     *
-     * @var Node
-     */
-    public $parent = null;
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   - Node::REPAIR - If something is broken, and automatic repair may
-     *                    be attempted.
-     *
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        return array();
-
-    }
-
-    /* {{{ IteratorAggregator interface */
-
-    /**
-     * Returns the iterator for this object
-     *
-     * @return ElementList
-     */
-    public function getIterator() {
-
-        if (!is_null($this->iterator))
-            return $this->iterator;
-
-        return new ElementList(array($this));
-
-    }
-
-    /**
-     * Sets the overridden iterator
-     *
-     * Note that this is not actually part of the iterator interface
-     *
-     * @param ElementList $iterator
-     * @return void
-     */
-    public function setIterator(ElementList $iterator) {
-
-        $this->iterator = $iterator;
-
-    }
-
-    /* }}} */
-
-    /* {{{ Countable interface */
-
-    /**
-     * Returns the number of elements
-     *
-     * @return int
-     */
-    public function count() {
-
-        $it = $this->getIterator();
-        return $it->count();
-
-    }
-
-    /* }}} */
-
-    /* {{{ ArrayAccess Interface */
-
-
-    /**
-     * Checks if an item exists through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return bool
-     */
-    public function offsetExists($offset) {
-
-        $iterator = $this->getIterator();
-        return $iterator->offsetExists($offset);
-
-    }
-
-    /**
-     * Gets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return mixed
-     */
-    public function offsetGet($offset) {
-
-        $iterator = $this->getIterator();
-        return $iterator->offsetGet($offset);
-
-    }
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($offset,$value) {
-
-        $iterator = $this->getIterator();
-        $iterator->offsetSet($offset,$value);
-
-    // @codeCoverageIgnoreStart
-    //
-    // This method always throws an exception, so we ignore the closing
-    // brace
-    }
-    // @codeCoverageIgnoreEnd
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return void
-     */
-    public function offsetUnset($offset) {
-
-        $iterator = $this->getIterator();
-        $iterator->offsetUnset($offset);
-
-    // @codeCoverageIgnoreStart
-    //
-    // This method always throws an exception, so we ignore the closing
-    // brace
-    }
-    // @codeCoverageIgnoreEnd
-
-    /* }}} */
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Parameter.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * VObject Parameter
- *
- * This class represents a parameter. A parameter is always tied to a property.
- * In the case of:
- *   DTSTART;VALUE=DATE:20101108
- * VALUE=DATE would be the parameter name and value.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Parameter extends Node {
-
-    /**
-     * Parameter name
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * Parameter value
-     *
-     * @var string
-     */
-    public $value;
-
-    /**
-     * Sets up the object
-     *
-     * @param string $name
-     * @param string $value
-     */
-    public function __construct($name, $value = null) {
-
-        if (!is_scalar($value) && !is_null($value)) {
-            throw new \InvalidArgumentException('The value argument must be a scalar value or null');
-        }
-
-        $this->name = strtoupper($name);
-        $this->value = $value;
-
-    }
-
-    /**
-     * Returns the parameter's internal value.
-     *
-     * @return string
-     */
-    public function getValue() {
-
-        return $this->value;
-
-    }
-
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    public function serialize() {
-
-        if (is_null($this->value)) {
-            return $this->name;
-        }
-        $src = array(
-            '\\',
-            "\n",
-        );
-        $out = array(
-            '\\\\',
-            '\n',
-        );
-
-        // quote parameters according to RFC 5545, Section 3.2
-        $quotes = '';
-        if (preg_match('/[:;,]/', $this->value)) {
-            $quotes = '"';
-        }
-
-        return $this->name . '=' . $quotes . str_replace($src, $out, $this->value) . $quotes;
-
-    }
-
-    /**
-     * Called when this object is being cast to a string
-     *
-     * @return string
-     */
-    public function __toString() {
-
-        return $this->value;
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/ParseException.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Exception thrown by Reader if an invalid object was attempted to be parsed.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class ParseException extends \Exception { }
--- a/plugins/libcalendaring/lib/Sabre/VObject/Property.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * VObject Property
- *
- * A property in VObject is usually in the form PARAMNAME:paramValue.
- * An example is : SUMMARY:Weekly meeting
- *
- * Properties can also have parameters:
- * SUMMARY;LANG=en:Weekly meeting.
- *
- * Parameters can be accessed using the ArrayAccess interface.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Property extends Node {
-
-    /**
-     * Propertyname
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * Group name
-     *
-     * This may be something like 'HOME' for vcards.
-     *
-     * @var string
-     */
-    public $group;
-
-    /**
-     * Property parameters
-     *
-     * @var array
-     */
-    public $parameters = array();
-
-    /**
-     * Property value
-     *
-     * @var string
-     */
-    public $value;
-
-    /**
-     * If properties are added to this map, they will be automatically mapped
-     * to their respective classes, if parsed by the reader or constructed with
-     * the 'create' method.
-     *
-     * @var array
-     */
-    static public $classMap = array(
-        'COMPLETED'     => 'Sabre\\VObject\\Property\\DateTime',
-        'CREATED'       => 'Sabre\\VObject\\Property\\DateTime',
-        'DTEND'         => 'Sabre\\VObject\\Property\\DateTime',
-        'DTSTAMP'       => 'Sabre\\VObject\\Property\\DateTime',
-        'DTSTART'       => 'Sabre\\VObject\\Property\\DateTime',
-        'DUE'           => 'Sabre\\VObject\\Property\\DateTime',
-        'EXDATE'        => 'Sabre\\VObject\\Property\\MultiDateTime',
-        'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\DateTime',
-        'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\DateTime',
-        'TRIGGER'       => 'Sabre\\VObject\\Property\\DateTime',
-        'N'             => 'Sabre\\VObject\\Property\\Compound',
-        'ORG'           => 'Sabre\\VObject\\Property\\Compound',
-        'ADR'           => 'Sabre\\VObject\\Property\\Compound',
-        'CATEGORIES'    => 'Sabre\\VObject\\Property\\Compound',
-    );
-
-    /**
-     * Creates the new property by name, but in addition will also see if
-     * there's a class mapped to the property name.
-     *
-     * Parameters can be specified with the optional third argument. Parameters
-     * must be a key->value map of the parameter name, and value. If the value
-     * is specified as an array, it is assumed that multiple parameters with
-     * the same name should be added.
-     *
-     * @param string $name
-     * @param string $value
-     * @param array $parameters
-     * @return Property
-     */
-    static public function create($name, $value = null, array $parameters = array()) {
-
-        $name = strtoupper($name);
-        $shortName = $name;
-        $group = null;
-        if (strpos($shortName,'.')!==false) {
-            list($group, $shortName) = explode('.', $shortName);
-        }
-
-        if (isset(self::$classMap[$shortName])) {
-            return new self::$classMap[$shortName]($name, $value, $parameters);
-        } else {
-            return new self($name, $value, $parameters);
-        }
-
-    }
-
-    /**
-     * Creates a new property object
-     *
-     * Parameters can be specified with the optional third argument. Parameters
-     * must be a key->value map of the parameter name, and value. If the value
-     * is specified as an array, it is assumed that multiple parameters with
-     * the same name should be added.
-     *
-     * @param string $name
-     * @param string $value
-     * @param array $parameters
-     */
-    public function __construct($name, $value = null, array $parameters = array()) {
-
-        if (!is_scalar($value) && !is_null($value)) {
-            throw new \InvalidArgumentException('The value argument must be scalar or null');
-        }
-
-        $name = strtoupper($name);
-        $group = null;
-        if (strpos($name,'.')!==false) {
-            list($group, $name) = explode('.', $name);
-        }
-        $this->name = $name;
-        $this->group = $group;
-        $this->setValue($value);
-
-        foreach($parameters as $paramName => $paramValues) {
-
-            if (!is_array($paramValues)) {
-                $paramValues = array($paramValues);
-            }
-
-            foreach($paramValues as $paramValue) {
-                $this->add($paramName, $paramValue);
-            }
-
-        }
-
-    }
-
-    /**
-     * Updates the internal value
-     *
-     * @param string $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        $this->value = $value;
-
-    }
-
-    /**
-     * Returns the internal value
-     *
-     * @param string $value
-     * @return string
-     */
-    public function getValue() {
-
-        return $this->value;
-
-    }
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    public function serialize() {
-
-        $str = $this->name;
-        if ($this->group) $str = $this->group . '.' . $this->name;
-
-        foreach($this->parameters as $param) {
-
-            $str.=';' . $param->serialize();
-
-        }
-
-        $src = array(
-            '\\',
-            "\n",
-            "\r",
-        );
-        $out = array(
-            '\\\\',
-            '\n',
-            '',
-        );
-
-        // avoid double-escaping of \, and \; from Compound properties
-        if (method_exists($this, 'setParts')) {
-            $src[] = '\\\\,';
-            $out[] = '\\,';
-            $src[] = '\\\\;';
-            $out[] = '\\;';
-        }
-
-        $str.=':' . str_replace($src, $out, $this->value);
-
-        $out = '';
-        while(strlen($str)>0) {
-            if (strlen($str)>75) {
-                $out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
-                $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
-            } else {
-                $out.=$str . "\r\n";
-                $str='';
-                break;
-            }
-        }
-
-        return $out;
-
-    }
-
-    /**
-     * Adds a new componenten or element
-     *
-     * You can call this method with the following syntaxes:
-     *
-     * add(Parameter $element)
-     * add(string $name, $value)
-     *
-     * The first version adds an Parameter
-     * The second adds a property as a string.
-     *
-     * @param mixed $item
-     * @param mixed $itemValue
-     * @return void
-     */
-    public function add($item, $itemValue = null) {
-
-        if ($item instanceof Parameter) {
-            if (!is_null($itemValue)) {
-                throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject');
-            }
-            $item->parent = $this;
-            $this->parameters[] = $item;
-        } elseif(is_string($item)) {
-
-            $parameter = new Parameter($item,$itemValue);
-            $parameter->parent = $this;
-            $this->parameters[] = $parameter;
-
-        } else {
-
-            throw new \InvalidArgumentException('The first argument must either be a Node a string');
-
-        }
-
-    }
-
-    /* ArrayAccess interface {{{ */
-
-    /**
-     * Checks if an array element exists
-     *
-     * @param mixed $name
-     * @return bool
-     */
-    public function offsetExists($name) {
-
-        if (is_int($name)) return parent::offsetExists($name);
-
-        $name = strtoupper($name);
-
-        foreach($this->parameters as $parameter) {
-            if ($parameter->name == $name) return true;
-        }
-        return false;
-
-    }
-
-    /**
-     * Returns a parameter, or parameter list.
-     *
-     * @param string $name
-     * @return Node
-     */
-    public function offsetGet($name) {
-
-        if (is_int($name)) return parent::offsetGet($name);
-        $name = strtoupper($name);
-
-        $result = array();
-        foreach($this->parameters as $parameter) {
-            if ($parameter->name == $name)
-                $result[] = $parameter;
-        }
-
-        if (count($result)===0) {
-            return null;
-        } elseif (count($result)===1) {
-            return $result[0];
-        } else {
-            $result[0]->setIterator(new ElementList($result));
-            return $result[0];
-        }
-
-    }
-
-    /**
-     * Creates a new parameter
-     *
-     * @param string $name
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($name, $value) {
-
-        if (is_int($name)) parent::offsetSet($name, $value);
-
-        if (is_scalar($value)) {
-            if (!is_string($name))
-                throw new \InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
-
-            $this->offsetUnset($name);
-            $parameter = new Parameter($name, $value);
-            $parameter->parent = $this;
-            $this->parameters[] = $parameter;
-
-        } elseif ($value instanceof Parameter) {
-            if (!is_null($name))
-                throw new \InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a \\Sabre\\VObject\\Parameter. Add using $array[]=$parameterObject.');
-
-            $value->parent = $this;
-            $this->parameters[] = $value;
-        } else {
-            throw new \InvalidArgumentException('You can only add parameters to the property object');
-        }
-
-    }
-
-    /**
-     * Removes one or more parameters with the specified name
-     *
-     * @param string $name
-     * @return void
-     */
-    public function offsetUnset($name) {
-
-        if (is_int($name)) parent::offsetUnset($name);
-        $name = strtoupper($name);
-
-        foreach($this->parameters as $key=>$parameter) {
-            if ($parameter->name == $name) {
-                $parameter->parent = null;
-                unset($this->parameters[$key]);
-            }
-
-        }
-
-    }
-
-    /* }}} */
-
-    /**
-     * Called when this object is being cast to a string
-     *
-     * @return string
-     */
-    public function __toString() {
-
-        return (string)$this->value;
-
-    }
-
-    /**
-     * This method is automatically called when the object is cloned.
-     * Specifically, this will ensure all child elements are also cloned.
-     *
-     * @return void
-     */
-    public function __clone() {
-
-        foreach($this->parameters as $key=>$child) {
-            $this->parameters[$key] = clone $child;
-            $this->parameters[$key]->parent = $this;
-        }
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   - Node::REPAIR - If something is broken, and automatic repair may
-     *                    be attempted.
-     *
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $warnings = array();
-
-        // Checking if our value is UTF-8
-        if (!StringUtil::isUTF8($this->value)) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'Property is not valid UTF-8!',
-                'node' => $this,
-            );
-            if ($options & self::REPAIR) {
-                $this->value = StringUtil::convertToUTF8($this->value);
-            }
-        }
-
-        // Checking if the propertyname does not contain any invalid bytes.
-        if (!preg_match('/^([A-Z0-9-]+)$/', $this->name)) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'The propertyname: ' . $this->name . ' contains invalid characters. Only A-Z, 0-9 and - are allowed',
-                'node' => $this,
-            );
-            if ($options & self::REPAIR) {
-                // Uppercasing and converting underscores to dashes.
-                $this->name = strtoupper(
-                    str_replace('_', '-', $this->name)
-                );
-                // Removing every other invalid character
-                $this->name = preg_replace('/([^A-Z0-9-])/u', '', $this->name);
-
-            }
-
-        }
-
-        // Validating inner parameters
-        foreach($this->parameters as $param) {
-            $warnings = array_merge($warnings, $param->validate($options));
-        }
-
-        return $warnings;
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Property/Compound.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject;
-
-/**
- * Compound property.
- *
- * This class adds (de)serialization of compound properties to/from arrays.
- *
- * Currently the following properties from RFC 6350 are mapped to use this
- * class:
- *
- *  N:          Section 6.2.2
- *  ADR:        Section 6.3.1
- *  ORG:        Section 6.6.4
- *  CATEGORIES: Section 6.7.1
- *
- * In order to use this correctly, you must call setParts and getParts to
- * retrieve and modify dates respectively.
- *
- * @author Thomas Tanghus (http://tanghus.net/)
- * @author Lars Kneschke
- * @author Evert Pot (http://evertpot.com/)
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Compound extends VObject\Property {
-
-    /**
-     * If property names are added to this map, they will be (de)serialised as arrays
-     * using the getParts() and setParts() methods.
-     * The keys are the property names, values are delimiter chars.
-     *
-     * @var array
-     */
-    static public $delimiterMap = array(
-        'N'           =>    ';',
-        'ADR'         =>    ';',
-        'ORG'         =>    ';',
-        'CATEGORIES'  =>    ',',
-    );
-
-    /**
-     * The currently used delimiter.
-     *
-     * @var string
-     */
-    protected $delimiter = null;
-
-    /**
-     * Get a compound value as an array.
-     *
-     * @param $name string
-     * @return array
-     */
-    public function getParts() {
-
-        if (is_null($this->value)) {
-            return array();
-        }
-
-        $delimiter = $this->getDelimiter();
-
-        // split by any $delimiter which is NOT prefixed by a slash.
-        // Note that this is not a a perfect solution. If a value is prefixed
-        // by two slashes, it should actually be split anyway.
-        //
-        // Hopefully we can fix this better in a future version, where we can
-        // break compatibility a bit.
-        $compoundValues = preg_split("/(?<!\\\)$delimiter/", $this->value);
-
-        // remove slashes from any semicolon and comma left escaped in the single values
-        $compoundValues = array_map(
-            function($val) {
-                return strtr($val, array('\,' => ',', '\;' => ';'));
-        }, $compoundValues);
-
-        return $compoundValues;
-
-    }
-
-    /**
-     * Returns the delimiter for this property.
-     *
-     * @return string
-     */
-    public function getDelimiter() {
-
-        if (!$this->delimiter) {
-            if (isset(self::$delimiterMap[$this->name])) {
-                $this->delimiter = self::$delimiterMap[$this->name];
-            } else {
-                // To be a bit future proof, we are going to default the
-                // delimiter to ;
-                $this->delimiter = ';';
-            }
-        }
-        return $this->delimiter;
-
-    }
-
-    /**
-     * Set a compound value as an array.
-     *
-     *
-     * @param $name string
-     * @return array
-     */
-    public function setParts(array $values) {
-
-        // add slashes to all semicolons and commas in the single values
-        $values = array_map(
-            function($val) {
-                return strtr($val, array(',' => '\,', ';' => '\;'));
-            }, $values);
-
-        $this->setValue(
-            implode($this->getDelimiter(), $values)
-        );
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Property/DateTime.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject;
-
-/**
- * DateTime property
- *
- * This element is used for iCalendar properties such as the DTSTART property.
- * It basically provides a few helper functions that make it easier to deal
- * with these. It supports both DATE-TIME and DATE values.
- *
- * In order to use this correctly, you must call setDateTime and getDateTime to
- * retrieve and modify dates respectively.
- *
- * If you use the 'value' or properties directly, this object does not keep
- * reference and results might appear incorrectly.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class DateTime extends VObject\Property {
-
-    /**
-     * Local 'floating' time
-     */
-    const LOCAL = 1;
-
-    /**
-     * UTC-based time
-     */
-    const UTC = 2;
-
-    /**
-     * Local time plus timezone
-     */
-    const LOCALTZ = 3;
-
-    /**
-     * Only a date, time is ignored
-     */
-    const DATE = 4;
-
-    /**
-     * DateTime representation
-     *
-     * @var \DateTime
-     */
-    protected $dateTime;
-
-    /**
-     * dateType
-     *
-     * @var int
-     */
-    protected $dateType;
-
-    /**
-     * Updates the Date and Time.
-     *
-     * @param \DateTime $dt
-     * @param int $dateType
-     * @return void
-     */
-    public function setDateTime(\DateTime $dt, $dateType = self::LOCALTZ) {
-
-        switch($dateType) {
-
-            case self::LOCAL :
-                $this->setValue($dt->format('Ymd\\THis'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE-TIME');
-                break;
-            case self::UTC :
-                $dt->setTimeZone(new \DateTimeZone('UTC'));
-                $this->setValue($dt->format('Ymd\\THis\\Z'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE-TIME');
-                break;
-            case self::LOCALTZ :
-                $this->setValue($dt->format('Ymd\\THis'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE-TIME');
-                $this->offsetSet('TZID', $dt->getTimeZone()->getName());
-                break;
-            case self::DATE :
-                $this->setValue($dt->format('Ymd'));
-                $this->offsetUnset('VALUE');
-                $this->offsetUnset('TZID');
-                $this->offsetSet('VALUE','DATE');
-                break;
-            default :
-                throw new \InvalidArgumentException('You must pass a valid dateType constant');
-
-        }
-        $this->dateTime = $dt;
-        $this->dateType = $dateType;
-
-    }
-
-    /**
-     * Returns the current DateTime value.
-     *
-     * If no value was set, this method returns null.
-     *
-     * @return \DateTime|null
-     */
-    public function getDateTime() {
-
-        if ($this->dateTime)
-            return $this->dateTime;
-
-        list(
-            $this->dateType,
-            $this->dateTime
-        ) = self::parseData($this->value, $this);
-        return $this->dateTime;
-
-    }
-
-    /**
-     * Returns the type of Date format.
-     *
-     * This method returns one of the format constants. If no date was set,
-     * this method will return null.
-     *
-     * @return int|null
-     */
-    public function getDateType() {
-
-        if ($this->dateType)
-            return $this->dateType;
-
-        list(
-            $this->dateType,
-            $this->dateTime,
-        ) = self::parseData($this->value, $this);
-        return $this->dateType;
-
-    }
-
-    /**
-     * This method will return true, if the property had a date and a time, as
-     * opposed to only a date.
-     *
-     * @return bool
-     */
-    public function hasTime() {
-
-        return $this->getDateType()!==self::DATE;
-
-    }
-
-    /**
-     * Parses the internal data structure to figure out what the current date
-     * and time is.
-     *
-     * The returned array contains two elements:
-     *   1. A 'DateType' constant (as defined on this class), or null.
-     *   2. A DateTime object (or null)
-     *
-     * @param string|null $propertyValue The string to parse (yymmdd or
-     *                                   ymmddThhmmss, etc..)
-     * @param \Sabre\VObject\Property|null $property The instance of the
-     *                                              property we're parsing.
-     * @return array
-     */
-    static public function parseData($propertyValue, VObject\Property $property = null) {
-
-        if (is_null($propertyValue)) {
-            return array(null, null);
-        }
-
-        $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
-        $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
-        $regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
-
-        if (!preg_match($regex, $propertyValue, $matches)) {
-            throw new \InvalidArgumentException($propertyValue . ' is not a valid \DateTime or Date string');
-        }
-
-        if (!isset($matches['hour'])) {
-            // Date-only
-            return array(
-                self::DATE,
-                new \DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00', new \DateTimeZone('UTC')),
-            );
-        }
-
-        $dateStr =
-            $matches['year'] .'-' .
-            $matches['month'] . '-' .
-            $matches['date'] . ' ' .
-            $matches['hour'] . ':' .
-            $matches['minute'] . ':' .
-            $matches['second'];
-
-        if (isset($matches['isutc'])) {
-            $dt = new \DateTime($dateStr,new \DateTimeZone('UTC'));
-            $dt->setTimeZone(new \DateTimeZone('UTC'));
-            return array(
-                self::UTC,
-                $dt
-            );
-        }
-
-        // Finding the timezone.
-        $tzid = $property['TZID'];
-        if (!$tzid) {
-            // This was a floating time string. This implies we use the
-            // timezone from date_default_timezone_set / date.timezone ini
-            // setting.
-            return array(
-                self::LOCAL,
-                new \DateTime($dateStr)
-            );
-        }
-
-        // To look up the timezone, we must first find the VCALENDAR component.
-        $root = $property;
-        while($root->parent) {
-            $root = $root->parent;
-        }
-        if ($root->name === 'VCALENDAR') {
-            $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root);
-        } else {
-            $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid);
-        }
-
-        $dt = new \DateTime($dateStr, $tz);
-        $dt->setTimeZone($tz);
-
-        return array(
-            self::LOCALTZ,
-            $dt
-        );
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Property/MultiDateTime.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject;
-
-/**
- * Multi-DateTime property
- *
- * This element is used for iCalendar properties such as the EXDATE property.
- * It basically provides a few helper functions that make it easier to deal
- * with these. It supports both DATE-TIME and DATE values.
- *
- * In order to use this correctly, you must call setDateTimes and getDateTimes
- * to retrieve and modify dates respectively.
- *
- * If you use the 'value' or properties directly, this object does not keep
- * reference and results might appear incorrectly.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class MultiDateTime extends VObject\Property {
-
-    /**
-     * DateTime representation
-     *
-     * @var DateTime[]
-     */
-    protected $dateTimes;
-
-    /**
-     * dateType
-     *
-     * This is one of the Sabre\VObject\Property\DateTime constants.
-     *
-     * @var int
-     */
-    protected $dateType;
-
-    /**
-     * Updates the value
-     *
-     * @param array $dt Must be an array of DateTime objects.
-     * @param int $dateType
-     * @return void
-     */
-    public function setDateTimes(array $dt, $dateType = VObject\Property\DateTime::LOCALTZ) {
-
-        foreach($dt as $i)
-            if (!$i instanceof \DateTime)
-                throw new \InvalidArgumentException('You must pass an array of DateTime objects');
-
-        $this->offsetUnset('VALUE');
-        $this->offsetUnset('TZID');
-        switch($dateType) {
-
-            case DateTime::LOCAL :
-                $val = array();
-                foreach($dt as $i) {
-                    $val[] = $i->format('Ymd\\THis');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE-TIME');
-                break;
-            case DateTime::UTC :
-                $val = array();
-                foreach($dt as $i) {
-                    $i->setTimeZone(new \DateTimeZone('UTC'));
-                    $val[] = $i->format('Ymd\\THis\\Z');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE-TIME');
-                break;
-            case DateTime::LOCALTZ :
-                $val = array();
-                foreach($dt as $i) {
-                    $val[] = $i->format('Ymd\\THis');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE-TIME');
-                $this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
-                break;
-            case DateTime::DATE :
-                $val = array();
-                foreach($dt as $i) {
-                    $val[] = $i->format('Ymd');
-                }
-                $this->setValue(implode(',',$val));
-                $this->offsetSet('VALUE','DATE');
-                break;
-            default :
-                throw new \InvalidArgumentException('You must pass a valid dateType constant');
-
-        }
-        $this->dateTimes = $dt;
-        $this->dateType = $dateType;
-
-    }
-
-    /**
-     * Returns the current DateTime value.
-     *
-     * If no value was set, this method returns null.
-     *
-     * @return array|null
-     */
-    public function getDateTimes() {
-
-        if ($this->dateTimes)
-            return $this->dateTimes;
-
-        $dts = array();
-
-        if (!$this->value) {
-            $this->dateTimes = null;
-            $this->dateType = null;
-            return null;
-        }
-
-        foreach(explode(',',$this->value) as $val) {
-            list(
-                $type,
-                $dt
-            ) = DateTime::parseData($val, $this);
-            $dts[] = $dt;
-            $this->dateType = $type;
-        }
-        $this->dateTimes = $dts;
-        return $this->dateTimes;
-
-    }
-
-    /**
-     * Returns the type of Date format.
-     *
-     * This method returns one of the format constants. If no date was set,
-     * this method will return null.
-     *
-     * @return int|null
-     */
-    public function getDateType() {
-
-        if ($this->dateType)
-            return $this->dateType;
-
-        if (!$this->value) {
-            $this->dateTimes = null;
-            $this->dateType = null;
-            return null;
-        }
-
-        $dts = array();
-        foreach(explode(',',$this->value) as $val) {
-            list(
-                $type,
-                $dt
-            ) = DateTime::parseData($val, $this);
-            $dts[] = $dt;
-            $this->dateType = $type;
-        }
-        $this->dateTimes = $dts;
-        return $this->dateType;
-
-    }
-
-    /**
-     * This method will return true, if the property had a date and a time, as
-     * opposed to only a date.
-     *
-     * @return bool
-     */
-    public function hasTime() {
-
-        return $this->getDateType()!==DateTime::DATE;
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Reader.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * VCALENDAR/VCARD reader
- *
- * This class reads the vobject file, and returns a full element tree.
- *
- * TODO: this class currently completely works 'statically'. This is pointless,
- * and defeats OOP principals. Needs refactoring in a future version.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Reader {
-
-    /**
-     * If this option is passed to the reader, it will be less strict about the
-     * validity of the lines.
-     *
-     * Currently using this option just means, that it will accept underscores
-     * in property names.
-     */
-    const OPTION_FORGIVING = 1;
-
-    /**
-     * If this option is turned on, any lines we cannot parse will be ignored
-     * by the reader.
-     */
-    const OPTION_IGNORE_INVALID_LINES = 2;
-
-    /**
-     * Parses the file and returns the top component
-     *
-     * The options argument is a bitfield. Pass any of the OPTIONS constant to
-     * alter the parsers' behaviour.
-     *
-     * @param string $data
-     * @param int $options
-     * @return Node
-     */
-    static function read($data, $options = 0) {
-
-        // Normalizing newlines
-        $data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
-
-        $lines = explode("\n", $data);
-
-        // Unfolding lines
-        $lines2 = array();
-        foreach($lines as $line) {
-
-            // Skipping empty lines
-            if (!$line) continue;
-
-            if ($line[0]===" " || $line[0]==="\t") {
-                $lines2[count($lines2)-1].=substr($line,1);
-            } else {
-                $lines2[] = $line;
-            }
-
-        }
-
-        unset($lines);
-
-        reset($lines2);
-
-        return self::readLine($lines2, $options);
-
-    }
-
-    /**
-     * Reads and parses a single line.
-     *
-     * This method receives the full array of lines. The array pointer is used
-     * to traverse.
-     *
-     * This method returns null if an invalid line was encountered, and the
-     * IGNORE_INVALID_LINES option was turned on.
-     *
-     * @param array $lines
-     * @param int $options See the OPTIONS constants.
-     * @return Node
-     */
-    static private function readLine(&$lines, $options = 0) {
-
-        $line = current($lines);
-        $lineNr = key($lines);
-        next($lines);
-
-        // Components
-        if (strtoupper(substr($line,0,6)) === "BEGIN:") {
-
-            $componentName = strtoupper(substr($line,6));
-            $obj = Component::create($componentName);
-
-            $nextLine = current($lines);
-
-            while(strtoupper(substr($nextLine,0,4))!=="END:") {
-
-                $parsedLine = self::readLine($lines, $options);
-                $nextLine = current($lines);
-
-                if (is_null($parsedLine)) {
-                    continue;
-                }
-                $obj->add($parsedLine);
-
-                if ($nextLine===false)
-                    throw new ParseException('Invalid VObject. Document ended prematurely.');
-
-            }
-
-            // Checking component name of the 'END:' line.
-            if (substr($nextLine,4)!==$obj->name) {
-                throw new ParseException('Invalid VObject, expected: "END:' . $obj->name . '" got: "' . $nextLine . '"');
-            }
-            next($lines);
-
-            return $obj;
-
-        }
-
-        // Properties
-        //$result = preg_match('/(?P<name>[A-Z0-9-]+)(?:;(?P<parameters>^(?<!:):))(.*)$/',$line,$matches);
-
-        if ($options & self::OPTION_FORGIVING) {
-            $token = '[A-Z0-9-\._]+';
-        } else {
-            $token = '[A-Z0-9-\.]+';
-        }
-        $parameters = "(?:;(?P<parameters>([^:^\"]|\"([^\"]*)\")*))?";
-        $regex = "/^(?P<name>$token)$parameters:(?P<value>.*)$/i";
-
-        $result = preg_match($regex,$line,$matches);
-
-        if (!$result) {
-            if ($options & self::OPTION_IGNORE_INVALID_LINES) {
-                return null;
-            } else {
-                throw new ParseException('Invalid VObject, line ' . ($lineNr+1) . ' did not follow the icalendar/vcard format');
-            }
-        }
-
-        $propertyName = strtoupper($matches['name']);
-        $propertyValue = preg_replace_callback('#(\\\\(\\\\|N|n))#',function($matches) {
-            if ($matches[2]==='n' || $matches[2]==='N') {
-                return "\n";
-            } else {
-                return $matches[2];
-            }
-        }, $matches['value']);
-
-        $obj = Property::create($propertyName, $propertyValue);
-
-        if ($matches['parameters']) {
-
-            foreach(self::readParameters($matches['parameters']) as $param) {
-                $obj->add($param);
-            }
-
-        }
-
-        return $obj;
-
-
-    }
-
-    /**
-     * Reads a parameter list from a property
-     *
-     * This method returns an array of Parameter
-     *
-     * @param string $parameters
-     * @return array
-     */
-    static private function readParameters($parameters) {
-
-        $token = '[A-Z0-9-]+';
-
-        $paramValue = '(?P<paramValue>[^\"^;]*|"[^"]*")';
-
-        $regex = "/(?<=^|;)(?P<paramName>$token)(=$paramValue(?=$|;))?/i";
-        preg_match_all($regex, $parameters, $matches,  PREG_SET_ORDER);
-
-        $params = array();
-        foreach($matches as $match) {
-
-            if (!isset($match['paramValue'])) {
-
-                $value = null;
-
-            } else {
-
-                $value = $match['paramValue'];
-
-                if (isset($value[0]) && $value[0]==='"') {
-                    // Stripping quotes, if needed
-                    $value = substr($value,1,strlen($value)-2);
-                }
-
-                $value = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
-                    if ($matches[2]==='n' || $matches[2]==='N') {
-                        return "\n";
-                    } else {
-                        return $matches[2];
-                    }
-                }, $value);
-
-            }
-
-            $params[] = new Parameter($match['paramName'], $value);
-
-        }
-
-        return $params;
-
-    }
-
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/RecurrenceIterator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1144 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This class is used to determine new for a recurring event, when the next
- * events occur.
- *
- * This iterator may loop infinitely in the future, therefore it is important
- * that if you use this class, you set hard limits for the amount of iterations
- * you want to handle.
- *
- * Note that currently there is not full support for the entire iCalendar
- * specification, as it's very complex and contains a lot of permutations
- * that's not yet used very often in software.
- *
- * For the focus has been on features as they actually appear in Calendaring
- * software, but this may well get expanded as needed / on demand
- *
- * The following RRULE properties are supported
- *   * UNTIL
- *   * INTERVAL
- *   * COUNT
- *   * FREQ=DAILY
- *     * BYDAY
- *     * BYHOUR
- *   * FREQ=WEEKLY
- *     * BYDAY
- *     * BYHOUR
- *     * WKST
- *   * FREQ=MONTHLY
- *     * BYMONTHDAY
- *     * BYDAY
- *     * BYSETPOS
- *   * FREQ=YEARLY
- *     * BYMONTH
- *     * BYMONTHDAY (only if BYMONTH is also set)
- *     * BYDAY (only if BYMONTH is also set)
- *
- * Anything beyond this is 'undefined', which means that it may get ignored, or
- * you may get unexpected results. The effect is that in some applications the
- * specified recurrence may look incorrect, or is missing.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class RecurrenceIterator implements \Iterator {
-
-    /**
-     * The initial event date
-     *
-     * @var DateTime
-     */
-    public $startDate;
-
-    /**
-     * The end-date of the initial event
-     *
-     * @var DateTime
-     */
-    public $endDate;
-
-    /**
-     * The 'current' recurrence.
-     *
-     * This will be increased for every iteration.
-     *
-     * @var DateTime
-     */
-    public $currentDate;
-
-
-    /**
-     * List of dates that are excluded from the rules.
-     *
-     * This list contains the items that have been overriden by the EXDATE
-     * property.
-     *
-     * @var array
-     */
-    public $exceptionDates = array();
-
-    /**
-     * Base event
-     *
-     * @var Component\VEvent
-     */
-    public $baseEvent;
-
-    /**
-     * List of dates that are overridden by other events.
-     * Similar to $overriddenEvents, but this just contains the original dates.
-     *
-     * @var array
-     */
-    public $overriddenDates = array();
-
-    /**
-     * list of events that are 'overridden'.
-     *
-     * This is an array of Component\VEvent objects.
-     *
-     * @var array
-     */
-    public $overriddenEvents = array();
-
-    /**
-     * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
-     * yearly.
-     *
-     * @var string
-     */
-    public $frequency;
-
-    /**
-     * The last instance of this recurrence, inclusively
-     *
-     * @var DateTime|null
-     */
-    public $until;
-
-    /**
-     * The number of recurrences, or 'null' if infinitely recurring.
-     *
-     * @var int
-     */
-    public $count;
-
-    /**
-     * The interval.
-     *
-     * If for example frequency is set to daily, interval = 2 would mean every
-     * 2 days.
-     *
-     * @var int
-     */
-    public $interval = 1;
-
-    /**
-     * Which seconds to recur.
-     *
-     * This is an array of integers (between 0 and 60)
-     *
-     * @var array
-     */
-    public $bySecond;
-
-    /**
-     * Which minutes to recur
-     *
-     * This is an array of integers (between 0 and 59)
-     *
-     * @var array
-     */
-    public $byMinute;
-
-    /**
-     * Which hours to recur
-     *
-     * This is an array of integers (between 0 and 23)
-     *
-     * @var array
-     */
-    public $byHour;
-
-    /**
-     * Which weekdays to recur.
-     *
-     * This is an array of weekdays
-     *
-     * This may also be preceeded by a positive or negative integer. If present,
-     * this indicates the nth occurrence of a specific day within the monthly or
-     * yearly rrule. For instance, -2TU indicates the second-last tuesday of
-     * the month, or year.
-     *
-     * @var array
-     */
-    public $byDay;
-
-    /**
-     * Which days of the month to recur
-     *
-     * This is an array of days of the months (1-31). The value can also be
-     * negative. -5 for instance means the 5th last day of the month.
-     *
-     * @var array
-     */
-    public $byMonthDay;
-
-    /**
-     * Which days of the year to recur.
-     *
-     * This is an array with days of the year (1 to 366). The values can also
-     * be negative. For instance, -1 will always represent the last day of the
-     * year. (December 31st).
-     *
-     * @var array
-     */
-    public $byYearDay;
-
-    /**
-     * Which week numbers to recur.
-     *
-     * This is an array of integers from 1 to 53. The values can also be
-     * negative. -1 will always refer to the last week of the year.
-     *
-     * @var array
-     */
-    public $byWeekNo;
-
-    /**
-     * Which months to recur
-     *
-     * This is an array of integers from 1 to 12.
-     *
-     * @var array
-     */
-    public $byMonth;
-
-    /**
-     * Which items in an existing st to recur.
-     *
-     * These numbers work together with an existing by* rule. It specifies
-     * exactly which items of the existing by-rule to filter.
-     *
-     * Valid values are 1 to 366 and -1 to -366. As an example, this can be
-     * used to recur the last workday of the month.
-     *
-     * This would be done by setting frequency to 'monthly', byDay to
-     * 'MO,TU,WE,TH,FR' and bySetPos to -1.
-     *
-     * @var array
-     */
-    public $bySetPos;
-
-    /**
-     * When a week starts
-     *
-     * @var string
-     */
-    public $weekStart = 'MO';
-
-    /**
-     * The current item in the list
-     *
-     * @var int
-     */
-    public $counter = 0;
-
-    /**
-     * Simple mapping from iCalendar day names to day numbers
-     *
-     * @var array
-     */
-    private $dayMap = array(
-        'SU' => 0,
-        'MO' => 1,
-        'TU' => 2,
-        'WE' => 3,
-        'TH' => 4,
-        'FR' => 5,
-        'SA' => 6,
-    );
-
-    /**
-     * Mappings between the day number and english day name.
-     *
-     * @var array
-     */
-    private $dayNames = array(
-        0 => 'Sunday',
-        1 => 'Monday',
-        2 => 'Tuesday',
-        3 => 'Wednesday',
-        4 => 'Thursday',
-        5 => 'Friday',
-        6 => 'Saturday',
-    );
-
-    /**
-     * If the current iteration of the event is an overriden event, this
-     * property will hold the VObject
-     *
-     * @var Component
-     */
-    private $currentOverriddenEvent;
-
-    /**
-     * This property may contain the date of the next not-overridden event.
-     * This date is calculated sometimes a bit early, before overridden events
-     * are evaluated.
-     *
-     * @var DateTime
-     */
-    private $nextDate;
-
-    /**
-     * This counts the number of overridden events we've handled so far
-     *
-     * @var int
-     */
-    private $handledOverridden = 0;
-
-    /**
-     * Creates the iterator
-     *
-     * You should pass a VCALENDAR component, as well as the UID of the event
-     * we're going to traverse.
-     *
-     * @param Component $vcal
-     * @param string|null $uid
-     */
-    public function __construct(Component $vcal, $uid=null) {
-
-        if (is_null($uid)) {
-            if ($vcal->name === 'VCALENDAR') {
-                throw new \InvalidArgumentException('If you pass a VCALENDAR object, you must pass a uid argument as well');
-            }
-            $components = array($vcal);
-            $uid = (string)$vcal->uid;
-        } else {
-            $components = $vcal->select('VEVENT');
-        }
-        foreach($components as $component) {
-            if ((string)$component->uid == $uid) {
-                if (isset($component->{'RECURRENCE-ID'})) {
-                    $this->overriddenEvents[$component->DTSTART->getDateTime()->getTimeStamp()] = $component;
-                    $this->overriddenDates[] = $component->{'RECURRENCE-ID'}->getDateTime();
-                } else {
-                    $this->baseEvent = $component;
-                }
-            }
-        }
-
-        ksort($this->overriddenEvents);
-
-        if (!$this->baseEvent) {
-            throw new \InvalidArgumentException('Could not find a base event with uid: ' . $uid);
-        }
-
-        $this->startDate = clone $this->baseEvent->DTSTART->getDateTime();
-
-        $this->endDate = null;
-        if (isset($this->baseEvent->DTEND)) {
-            $this->endDate = clone $this->baseEvent->DTEND->getDateTime();
-        } else {
-            $this->endDate = clone $this->startDate;
-            if (isset($this->baseEvent->DURATION)) {
-                $this->endDate->add(DateTimeParser::parse($this->baseEvent->DURATION->value));
-            } elseif ($this->baseEvent->DTSTART->getDateType()===Property\DateTime::DATE) {
-                $this->endDate->modify('+1 day');
-            }
-        }
-        $this->currentDate = clone $this->startDate;
-
-        $rrule = (string)$this->baseEvent->RRULE;
-
-        $parts = explode(';', $rrule);
-
-        // If no rrule was specified, we create a default setting
-        if (!$rrule) {
-            $this->frequency = 'daily';
-            $this->count = 1;
-        } else foreach($parts as $part) {
-
-            list($key, $value) = explode('=', $part, 2);
-
-            switch(strtoupper($key)) {
-
-                case 'FREQ' :
-                    if (!in_array(
-                        strtolower($value),
-                        array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
-                    )) {
-                        throw new \InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
-
-                    }
-                    $this->frequency = strtolower($value);
-                    break;
-
-                case 'UNTIL' :
-                    $this->until = DateTimeParser::parse($value);
-
-                    // In some cases events are generated with an UNTIL=
-                    // parameter before the actual start of the event.
-                    //
-                    // Not sure why this is happening. We assume that the
-                    // intention was that the event only recurs once.
-                    //
-                    // So we are modifying the parameter so our code doesn't
-                    // break.
-                    if($this->until < $this->baseEvent->DTSTART->getDateTime()) {
-                        $this->until = $this->baseEvent->DTSTART->getDateTime();
-                    }
-                    break;
-
-                case 'COUNT' :
-                    $this->count = (int)$value;
-                    break;
-
-                case 'INTERVAL' :
-                    $this->interval = (int)$value;
-                    if ($this->interval < 1) {
-                        throw new \InvalidArgumentException('INTERVAL in RRULE must be a positive integer!');
-                    }
-                    break;
-
-                case 'BYSECOND' :
-                    $this->bySecond = explode(',', $value);
-                    break;
-
-                case 'BYMINUTE' :
-                    $this->byMinute = explode(',', $value);
-                    break;
-
-                case 'BYHOUR' :
-                    $this->byHour = explode(',', $value);
-                    break;
-
-                case 'BYDAY' :
-                    $this->byDay = explode(',', strtoupper($value));
-                    break;
-
-                case 'BYMONTHDAY' :
-                    $this->byMonthDay = explode(',', $value);
-                    break;
-
-                case 'BYYEARDAY' :
-                    $this->byYearDay = explode(',', $value);
-                    break;
-
-                case 'BYWEEKNO' :
-                    $this->byWeekNo = explode(',', $value);
-                    break;
-
-                case 'BYMONTH' :
-                    $this->byMonth = explode(',', $value);
-                    break;
-
-                case 'BYSETPOS' :
-                    $this->bySetPos = explode(',', $value);
-                    break;
-
-                case 'WKST' :
-                    $this->weekStart = strtoupper($value);
-                    break;
-
-            }
-
-        }
-
-        // Parsing exception dates
-        if (isset($this->baseEvent->EXDATE)) {
-            foreach($this->baseEvent->EXDATE as $exDate) {
-
-                foreach(explode(',', (string)$exDate) as $exceptionDate) {
-
-                    $this->exceptionDates[] =
-                        DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
-
-                }
-
-            }
-
-        }
-
-    }
-
-    /**
-     * Returns the current item in the list
-     *
-     * @return DateTime
-     */
-    public function current() {
-
-        if (!$this->valid()) return null;
-        return clone $this->currentDate;
-
-    }
-
-    /**
-     * This method returns the startdate for the current iteration of the
-     * event.
-     *
-     * @return DateTime
-     */
-    public function getDtStart() {
-
-        if (!$this->valid()) return null;
-        return clone $this->currentDate;
-
-    }
-
-    /**
-     * This method returns the enddate for the current iteration of the
-     * event.
-     *
-     * @return DateTime
-     */
-    public function getDtEnd() {
-
-        if (!$this->valid()) return null;
-        $dtEnd = clone $this->currentDate;
-        $dtEnd->add( $this->startDate->diff( $this->endDate ) );
-        return clone $dtEnd;
-
-    }
-
-    /**
-     * Returns a VEVENT object with the updated start and end date.
-     *
-     * Any recurrence information is removed, and this function may return an
-     * 'overridden' event instead.
-     *
-     * This method always returns a cloned instance.
-     *
-     * @return Component\VEvent
-     */
-    public function getEventObject() {
-
-        if ($this->currentOverriddenEvent) {
-            return clone $this->currentOverriddenEvent;
-        }
-        $event = clone $this->baseEvent;
-        unset($event->RRULE);
-        unset($event->EXDATE);
-        unset($event->RDATE);
-        unset($event->EXRULE);
-
-        $event->DTSTART->setDateTime($this->getDTStart(), $event->DTSTART->getDateType());
-        if (isset($event->DTEND)) {
-            $event->DTEND->setDateTime($this->getDtEnd(), $event->DTSTART->getDateType());
-        }
-        if ($this->counter > 0) {
-            $event->{'RECURRENCE-ID'} = (string)$event->DTSTART;
-        }
-
-        return $event;
-
-    }
-
-    /**
-     * Returns the current item number
-     *
-     * @return int
-     */
-    public function key() {
-
-        return $this->counter;
-
-    }
-
-    /**
-     * Whether or not there is a 'next item'
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        if (!is_null($this->count)) {
-            return $this->counter < $this->count;
-        }
-        if (!is_null($this->until) && $this->currentDate > $this->until) {
-
-            // Need to make sure there's no overridden events past the
-            // until date.
-            foreach($this->overriddenEvents as $overriddenEvent) {
-
-                if ($overriddenEvent->DTSTART->getDateTime() >= $this->currentDate) {
-
-                    return true;
-                }
-            }
-            return false;
-        }
-        return true;
-
-    }
-
-    /**
-     * Resets the iterator
-     *
-     * @return void
-     */
-    public function rewind() {
-
-        $this->currentDate = clone $this->startDate;
-        $this->counter = 0;
-
-    }
-
-    /**
-     * This method allows you to quickly go to the next occurrence after the
-     * specified date.
-     *
-     * Note that this checks the current 'endDate', not the 'stardDate'. This
-     * means that if you forward to January 1st, the iterator will stop at the
-     * first event that ends *after* January 1st.
-     *
-     * @param DateTime $dt
-     * @return void
-     */
-    public function fastForward(\DateTime $dt) {
-
-        while($this->valid() && $this->getDTEnd() <= $dt) {
-            $this->next();
-        }
-
-    }
-
-    /**
-     * Returns true if this recurring event never ends.
-     *
-     * @return bool
-     */
-    public function isInfinite() {
-
-        return !$this->count && !$this->until;
-
-    }
-
-    /**
-     * Goes on to the next iteration
-     *
-     * @return void
-     */
-    public function next() {
-
-        $previousStamp = $this->currentDate->getTimeStamp();
-
-        // Finding the next overridden event in line, and storing that for
-        // later use.
-        $overriddenEvent = null;
-        $overriddenDate = null;
-        $this->currentOverriddenEvent = null;
-
-        foreach($this->overriddenEvents as $index=>$event) {
-            if ($index > $previousStamp) {
-                $overriddenEvent = $event;
-                $overriddenDate = clone $event->DTSTART->getDateTime();
-                break;
-            }
-        }
-
-        // If we have a stored 'next date', we will use that.
-        if ($this->nextDate) {
-            if (!$overriddenDate || $this->nextDate < $overriddenDate) {
-                $this->currentDate = $this->nextDate;
-                $currentStamp = $this->currentDate->getTimeStamp();
-                $this->nextDate = null;
-            } else {
-                $this->currentDate = clone $overriddenDate;
-                $this->currentOverriddenEvent = $overriddenEvent;
-            }
-            $this->counter++;
-            return;
-        }
-
-        while(true) {
-
-            // Otherwise, we find the next event in the normal RRULE
-            // sequence.
-            switch($this->frequency) {
-
-                case 'hourly' :
-                    $this->nextHourly();
-                    break;
-
-                case 'daily' :
-                    $this->nextDaily();
-                    break;
-
-                case 'weekly' :
-                    $this->nextWeekly();
-                    break;
-
-                case 'monthly' :
-                    $this->nextMonthly();
-                    break;
-
-                case 'yearly' :
-                    $this->nextYearly();
-                    break;
-
-            }
-            $currentStamp = $this->currentDate->getTimeStamp();
-
-
-            // Checking exception dates
-            foreach($this->exceptionDates as $exceptionDate) {
-                if ($this->currentDate == $exceptionDate) {
-                    $this->counter++;
-                    continue 2;
-                }
-            }
-            foreach($this->overriddenDates as $check) {
-                if ($this->currentDate == $check) {
-                    continue 2;
-                }
-            }
-            break;
-
-        }
-
-
-
-        // Is the date we have actually higher than the next overiddenEvent?
-        if ($overriddenDate && $this->currentDate > $overriddenDate) {
-            $this->nextDate = clone $this->currentDate;
-            $this->currentDate = clone $overriddenDate;
-            $this->currentOverriddenEvent = $overriddenEvent;
-            $this->handledOverridden++;
-        }
-        $this->counter++;
-
-
-        /*
-         * If we have overridden events left in the queue, but our counter is
-         * running out, we should grab one of those.
-         */
-        if (!is_null($overriddenEvent) && !is_null($this->count) && count($this->overriddenEvents) - $this->handledOverridden >= ($this->count - $this->counter)) {
-
-            $this->currentOverriddenEvent = $overriddenEvent;
-            $this->currentDate = clone $overriddenDate;
-            $this->handledOverridden++;
-
-        }
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for hourly frequency.
-     *
-     * @return void
-     */
-    protected function nextHourly() {
-
-        if (!$this->byHour) {
-            $this->currentDate->modify('+' . $this->interval . ' hours');
-            return;
-        }
-    }
-
-    /**
-     * Does the processing for advancing the iterator for daily frequency.
-     *
-     * @return void
-     */
-    protected function nextDaily() {
-
-        if (!$this->byHour && !$this->byDay) {
-            $this->currentDate->modify('+' . $this->interval . ' days');
-            return;
-        }
-
-        if (isset($this->byHour)) {
-            $recurrenceHours = $this->getHours();
-        }
-
-        if (isset($this->byDay)) {
-            $recurrenceDays = $this->getDays();
-        }
-
-        do {
-
-            if ($this->byHour) {
-                if ($this->currentDate->format('G') == '23') {
-                    // to obey the interval rule
-                    $this->currentDate->modify('+' . $this->interval-1 . ' days');
-                }
-
-                $this->currentDate->modify('+1 hours');
-
-            } else {
-                $this->currentDate->modify('+' . $this->interval . ' days');
-
-            }
-
-            // Current day of the week
-            $currentDay = $this->currentDate->format('w');
-
-            // Current hour of the day
-            $currentHour = $this->currentDate->format('G');
-
-        } while (($this->byDay && !in_array($currentDay, $recurrenceDays)) || ($this->byHour && !in_array($currentHour, $recurrenceHours)));
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for weekly frequency.
-     *
-     * @return void
-     */
-    protected function nextWeekly() {
-
-        if (!$this->byHour && !$this->byDay) {
-            $this->currentDate->modify('+' . $this->interval . ' weeks');
-            return;
-        }
-
-        if ($this->byHour) {
-            $recurrenceHours = $this->getHours();
-        }
-
-        if ($this->byDay) {
-            $recurrenceDays = $this->getDays();
-        }
-
-        // First day of the week:
-        $firstDay = $this->dayMap[$this->weekStart];
-
-        do {
-
-            if ($this->byHour) {
-                $this->currentDate->modify('+1 hours');
-            } else {
-                $this->currentDate->modify('+1 days');
-            }
-
-            // Current day of the week
-            $currentDay = (int) $this->currentDate->format('w');
-
-            // Current hour of the day
-            $currentHour = (int) $this->currentDate->format('G');
-
-            // We need to roll over to the next week
-            if ($currentDay === $firstDay && (!$this->byHour || $currentHour == '0')) {
-                $this->currentDate->modify('+' . $this->interval-1 . ' weeks');
-
-                // We need to go to the first day of this week, but only if we
-                // are not already on this first day of this week.
-                if($this->currentDate->format('w') != $firstDay) {
-                    $this->currentDate->modify('last ' . $this->dayNames[$this->dayMap[$this->weekStart]]);
-                }
-            }
-
-            // We have a match
-        } while (($this->byDay && !in_array($currentDay, $recurrenceDays)) || ($this->byHour && !in_array($currentHour, $recurrenceHours)));
-    }
-
-    /**
-     * Does the processing for advancing the iterator for monthly frequency.
-     *
-     * @return void
-     */
-    protected function nextMonthly() {
-
-        $currentDayOfMonth = $this->currentDate->format('j');
-        if (!$this->byMonthDay && !$this->byDay) {
-
-            // If the current day is higher than the 28th, rollover can
-            // occur to the next month. We Must skip these invalid
-            // entries.
-            if ($currentDayOfMonth < 29) {
-                $this->currentDate->modify('+' . $this->interval . ' months');
-            } else {
-                $increase = 0;
-                do {
-                    $increase++;
-                    $tempDate = clone $this->currentDate;
-                    $tempDate->modify('+ ' . ($this->interval*$increase) . ' months');
-                } while ($tempDate->format('j') != $currentDayOfMonth);
-                $this->currentDate = $tempDate;
-            }
-            return;
-        }
-
-        while(true) {
-
-            $occurrences = $this->getMonthlyOccurrences();
-
-            foreach($occurrences as $occurrence) {
-
-                // The first occurrence thats higher than the current
-                // day of the month wins.
-                if ($occurrence > $currentDayOfMonth) {
-                    break 2;
-                }
-
-            }
-
-            // If we made it all the way here, it means there were no
-            // valid occurrences, and we need to advance to the next
-            // month.
-            $this->currentDate->modify('first day of this month');
-            $this->currentDate->modify('+ ' . $this->interval . ' months');
-
-            // This goes to 0 because we need to start counting at hte
-            // beginning.
-            $currentDayOfMonth = 0;
-
-        }
-
-        $this->currentDate->setDate($this->currentDate->format('Y'), $this->currentDate->format('n'), $occurrence);
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for yearly frequency.
-     *
-     * @return void
-     */
-    protected function nextYearly() {
-
-        $currentMonth = $this->currentDate->format('n');
-        $currentYear = $this->currentDate->format('Y');
-        $currentDayOfMonth = $this->currentDate->format('j');
-
-        // No sub-rules, so we just advance by year
-        if (!$this->byMonth) {
-
-            // Unless it was a leap day!
-            if ($currentMonth==2 && $currentDayOfMonth==29) {
-
-                $counter = 0;
-                do {
-                    $counter++;
-                    // Here we increase the year count by the interval, until
-                    // we hit a date that's also in a leap year.
-                    //
-                    // We could just find the next interval that's dividable by
-                    // 4, but that would ignore the rule that there's no leap
-                    // year every year that's dividable by a 100, but not by
-                    // 400. (1800, 1900, 2100). So we just rely on the datetime
-                    // functions instead.
-                    $nextDate = clone $this->currentDate;
-                    $nextDate->modify('+ ' . ($this->interval*$counter) . ' years');
-                } while ($nextDate->format('n')!=2);
-                $this->currentDate = $nextDate;
-
-                return;
-
-            }
-
-            // The easiest form
-            $this->currentDate->modify('+' . $this->interval . ' years');
-            return;
-
-        }
-
-        $currentMonth = $this->currentDate->format('n');
-        $currentYear = $this->currentDate->format('Y');
-        $currentDayOfMonth = $this->currentDate->format('j');
-
-        $advancedToNewMonth = false;
-
-        // If we got a byDay or getMonthDay filter, we must first expand
-        // further.
-        if ($this->byDay || $this->byMonthDay) {
-
-            while(true) {
-
-                $occurrences = $this->getMonthlyOccurrences();
-
-                foreach($occurrences as $occurrence) {
-
-                    // The first occurrence that's higher than the current
-                    // day of the month wins.
-                    // If we advanced to the next month or year, the first
-                    // occurrence is always correct.
-                    if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
-                        break 2;
-                    }
-
-                }
-
-                // If we made it here, it means we need to advance to
-                // the next month or year.
-                $currentDayOfMonth = 1;
-                $advancedToNewMonth = true;
-                do {
-
-                    $currentMonth++;
-                    if ($currentMonth>12) {
-                        $currentYear+=$this->interval;
-                        $currentMonth = 1;
-                    }
-                } while (!in_array($currentMonth, $this->byMonth));
-
-                $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
-
-            }
-
-            // If we made it here, it means we got a valid occurrence
-            $this->currentDate->setDate($currentYear, $currentMonth, $occurrence);
-            return;
-
-        } else {
-
-            // These are the 'byMonth' rules, if there are no byDay or
-            // byMonthDay sub-rules.
-            do {
-
-                $currentMonth++;
-                if ($currentMonth>12) {
-                    $currentYear+=$this->interval;
-                    $currentMonth = 1;
-                }
-            } while (!in_array($currentMonth, $this->byMonth));
-            $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
-
-            return;
-
-        }
-
-    }
-
-    /**
-     * Returns all the occurrences for a monthly frequency with a 'byDay' or
-     * 'byMonthDay' expansion for the current month.
-     *
-     * The returned list is an array of integers with the day of month (1-31).
-     *
-     * @return array
-     */
-    protected function getMonthlyOccurrences() {
-
-        $startDate = clone $this->currentDate;
-
-        $byDayResults = array();
-
-        // Our strategy is to simply go through the byDays, advance the date to
-        // that point and add it to the results.
-        if ($this->byDay) foreach($this->byDay as $day) {
-
-            $dayName = $this->dayNames[$this->dayMap[substr($day,-2)]];
-
-            // Dayname will be something like 'wednesday'. Now we need to find
-            // all wednesdays in this month.
-            $dayHits = array();
-
-            $checkDate = clone $startDate;
-            $checkDate->modify('first day of this month');
-            $checkDate->modify($dayName);
-
-            do {
-                $dayHits[] = $checkDate->format('j');
-                $checkDate->modify('next ' . $dayName);
-            } while ($checkDate->format('n') === $startDate->format('n'));
-
-            // So now we have 'all wednesdays' for month. It is however
-            // possible that the user only really wanted the 1st, 2nd or last
-            // wednesday.
-            if (strlen($day)>2) {
-                $offset = (int)substr($day,0,-2);
-
-                if ($offset>0) {
-                    // It is possible that the day does not exist, such as a
-                    // 5th or 6th wednesday of the month.
-                    if (isset($dayHits[$offset-1])) {
-                        $byDayResults[] = $dayHits[$offset-1];
-                    }
-                } else {
-
-                    // if it was negative we count from the end of the array
-                    $byDayResults[] = $dayHits[count($dayHits) + $offset];
-                }
-            } else {
-                // There was no counter (first, second, last wednesdays), so we
-                // just need to add the all to the list).
-                $byDayResults = array_merge($byDayResults, $dayHits);
-
-            }
-
-        }
-
-        $byMonthDayResults = array();
-        if ($this->byMonthDay) foreach($this->byMonthDay as $monthDay) {
-
-            // Removing values that are out of range for this month
-            if ($monthDay > $startDate->format('t') ||
-                $monthDay < 0-$startDate->format('t')) {
-                    continue;
-            }
-            if ($monthDay>0) {
-                $byMonthDayResults[] = $monthDay;
-            } else {
-                // Negative values
-                $byMonthDayResults[] = $startDate->format('t') + 1 + $monthDay;
-            }
-        }
-
-        // If there was just byDay or just byMonthDay, they just specify our
-        // (almost) final list. If both were provided, then byDay limits the
-        // list.
-        if ($this->byMonthDay && $this->byDay) {
-            $result = array_intersect($byMonthDayResults, $byDayResults);
-        } elseif ($this->byMonthDay) {
-            $result = $byMonthDayResults;
-        } else {
-            $result = $byDayResults;
-        }
-        $result = array_unique($result);
-        sort($result, SORT_NUMERIC);
-
-        // The last thing that needs checking is the BYSETPOS. If it's set, it
-        // means only certain items in the set survive the filter.
-        if (!$this->bySetPos) {
-            return $result;
-        }
-
-        $filteredResult = array();
-        foreach($this->bySetPos as $setPos) {
-
-            if ($setPos<0) {
-                $setPos = count($result)-($setPos+1);
-            }
-            if (isset($result[$setPos-1])) {
-                $filteredResult[] = $result[$setPos-1];
-            }
-        }
-
-        sort($filteredResult, SORT_NUMERIC);
-        return $filteredResult;
-
-    }
-
-    protected function getHours()
-    {
-        $recurrenceHours = array();
-        foreach($this->byHour as $byHour) {
-            $recurrenceHours[] = $byHour;
-        }
-
-        return $recurrenceHours;
-    }
-
-    protected function getDays()
-    {
-        $recurrenceDays = array();
-        foreach($this->byDay as $byDay) {
-
-            // The day may be preceeded with a positive (+n) or
-            // negative (-n) integer. However, this does not make
-            // sense in 'weekly' so we ignore it here.
-            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
-
-        }
-
-        return $recurrenceDays;
-    }
-}
-
--- a/plugins/libcalendaring/lib/Sabre/VObject/Splitter/ICalendar.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-use Sabre\VObject;
-
-/**
- * Splitter
- *
- * This class is responsible for splitting up iCalendar objects.
- *
- * This class expects a single VCALENDAR object with one or more
- * calendar-objects inside. Objects with identical UID's will be combined into
- * a single object.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Dominik Tobschall
- * @author Armin Hackmann
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class ICalendar implements SplitterInterface {
-
-    /**
-     * Timezones
-     *
-     * @var array
-     */
-    protected $vtimezones = array();
-
-    /**
-     * iCalendar objects
-     *
-     * @var array
-     */
-    protected $objects = array();
-
-    /**
-     * Constructor
-     *
-     * The splitter should receive an readable file stream as it's input.
-     *
-     * @param resource $input
-     */
-    public function __construct($input) {
-
-        $data = VObject\Reader::read(stream_get_contents($input));
-        $vtimezones = array();
-        $components = array();
-
-        foreach($data->children as $component) {
-            if (!$component instanceof VObject\Component) {
-                continue;
-            }
-
-            // Get all timezones
-            if ($component->name === 'VTIMEZONE') {
-                $this->vtimezones[(string)$component->TZID] = $component;
-                continue;
-            }
-
-            // Get component UID for recurring Events search
-            if($component->UID) {
-                $uid = (string)$component->UID;
-            } else {
-                // Generating a random UID
-                $uid = sha1(microtime()) . '-vobjectimport';
-            }
-
-            // Take care of recurring events
-            if (!array_key_exists($uid, $this->objects)) {
-                $this->objects[$uid] = VObject\Component::create('VCALENDAR');
-            }
-
-            $this->objects[$uid]->add(clone $component);
-        }
-
-    }
-
-    /**
-     * Every time getNext() is called, a new object will be parsed, until we
-     * hit the end of the stream.
-     *
-     * When the end is reached, null will be returned.
-     *
-     * @return Sabre\VObject\Component|null
-     */
-    public function getNext() {
-
-        if($object=array_shift($this->objects)) {
-
-            // create our baseobject
-            $object->version = '2.0';
-            $object->prodid = '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN';
-            $object->calscale = 'GREGORIAN';
-
-            // add vtimezone information to obj (if we have it)
-            foreach ($this->vtimezones as $vtimezone) {
-                $object->add($vtimezone);
-            }
-
-            return $object;
-
-        } else {
-
-            return null;
-
-        }
-
-   }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Splitter/SplitterInterface.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-/**
- * VObject splitter
- *
- * The splitter is responsible for reading a large vCard or iCalendar object,
- * and splitting it into multiple objects.
- *
- * This is for example for Card and CalDAV, which require every event and vcard
- * to exist in their own objects, instead of one large one.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Dominik Tobschall
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-interface SplitterInterface {
-
-    /**
-     * Constructor
-     *
-     * The splitter should receive an readable file stream as it's input.
-     *
-     * @param resource $input
-     */
-    function __construct($input);
-
-    /**
-     * Every time getNext() is called, a new object will be parsed, until we
-     * hit the end of the stream.
-     *
-     * When the end is reached, null will be returned.
-     *
-     * @return Sabre\VObject\Component|null
-     */
-    function getNext();
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Splitter/VCard.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-use Sabre\VObject;
-
-/**
- * Splitter
- *
- * This class is responsible for splitting up VCard objects.
- *
- * It is assumed that the input stream contains 1 or more VCARD objects. This
- * class checks for BEGIN:VCARD and END:VCARD and parses each encountered
- * component individually.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Dominik Tobschall
- * @author Armin Hackmann
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class VCard implements SplitterInterface {
-
-    /**
-     * File handle
-     *
-     * @var resource
-     */
-    protected $input;
-
-    /**
-     * Constructor
-     *
-     * The splitter should receive an readable file stream as it's input.
-     *
-     * @param resource $input
-     */
-    public function __construct($input) {
-
-        $this->input = $input;
-
-    }
-
-    /**
-     * Every time getNext() is called, a new object will be parsed, until we
-     * hit the end of the stream.
-     *
-     * When the end is reached, null will be returned.
-     *
-     * @return Sabre\VObject\Component|null
-     */
-    public function getNext() {
-
-        $vcard = '';
-
-        do {
-
-            if (feof($this->input)) {
-                return false;
-            }
-
-            $line = fgets($this->input);
-            $vcard .= $line;
-
-        } while(strtoupper(substr($line,0,4))!=="END:");
-
-        $object = VObject\Reader::read($vcard);
-
-        if($object->name !== 'VCARD') {
-            throw new \InvalidArgumentException("Thats no vCard!", 1);
-        }
-
-        return $object;
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/StringUtil.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Useful utilities for working with various strings.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class StringUtil {
-
-    /**
-     * Returns true or false depending on if a string is valid UTF-8
-     *
-     * @param string $str
-     * @return bool
-     */
-    static function isUTF8($str) {
-
-        // First check.. mb_check_encoding
-        if (!mb_check_encoding($str, 'UTF-8')) {
-            return false;
-        }
-
-        // Control characters
-        if (preg_match('%(?:[\x00-\x08\x0B-\x0C\x0E\x0F])%', $str)) {
-            return false;
-        }
-
-        return true;
-
-    }
-
-    /**
-     * This method tries its best to convert the input string to UTF-8.
-     *
-     * Currently only ISO-5991-1 input and UTF-8 input is supported, but this
-     * may be expanded upon if we receive other examples.
-     *
-     * @param string $str
-     * @return string
-     */
-    static function convertToUTF8($str) {
-
-        $encoding = mb_detect_encoding($str , array('UTF-8','ISO-8859-1'), true);
-
-        if ($encoding === 'ISO-8859-1') {
-            $newStr = utf8_encode($str);
-        } else {
-            $newStr = $str;
-        }
-
-        // Removing any control characters
-        return (preg_replace('%(?:[\x00-\x08\x0B-\x0C\x0E\x0F])%', '', $newStr));
-
-    }
-
-}
-
--- a/plugins/libcalendaring/lib/Sabre/VObject/TimeZoneUtil.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Time zone name translation
- *
- * This file translates well-known time zone names into "Olson database" time zone names.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Frank Edelhaeuser (fedel@users.sourceforge.net)
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class TimeZoneUtil {
-
-    public static $map = array(
-
-        // from http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html
-        // snapshot taken on 2012/01/16
-
-        // windows
-        'AUS Central Standard Time'=>'Australia/Darwin',
-        'AUS Eastern Standard Time'=>'Australia/Sydney',
-        'Afghanistan Standard Time'=>'Asia/Kabul',
-        'Alaskan Standard Time'=>'America/Anchorage',
-        'Arab Standard Time'=>'Asia/Riyadh',
-        'Arabian Standard Time'=>'Asia/Dubai',
-        'Arabic Standard Time'=>'Asia/Baghdad',
-        'Argentina Standard Time'=>'America/Buenos_Aires',
-        'Armenian Standard Time'=>'Asia/Yerevan',
-        'Atlantic Standard Time'=>'America/Halifax',
-        'Azerbaijan Standard Time'=>'Asia/Baku',
-        'Azores Standard Time'=>'Atlantic/Azores',
-        'Bangladesh Standard Time'=>'Asia/Dhaka',
-        'Canada Central Standard Time'=>'America/Regina',
-        'Cape Verde Standard Time'=>'Atlantic/Cape_Verde',
-        'Caucasus Standard Time'=>'Asia/Yerevan',
-        'Cen. Australia Standard Time'=>'Australia/Adelaide',
-        'Central America Standard Time'=>'America/Guatemala',
-        'Central Asia Standard Time'=>'Asia/Almaty',
-        'Central Brazilian Standard Time'=>'America/Cuiaba',
-        'Central Europe Standard Time'=>'Europe/Budapest',
-        'Central European Standard Time'=>'Europe/Warsaw',
-        'Central Pacific Standard Time'=>'Pacific/Guadalcanal',
-        'Central Standard Time'=>'America/Chicago',
-        'Central Standard Time (Mexico)'=>'America/Mexico_City',
-        'China Standard Time'=>'Asia/Shanghai',
-        'Dateline Standard Time'=>'Etc/GMT+12',
-        'E. Africa Standard Time'=>'Africa/Nairobi',
-        'E. Australia Standard Time'=>'Australia/Brisbane',
-        'E. Europe Standard Time'=>'Europe/Minsk',
-        'E. South America Standard Time'=>'America/Sao_Paulo',
-        'Eastern Standard Time'=>'America/New_York',
-        'Egypt Standard Time'=>'Africa/Cairo',
-        'Ekaterinburg Standard Time'=>'Asia/Yekaterinburg',
-        'FLE Standard Time'=>'Europe/Kiev',
-        'Fiji Standard Time'=>'Pacific/Fiji',
-        'GMT Standard Time'=>'Europe/London',
-        'GTB Standard Time'=>'Europe/Istanbul',
-        'Georgian Standard Time'=>'Asia/Tbilisi',
-        'Greenland Standard Time'=>'America/Godthab',
-        'Greenwich Standard Time'=>'Atlantic/Reykjavik',
-        'Hawaiian Standard Time'=>'Pacific/Honolulu',
-        'India Standard Time'=>'Asia/Calcutta',
-        'Iran Standard Time'=>'Asia/Tehran',
-        'Israel Standard Time'=>'Asia/Jerusalem',
-        'Jordan Standard Time'=>'Asia/Amman',
-        'Kamchatka Standard Time'=>'Asia/Kamchatka',
-        'Korea Standard Time'=>'Asia/Seoul',
-        'Magadan Standard Time'=>'Asia/Magadan',
-        'Mauritius Standard Time'=>'Indian/Mauritius',
-        'Mexico Standard Time'=>'America/Mexico_City',
-        'Mexico Standard Time 2'=>'America/Chihuahua',
-        'Mid-Atlantic Standard Time'=>'Etc/GMT-2',
-        'Middle East Standard Time'=>'Asia/Beirut',
-        'Montevideo Standard Time'=>'America/Montevideo',
-        'Morocco Standard Time'=>'Africa/Casablanca',
-        'Mountain Standard Time'=>'America/Denver',
-        'Mountain Standard Time (Mexico)'=>'America/Chihuahua',
-        'Myanmar Standard Time'=>'Asia/Rangoon',
-        'N. Central Asia Standard Time'=>'Asia/Novosibirsk',
-        'Namibia Standard Time'=>'Africa/Windhoek',
-        'Nepal Standard Time'=>'Asia/Katmandu',
-        'New Zealand Standard Time'=>'Pacific/Auckland',
-        'Newfoundland Standard Time'=>'America/St_Johns',
-        'North Asia East Standard Time'=>'Asia/Irkutsk',
-        'North Asia Standard Time'=>'Asia/Krasnoyarsk',
-        'Pacific SA Standard Time'=>'America/Santiago',
-        'Pacific Standard Time'=>'America/Los_Angeles',
-        'Pacific Standard Time (Mexico)'=>'America/Santa_Isabel',
-        'Pakistan Standard Time'=>'Asia/Karachi',
-        'Paraguay Standard Time'=>'America/Asuncion',
-        'Romance Standard Time'=>'Europe/Paris',
-        'Russian Standard Time'=>'Europe/Moscow',
-        'SA Eastern Standard Time'=>'America/Cayenne',
-        'SA Pacific Standard Time'=>'America/Bogota',
-        'SA Western Standard Time'=>'America/La_Paz',
-        'SE Asia Standard Time'=>'Asia/Bangkok',
-        'Samoa Standard Time'=>'Pacific/Apia',
-        'Singapore Standard Time'=>'Asia/Singapore',
-        'South Africa Standard Time'=>'Africa/Johannesburg',
-        'Sri Lanka Standard Time'=>'Asia/Colombo',
-        'Syria Standard Time'=>'Asia/Damascus',
-        'Taipei Standard Time'=>'Asia/Taipei',
-        'Tasmania Standard Time'=>'Australia/Hobart',
-        'Tokyo Standard Time'=>'Asia/Tokyo',
-        'Tonga Standard Time'=>'Pacific/Tongatapu',
-        'US Eastern Standard Time'=>'America/Indianapolis',
-        'US Mountain Standard Time'=>'America/Phoenix',
-        'UTC+12'=>'Etc/GMT-12',
-        'UTC-02'=>'Etc/GMT+2',
-        'UTC-11'=>'Etc/GMT+11',
-        'Ulaanbaatar Standard Time'=>'Asia/Ulaanbaatar',
-        'Venezuela Standard Time'=>'America/Caracas',
-        'Vladivostok Standard Time'=>'Asia/Vladivostok',
-        'W. Australia Standard Time'=>'Australia/Perth',
-        'W. Central Africa Standard Time'=>'Africa/Lagos',
-        'W. Europe Standard Time'=>'Europe/Berlin',
-        'West Asia Standard Time'=>'Asia/Tashkent',
-        'West Pacific Standard Time'=>'Pacific/Port_Moresby',
-        'Yakutsk Standard Time'=>'Asia/Yakutsk',
-
-        // Microsoft exchange timezones
-        // Source:
-        // http://msdn.microsoft.com/en-us/library/ms988620%28v=exchg.65%29.aspx
-        //
-        // Correct timezones deduced with help from:
-        // http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
-        'Universal Coordinated Time' => 'UTC',
-        'Casablanca, Monrovia' => 'Africa/Casablanca',
-        'Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London' => 'Europe/Lisbon',
-        'Greenwich Mean Time; Dublin, Edinburgh, London' =>  'Europe/London',
-        'Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
-        'Belgrade, Pozsony, Budapest, Ljubljana, Prague' => 'Europe/Prague',
-        'Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
-        'Paris, Madrid, Brussels, Copenhagen' => 'Europe/Paris',
-        'Prague, Central Europe' => 'Europe/Prague',
-        'Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb' => 'Europe/Sarajevo',
-        'West Central Africa' => 'Africa/Luanda', // This was a best guess
-        'Athens, Istanbul, Minsk' => 'Europe/Athens',
-        'Bucharest' => 'Europe/Bucharest',
-        'Cairo' => 'Africa/Cairo',
-        'Harare, Pretoria' => 'Africa/Harare',
-        'Helsinki, Riga, Tallinn' => 'Europe/Helsinki',
-        'Israel, Jerusalem Standard Time' => 'Asia/Jerusalem',
-        'Baghdad' => 'Asia/Baghdad',
-        'Arab, Kuwait, Riyadh' => 'Asia/Kuwait',
-        'Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
-        'East Africa, Nairobi' => 'Africa/Nairobi',
-        'Tehran' => 'Asia/Tehran',
-        'Abu Dhabi, Muscat' => 'Asia/Muscat', // Best guess
-        'Baku, Tbilisi, Yerevan' => 'Asia/Baku',
-        'Kabul' => 'Asia/Kabul',
-        'Ekaterinburg' => 'Asia/Yekaterinburg',
-        'Islamabad, Karachi, Tashkent' => 'Asia/Karachi',
-        'Kolkata, Chennai, Mumbai, New Delhi, India Standard Time' => 'Asia/Calcutta',
-        'Kathmandu, Nepal' => 'Asia/Kathmandu',
-        'Almaty, Novosibirsk, North Central Asia' => 'Asia/Almaty',
-        'Astana, Dhaka' => 'Asia/Dhaka',
-        'Sri Jayawardenepura, Sri Lanka' => 'Asia/Colombo',
-        'Rangoon' => 'Asia/Rangoon',
-        'Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
-        'Krasnoyarsk' => 'Asia/Krasnoyarsk',
-        'Beijing, Chongqing, Hong Kong SAR, Urumqi' => 'Asia/Shanghai',
-        'Irkutsk, Ulaan Bataar' => 'Asia/Irkutsk',
-        'Kuala Lumpur, Singapore' => 'Asia/Singapore',
-        'Perth, Western Australia' => 'Australia/Perth',
-        'Taipei' => 'Asia/Taipei',
-        'Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
-        'Seoul, Korea Standard time' => 'Asia/Seoul',
-        'Yakutsk' => 'Asia/Yakutsk',
-        'Adelaide, Central Australia' => 'Australia/Adelaide',
-        'Darwin' => 'Australia/Darwin',
-        'Brisbane, East Australia' => 'Australia/Brisbane',
-        'Canberra, Melbourne, Sydney, Hobart (year 2000 only)' => 'Australia/Sydney',
-        'Guam, Port Moresby' => 'Pacific/Guam',
-        'Hobart, Tasmania' => 'Australia/Hobart',
-        'Vladivostok' => 'Asia/Vladivostok',
-        'Magadan, Solomon Is., New Caledonia' => 'Asia/Magadan',
-        'Auckland, Wellington' => 'Pacific/Auckland',
-        'Fiji Islands, Kamchatka, Marshall Is.' => 'Pacific/Fiji',
-        'Nuku\'alofa, Tonga' => 'Pacific/Tongatapu',
-        'Azores' => 'Atlantic/Azores',
-        'Cape Verde Is.' => 'Atlantic/Cape_Verde',
-        'Mid-Atlantic' => 'America/Noronha',
-        'Brasilia' => 'America/Sao_Paulo', // Best guess
-        'Buenos Aires' => 'America/Argentina/Buenos_Aires',
-        'Greenland' => 'America/Godthab',
-        'Newfoundland' => 'America/St_Johns',
-        'Atlantic Time (Canada)' => 'America/Halifax',
-        'Caracas, La Paz' => 'America/Caracas',
-        'Santiago' => 'America/Santiago',
-        'Bogota, Lima, Quito' => 'America/Bogota',
-        'Eastern Time (US & Canada)' => 'America/New_York',
-        'Indiana (East)' => 'America/Indiana/Indianapolis',
-        'Central America' => 'America/Guatemala',
-        'Central Time (US & Canada)' => 'America/Chicago',
-        'Mexico City, Tegucigalpa' => 'America/Mexico_City',
-        'Saskatchewan' => 'America/Edmonton',
-        'Arizona' => 'America/Phoenix',
-        'Mountain Time (US & Canada)' => 'America/Denver', // Best guess
-        'Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles', // Best guess
-        'Alaska' => 'America/Anchorage',
-        'Hawaii' => 'Pacific/Honolulu',
-        'Midway Island, Samoa' => 'Pacific/Midway',
-        'Eniwetok, Kwajalein, Dateline Time' => 'Pacific/Kwajalein',
-
-        // The following list are timezone names that could be generated by
-        // Lotus / Domino
-        'Dateline'               => 'Etc/GMT-12',
-        'Samoa'                  => 'Pacific/Apia',
-        'Hawaiian'               => 'Pacific/Honolulu',
-        'Alaskan'                => 'America/Anchorage',
-        'Pacific'                => 'America/Los_Angeles',
-        'Pacific Standard Time'  => 'America/Los_Angeles',
-        'Mexico Standard Time 2' => 'America/Chihuahua',
-        'Mountain'               => 'America/Denver',
-        'Mountain Standard Time' => 'America/Chihuahua',
-        'US Mountain'            => 'America/Phoenix',
-        'Canada Central'         => 'America/Edmonton',
-        'Central America'        => 'America/Guatemala',
-        'Central'                => 'America/Chicago',
-        'Central Standard Time'  => 'America/Mexico_City',
-        'Mexico'                 => 'America/Mexico_City',
-        'Eastern'                => 'America/New_York',
-        'SA Pacific'             => 'America/Bogota',
-        'US Eastern'             => 'America/Indiana/Indianapolis',
-        'Venezuela'              => 'America/Caracas',
-        'Atlantic'               => 'America/Halifax',
-        'Central Brazilian'      => 'America/Manaus',
-        'Pacific SA'             => 'America/Santiago',
-        'SA Western'             => 'America/La_Paz',
-        'Newfoundland'           => 'America/St_Johns',
-        'Argentina'              => 'America/Argentina/Buenos_Aires',
-        'E. South America'       => 'America/Belem',
-        'Greenland'              => 'America/Godthab',
-        'Montevideo'             => 'America/Montevideo',
-        'SA Eastern'             => 'America/Belem',
-        'Mid-Atlantic'           => 'Etc/GMT-2',
-        'Azores'                 => 'Atlantic/Azores',
-        'Cape Verde'             => 'Atlantic/Cape_Verde',
-        'Greenwich'              => 'Atlantic/Reykjavik', // No I'm serious.. Greenwich is not GMT.
-        'Morocco'                => 'Africa/Casablanca',
-        'Central Europe'         => 'Europe/Prague',
-        'Central European'       => 'Europe/Sarajevo',
-        'Romance'                => 'Europe/Paris',
-        'W. Central Africa'      => 'Africa/Lagos', // Best guess
-        'W. Europe'              => 'Europe/Amsterdam',
-        'E. Europe'              => 'Europe/Minsk',
-        'Egypt'                  => 'Africa/Cairo',
-        'FLE'                    => 'Europe/Helsinki',
-        'GTB'                    => 'Europe/Athens',
-        'Israel'                 => 'Asia/Jerusalem',
-        'Jordan'                 => 'Asia/Amman',
-        'Middle East'            => 'Asia/Beirut',
-        'Namibia'                => 'Africa/Windhoek',
-        'South Africa'           => 'Africa/Harare',
-        'Arab'                   => 'Asia/Kuwait',
-        'Arabic'                 => 'Asia/Baghdad',
-        'E. Africa'              => 'Africa/Nairobi',
-        'Georgian'               => 'Asia/Tbilisi',
-        'Russian'                => 'Europe/Moscow',
-        'Iran'                   => 'Asia/Tehran',
-        'Arabian'                => 'Asia/Muscat',
-        'Armenian'               => 'Asia/Yerevan',
-        'Azerbijan'              => 'Asia/Baku',
-        'Caucasus'               => 'Asia/Yerevan',
-        'Mauritius'              => 'Indian/Mauritius',
-        'Afghanistan'            => 'Asia/Kabul',
-        'Ekaterinburg'           => 'Asia/Yekaterinburg',
-        'Pakistan'               => 'Asia/Karachi',
-        'West Asia'              => 'Asia/Tashkent',
-        'India'                  => 'Asia/Calcutta',
-        'Sri Lanka'              => 'Asia/Colombo',
-        'Nepal'                  => 'Asia/Kathmandu',
-        'Central Asia'           => 'Asia/Dhaka',
-        'N. Central Asia'        => 'Asia/Almaty',
-        'Myanmar'                => 'Asia/Rangoon',
-        'North Asia'             => 'Asia/Krasnoyarsk',
-        'SE Asia'                => 'Asia/Bangkok',
-        'China'                  => 'Asia/Shanghai',
-        'North Asia East'        => 'Asia/Irkutsk',
-        'Singapore'              => 'Asia/Singapore',
-        'Taipei'                 => 'Asia/Taipei',
-        'W. Australia'           => 'Australia/Perth',
-        'Korea'                  => 'Asia/Seoul',
-        'Tokyo'                  => 'Asia/Tokyo',
-        'Yakutsk'                => 'Asia/Yakutsk',
-        'AUS Central'            => 'Australia/Darwin',
-        'Cen. Australia'         => 'Australia/Adelaide',
-        'AUS Eastern'            => 'Australia/Sydney',
-        'E. Australia'           => 'Australia/Brisbane',
-        'Tasmania'               => 'Australia/Hobart',
-        'Vladivostok'            => 'Asia/Vladivostok',
-        'West Pacific'           => 'Pacific/Guam',
-        'Central Pacific'        => 'Asia/Magadan',
-        'Fiji'                   => 'Pacific/Fiji',
-        'New Zealand'            => 'Pacific/Auckland',
-        'Tonga'                  => 'Pacific/Tongatapu',
-    );
-
-    /**
-     * List of microsoft exchange timezone ids.
-     *
-     * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx
-     */
-    public static $microsoftExchangeMap = array(
-        0  => 'UTC',
-        31 => 'Africa/Casablanca',
-
-        // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo.
-        // I'm not even kidding.. We handle this special case in the
-        // getTimeZone method.
-        2  => 'Europe/Lisbon',
-        1  => 'Europe/London',
-        4  => 'Europe/Berlin',
-        6  => 'Europe/Prague',
-        3  => 'Europe/Paris',
-        69 => 'Africa/Luanda', // This was a best guess
-        7  => 'Europe/Athens',
-        5  => 'Europe/Bucharest',
-        49 => 'Africa/Cairo',
-        50 => 'Africa/Harare',
-        59 => 'Europe/Helsinki',
-        27 => 'Asia/Jerusalem',
-        26 => 'Asia/Baghdad',
-        74 => 'Asia/Kuwait',
-        51 => 'Europe/Moscow',
-        56 => 'Africa/Nairobi',
-        25 => 'Asia/Tehran',
-        24 => 'Asia/Muscat', // Best guess
-        54 => 'Asia/Baku',
-        48 => 'Asia/Kabul',
-        58 => 'Asia/Yekaterinburg',
-        47 => 'Asia/Karachi',
-        23 => 'Asia/Calcutta',
-        62 => 'Asia/Kathmandu',
-        46 => 'Asia/Almaty',
-        71 => 'Asia/Dhaka',
-        66 => 'Asia/Colombo',
-        61 => 'Asia/Rangoon',
-        22 => 'Asia/Bangkok',
-        64 => 'Asia/Krasnoyarsk',
-        45 => 'Asia/Shanghai',
-        63 => 'Asia/Irkutsk',
-        21 => 'Asia/Singapore',
-        73 => 'Australia/Perth',
-        75 => 'Asia/Taipei',
-        20 => 'Asia/Tokyo',
-        72 => 'Asia/Seoul',
-        70 => 'Asia/Yakutsk',
-        19 => 'Australia/Adelaide',
-        44 => 'Australia/Darwin',
-        18 => 'Australia/Brisbane',
-        76 => 'Australia/Sydney',
-        43 => 'Pacific/Guam',
-        42 => 'Australia/Hobart',
-        68 => 'Asia/Vladivostok',
-        41 => 'Asia/Magadan',
-        17 => 'Pacific/Auckland',
-        40 => 'Pacific/Fiji',
-        67 => 'Pacific/Tongatapu',
-        29 => 'Atlantic/Azores',
-        53 => 'Atlantic/Cape_Verde',
-        30 => 'America/Noronha',
-         8 => 'America/Sao_Paulo', // Best guess
-        32 => 'America/Argentina/Buenos_Aires',
-        60 => 'America/Godthab',
-        28 => 'America/St_Johns',
-         9 => 'America/Halifax',
-        33 => 'America/Caracas',
-        65 => 'America/Santiago',
-        35 => 'America/Bogota',
-        10 => 'America/New_York',
-        34 => 'America/Indiana/Indianapolis',
-        55 => 'America/Guatemala',
-        11 => 'America/Chicago',
-        37 => 'America/Mexico_City',
-        36 => 'America/Edmonton',
-        38 => 'America/Phoenix',
-        12 => 'America/Denver', // Best guess
-        13 => 'America/Los_Angeles', // Best guess
-        14 => 'America/Anchorage',
-        15 => 'Pacific/Honolulu',
-        16 => 'Pacific/Midway',
-        39 => 'Pacific/Kwajalein',
-    );
-
-    /**
-     * This method will try to find out the correct timezone for an iCalendar
-     * date-time value.
-     *
-     * You must pass the contents of the TZID parameter, as well as the full
-     * calendar.
-     *
-     * If the lookup fails, this method will return the default PHP timezone
-     * (as configured using date_default_timezone_set, or the date.timezone ini
-     * setting).
-     *
-     * Alternatively, if $failIfUncertain is set to true, it will throw an
-     * exception if we cannot accurately determine the timezone.
-     *
-     * @param string $tzid
-     * @param Sabre\VObject\Component $vcalendar
-     * @return DateTimeZone
-     */
-    static public function getTimeZone($tzid, Component $vcalendar = null, $failIfUncertain = false) {
-
-        // First we will just see if the tzid is a support timezone identifier.
-        try {
-            return new \DateTimeZone($tzid);
-        } catch (\Exception $e) {
-        }
-
-        // Next, we check if the tzid is somewhere in our tzid map.
-        if (isset(self::$map[$tzid])) {
-            return new \DateTimeZone(self::$map[$tzid]);
-        }
-
-        // Maybe the author was hyper-lazy and just included an offset. We
-        // support it, but we aren't happy about it.
-        if (preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches)) {
-            return new \DateTimeZone('Etc/GMT' . $matches[1] . ltrim(substr($matches[2],0,2),'0'));
-        }
-
-        if ($vcalendar) {
-
-            // If that didn't work, we will scan VTIMEZONE objects
-            foreach($vcalendar->select('VTIMEZONE') as $vtimezone) {
-
-                if ((string)$vtimezone->TZID === $tzid) {
-
-                    // Some clients add 'X-LIC-LOCATION' with the olson name.
-                    if (isset($vtimezone->{'X-LIC-LOCATION'})) {
-
-                        $lic = (string)$vtimezone->{'X-LIC-LOCATION'};
-
-                        // Libical generators may specify strings like
-                        // "SystemV/EST5EDT". For those we must remove the
-                        // SystemV part.
-                        if (substr($lic,0,8)==='SystemV/') {
-                            $lic = substr($lic,8);
-                        }
-
-                        try {
-                            return new \DateTimeZone($lic);
-                        } catch (\Exception $e) {
-                        }
-
-                    }
-                    // Microsoft may add a magic number, which we also have an
-                    // answer for.
-                    if (isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) {
-                        $cdoId = (int)$vtimezone->{'X-MICROSOFT-CDO-TZID'}->value;
-
-                        // 2 can mean both Europe/Lisbon and Europe/Sarajevo.
-                        if ($cdoId===2 && strpos((string)$vtimezone->TZID, 'Sarajevo')!==false) {
-                            return new \DateTimeZone('Europe/Sarajevo');
-                        }
-
-                        if (isset(self::$microsoftExchangeMap[$cdoId])) {
-                            return new \DateTimeZone(self::$microsoftExchangeMap[$cdoId]);
-                        }
-                    }
-
-                }
-
-            }
-
-        }
-
-        if ($failIfUncertain) {
-            throw new \InvalidArgumentException('We were unable to determine the correct PHP timezone for tzid: ' . $tzid);
-        }
-
-        // If we got all the way here, we default to UTC.
-        return new \DateTimeZone(date_default_timezone_get());
-
-    }
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/Version.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This class contains the version number for the VObject package
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Version {
-
-    /**
-     * Full version number
-     */
-    const VERSION = '2.1.3';
-
-    /**
-     * Stability : alpha, beta, stable
-     */
-    const STABILITY = 'stable';
-
-}
--- a/plugins/libcalendaring/lib/Sabre/VObject/includes.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * Includes file
- *
- * This file includes the entire VObject library in one go.
- * The benefit is that an autoloader is not needed, which is often faster.
- *
- * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-
-// Begin includes
-include __DIR__ . '/DateTimeParser.php';
-include __DIR__ . '/ElementList.php';
-include __DIR__ . '/FreeBusyGenerator.php';
-include __DIR__ . '/Node.php';
-include __DIR__ . '/Parameter.php';
-include __DIR__ . '/ParseException.php';
-include __DIR__ . '/Property.php';
-include __DIR__ . '/Reader.php';
-include __DIR__ . '/RecurrenceIterator.php';
-include __DIR__ . '/Splitter/SplitterInterface.php';
-include __DIR__ . '/StringUtil.php';
-include __DIR__ . '/TimeZoneUtil.php';
-include __DIR__ . '/Version.php';
-include __DIR__ . '/Splitter/VCard.php';
-include __DIR__ . '/Component.php';
-include __DIR__ . '/Document.php';
-include __DIR__ . '/Property/Compound.php';
-include __DIR__ . '/Property/DateTime.php';
-include __DIR__ . '/Property/MultiDateTime.php';
-include __DIR__ . '/Splitter/ICalendar.php';
-include __DIR__ . '/Component/VAlarm.php';
-include __DIR__ . '/Component/VCalendar.php';
-include __DIR__ . '/Component/VEvent.php';
-include __DIR__ . '/Component/VFreeBusy.php';
-include __DIR__ . '/Component/VJournal.php';
-include __DIR__ . '/Component/VTodo.php';
-// End includes
--- a/vendor/autoload.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<?php
-
-// autoload.php @generated by Composer
-
-require_once __DIR__ . '/composer/autoload_real.php';
-
-return ComposerAutoloaderInitd52cd7aa2b1301e6e89413f57235d2fc::getLoader();
--- a/vendor/sabre/vobject/.gitignore	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-# Composer stuff
-vendor/
-composer.lock
-tests/cov/
-tests/temp
-
-#vim
-.*.swp
-
-#binaries
-bin/phpunit
-bin/phpcs
-
-# Development stuff
-testdata/
-
-# OS X
-.DS_Store
--- a/vendor/sabre/vobject/.travis.yml	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-language: php
-php:
-  - 5.3
-  - 5.4
-  - 5.5
-  - 5.6
-  - hhvm
-
-matrix:
-  fast_finish: true
-
-script:
-  - phpunit --configuration tests/phpunit.xml
-  - ./bin/phpcs -p --standard=tests/phpcs/ruleset.xml lib/
-
-
-before_script: composer install
--- a/vendor/sabre/vobject/ChangeLog.md	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,494 +0,0 @@
-ChangeLog
-=========
-
-3.3.5 (2015-01-09)
-------------------
-
-* #168: Expanding calendars now removes objects with recurrence rules that
-  don't have a valid recurrence instance.
-* #177: SCHEDULE-STATUS should not contain a reason phrase, only a status
-  code.
-* #175: Parser can now read and skip the UTF-8 BOM.
-* #179: Added `isFloating` to `DATE-TIME` properties.
-* #179: Fixed jCal serialization of floating `DATE-TIME` properties.
-* #173: vCard converter failed for `X-ABDATE` properties that had no
-  `X-ABLABEL`.
-
-
-3.3.4 (2014-11-19)
-------------------
-
-* #154: Converting `ANNIVERSARY` to `X-ANNIVERSARY` and `X-ABDATE` and
-  vice-versa when converting to/from vCard 4.
-* #154: It's now possible to easily select all vCard properties belonging to
-  a single group with `$vcard->{'ITEM1.'}` syntax. (@armin-hackmann)
-* #156: Simpler way to check if a string is UTF-8. (@Hywan)
-* Unittest improvements.
-* #159: The recurrence iterator, freebusy generator and iCalendar DATE and
-  DATE-TIME properties can now all accept a reference timezone when working
-  floating times or all-day events.
-* #159: Master events will no longer get a `RECURRENCE-ID` when expanding.
-* #159: `RECURRENCE-ID` for all-day events will now be correct when expanding.
-* #163: Added a `getTimeZone()` method to `VTIMEZONE` components.
-
-
-3.3.3 (2014-10-09)
-------------------
-
-* #142: `CANCEL` and `REPLY` messages now include the `DTSTART` from the
-  original event.
-* #143: `SCHEDULE-AGENT` on the `ORGANIZER` property is respected.
-* #144: `PARTSTAT=NEEDS-ACTION` is now set for new invites, if no `PARTSTAT` is
-  set to support the inbox feature of iOS.
-* #147: Bugs related to scheduling all-day events.
-* #148: Ignore events that have attendees but no organizer.
-* #149: Avoiding logging errors during timezone detection. This is a workaround
-  for a PHP bug.
-* Support for "Line Islands Standard Time" windows timezone.
-* #154: Correctly work around vCard parameters that have a value but no name.
-
-
-3.3.2 (2014-09-19)
-------------------
-
-* Changed: iTip broker now sets RSVP status to false when replies are received.
-* #118: iTip Message now has a `getScheduleStatus()` method.
-* #119: Support for detecting 'significant changes'.
-* #120: Support for `SCHEDULE-FORCE-SEND`.
-* #121: iCal demands parameters containing the + sign to be quoted.
-* #122: Don't generate REPLY messages for events that have been cancelled.
-* #123: Added `SUMMARY` to iTip messages.
-* #130: Incorrect validation rules for `RELATED` (should be `RELATED-TO`).
-* #128: `ATTACH` in iCalendar is `URI` by default, not `BINARY`.
-* #131: RRULE that doesn't provide a single valid instance now throws an
-  exception.
-* #136: Validator rejects *all* control characters. We were missing a few.
-* #133: Splitter objects will throw exceptions when receiving incompatible
-  objects.
-* #127: Attendees who delete recurring event instances events they had already
-  declined earlier will no longer generate another reply.
-* #125: Send CANCEL messages when ORGANIZER property gets deleted.
-
-
-3.3.1 (2014-08-18)
-------------------
-
-* Changed: It's now possible to pass DateTime objects when using the magic
-  setters on properties. (`$event->DTSTART = new DateTime('now')`).
-* #111: iTip Broker does not process attendee adding events to EXDATE.
-* #112: EventIterator now sets TZID on RECURRENCE-ID.
-* #113: Timezone support during creation of iTip REPLY messages.
-* #114: VTIMEZONE is retained when generating new REQUEST objects.
-* #114: Support for 'MAILTO:' style email addresses (in uppercase) in the iTip
-  broker. This improves evolution support.
-* #115: Using REQUEST-STATUS from REPLY messages and now propegating that into
-  SCHEDULE-STATUS.
-
-
-3.3.0 (2014-08-07)
-------------------
-
-* We now use PSR-4 for the directory structure. This means that everything
-  that was used to be in the `lib/Sabre/VObject` directory is now moved to
-  `lib/`. If you use composer to load this library, you shouldn't have to do
-  anything about that though.
-* VEVENT now get populated with a DTSTAMP and UID property by default.
-* BC Break: Removed the 'includes.php' file. Use composer instead.
-* #103: Added support for processing [iTip][iTip] messages. This allows a user
-  to parse incoming iTip messages and apply the result on existing calendars,
-  or automatically generate invites/replies/cancellations based on changes that
-  a user made on objects.
-* #75, #58, #18: Fixes related to overriding the first event in recurrences.
-* Added: VCalendar::getBaseComponent to find the 'master' component in a
-  calendar.
-* #51: Support for iterating RDATE properties.
-* Fixed: Issue #101: RecurrenceIterator::nextMonthly() shows events that are
-  excluded events with wrong time
-
-
-3.2.4 (2014-07-14)
-------------------
-
-* Added: Issue #98. The VCardConverter now takes `X-APPLE-OMIT-YEAR` into
-  consideration when converting between vCard 3 and 4.
-* Fixed: Issue #96. Some support for Yahoo's broken vcards.
-* Fixed: PHP 5.3 support was broken in the cli tool.
-
-
-3.2.3 (2014-06-12)
-------------------
-
-* Validator now checks if DUE and DTSTART are of the same type in VTODO, and
-  ensures that DUE is always after DTSTART.
-* Removed documentation from source repository, to http://sabre.io/vobject/
-* Expanded the vobject cli tool validation output to make it easier to find
-  issues.
-* Fixed: vobject repair. It was not working for iCalendar objects.
-
-
-3.2.2 (2014-05-07)
-------------------
-
-* Minor tweak in unittests to make it run on PHP 5.5.12. Json-prettifying
-  slightly changed which caused the test to fail.
-
-
-3.2.1 (2014-05-03)
-------------------
-
-* Minor tweak to make the unittests run with the latest hhvm on travis.
-* Updated timezone definitions.
-* Updated copyright links to point to http://sabre.io/
-
-
-3.2.0 (2014-04-02)
-------------------
-
-* Now hhvm compatible!
-* The validator can now detect a _lot_ more problems. Many rules for both
-  iCalendar and vCard were added.
-* Added: bin/generate_vcards, a utility to generate random vcards for testing
-  purposes. Patches are welcome to add more data.
-* Updated: Windows timezone mapping to latest version from unicode.org
-* Changed: The timezone maps are now loaded in from external files, in
-  lib/Sabre/VObject/timezonedata.
-* Added: Fixing badly encoded URL's from google contacts vcards.
-* Fixed: Issue #68. Couldn't decode properties ending in a colon.
-* Fixed: Issue #72. RecurrenceIterator should respect timezone in the UNTIL
-  clause.
-* Fixed: Issue #67. BYMONTH limit on DAILY recurrences.
-* Fixed: Issue #26. Return a more descriptive error when coming across broken
-  BYDAY rules.
-* Fixed: Issue #28. Incorrect timezone detection for some timezones.
-* Fixed: Issue #70. Casting a parameter with a null value to string would fail.
-* Added: Support for rfc6715 and rfc6474.
-* Added: Support for DateTime objects in the VCard DATE-AND-OR-TIME property.
-* Added: UUIDUtil, for easily creating unique identifiers.
-* Fixed: Issue #83. Creating new VALUE=DATE objects using php's DateTime.
-* Fixed: Issue #86. Don't go into an infinite loop when php errors are
-  disabled and an invalid file is read.
-
-
-3.1.4 (2014-03-30)
-------------------
-
-* Fixed: Issue #87: Several compatibility fixes related to timezone handling
-  changes in PHP 5.5.10.
-
-
-3.1.3 (2013-10-02)
-------------------
-
-* Fixed: Support from properties from draft-daboo-valarm-extensions-04. Issue
-  #56.
-* Fixed: Issue #54. Parsing a stream of multiple vcards separated by more than
-  one newline. Thanks @Vedmak for the patch.
-* Fixed: Serializing vcard 2.1 parameters with no name caused a literal '1' to
-  be inserted.
-* Added: VCardConverter removed properties that are no longer supported in vCard
-  4.0.
-* Added: vCards with a minimum number of values (such as N), but don't have that
-  many, are now automatically padded with empty components.
-* Added: The vCard validator now also checks for a minimum number of components,
-  and has the ability to repair these.
-* Added: Some support for vCard 2.1 in the VCard converter, to upgrade to vCard
-  3.0 or 4.0.
-* Fixed: Issue 60 Use Document::$componentMap when instantiating the top-level
-  VCalendar and VCard components.
-* Fixed: Issue 62: Parsing iCalendar parameters with no value.
-* Added: --forgiving option to vobject utility.
-* Fixed: Compound properties such as ADR were not correctly split up in vCard
-  2.1 quoted printable-encoded properties.
-* Fixed: Issue 64: Encoding of binary properties of converted vCards. Thanks
-  @DominikTo for the patch.
-
-
-3.1.2 (2013-08-13)
-------------------
-
-* Fixed: Setting correct property group on VCard conversion
-
-
-3.1.1 (2013-08-02)
-------------------
-
-* Fixed: Issue #53. A regression in RecurrenceIterator.
-
-
-3.1.0 (2013-07-27)
-------------------
-
-* Added: bad-ass new cli debugging utility (in bin/vobject).
-* Added: jCal and jCard parser.
-* Fixed: URI properties should not escape ; and ,.
-* Fixed: VCard 4 documents now correctly use URI as a default value-type for
-  PHOTO and others. BINARY no longer exists in vCard 4.
-* Added: Utility to convert between 2.1, 3.0 and 4.0 vCards.
-* Added: You can now add() multiple parameters to a property in one call.
-* Added: Parameter::has() for easily checking if a parameter value exists.
-* Added: VCard::preferred() to find a preferred email, phone number, etc for a
-  contact.
-* Changed: All $duration properties are now public.
-* Added: A few validators for iCalendar documents.
-* Fixed: Issue #50. RecurrenceIterator gives incorrect result when exception
-  events are out of order in the iCalendar file.
-* Fixed: Issue #48. Overridden events in the recurrence iterator that were past
-  the UNTIL date were ignored.
-* Added: getDuration for DURATION values such as TRIGGER. Thanks to
-  @SimonSimCity.
-* Fixed: Issue #52. vCard 2.1 parameters with no name may lose values if there's
-  more than 1. Thanks to @Vedmak.
-
-
-3.0.0 (2013-06-21)
-------------------
-
-* Fixed: includes.php file was still broken. Our tool to generate it had some
-  bugs.
-
-
-3.0.0-beta4 (2013-06-21)
-------------------------
-
-* Fixed: includes.php was no longer up to date.
-
-
-3.0.0-beta3 (2013-06-17)
-------------------------
-
-* Added: OPTION_FORGIVING now also allows slashes in property names.
-* Fixed: DateTimeParser no longer fails on dates with years < 1000 & > 4999
-* Fixed: Issue 36: Workaround for the recurrenceiterator and caldav events with
-  a missing base event.
-* Fixed: jCard encoding of TIME properties.
-* Fixed: jCal encoding of REQUEST-STATUS, GEO and PERIOD values.
-
-
-3.0.0-beta2 (2013-06-10)
-------------------------
-
-* Fixed: Corrected includes.php file.
-* Fixed: vCard date-time parser supported extended-format dates as well.
-* Changed: Properties have been moved to an ICalendar or VCard directory.
-* Fixed: Couldn't parse vCard 3 extended format dates and times.
-* Fixed: Couldn't export jCard DATE values correctly.
-* Fixed: Recursive loop in ICalendar\DateTime property.
-
-
-3.0.0-beta1 (2013-06-07)
-------------------------
-
-* Added: jsonSerialize() for creating jCal and jCard documents.
-* Added: helper method to parse vCard dates and times.
-* Added: Specialized classes for FLOAT, LANGUAGE-TAG, TIME, TIMESTAMP,
-  DATE-AND-OR-TIME, CAL-ADDRESS, UNKNOWN and UTC-OFFSET properties.
-* Removed: CommaSeparatedText property. Now included into Text.
-* Fixed: Multiple parameters with the same name are now correctly encoded.
-* Fixed: Parameter values containing a comma are now enclosed in double-quotes.
-* Fixed: Iterating parameter values should now fully work as expected.
-* Fixed: Support for vCard 2.1 nameless parameters.
-* Changed: $valueMap, $componentMap and $propertyMap now all use fully-qualified
-  class names, so they are actually overridable.
-* Fixed: Updating DATE-TIME to DATE values now behaves like expected.
-
-
-3.0.0-alpha4 (2013-05-31)
--------------------------
-
-* Added: It's now possible to send parser options to the splitter classes.
-* Added: A few tweaks to improve component and property creation.
-
-
-3.0.0-alpha3 (2013-05-13)
--------------------------
-
-* Changed: propertyMap, valueMap and componentMap are now static properties.
-* Changed: Component::remove() will throw an exception when trying to a node
-  that's not a child of said component.
-* Added: Splitter objects are now faster, line numbers are accurately reported
-  and use less memory.
-* Added: MimeDir parser can now continue parsing with the same stream buffer.
-* Fixed: vobjectvalidate.php is operational again.
-* Fixed: \r is properly stripped in text values.
-* Fixed: QUOTED-PRINTABLE is now correctly encoded as well as encoded, for
-  vCards 2.1.
-* Fixed: Parser assumes vCard 2.1, if no version was supplied.
-
-
-3.0.0-alpha2 (2013-05-22)
--------------------------
-
-* Fixed: vCard URL properties were referencing a non-existant class.
-
-
-3.0.0-alpha1 (2013-05-21)
--------------------------
-
-* Fixed: Now correctly dealing with escaping of properties. This solves the
-  problem with double-backslashes where they don't belong.
-* Added: Easy support for properties with more than one value, using setParts
-  and getParts.
-* Added: Support for broken 2.1 vCards produced by microsoft.
-* Added: Automatically decoding quoted-printable values.
-* Added: Automatically decoding base64 values.
-* Added: Decoding RFC6868 parameter values (uses ^ as an escape character).
-* Added: Fancy new MimeDir parser that can also parse streams.
-* Added: Automatically mapping many, many properties to a property-class with
-  specialized API's.
-* Added: remove() method for easily removing properties and sub-components
-  components.
-* Changed: Components, Properties and Parameters can no longer be created with
-  Component::create, Property::create and Parameter::create. They must instead
-  be created through the root component. (A VCalendar or VCard object).
-* Changed: API for DateTime properties has slightly changed.
-* Changed: the ->value property is now protected everywhere. Use getParts() and
-  getValue() instead.
-* BC Break: No support for mac newlines (\r). Never came across these anyway.
-* Added: add() method to the Property class.
-* Added: It's now possible to easy set multi-value properties as arrays.
-* Added: When setting date-time properties you can just pass PHP's DateTime
-  object.
-* Added: New components automatically get a bunch of default properties, such as
-  VERSION and CALSCALE.
-* Added: You can add new sub-components much quicker with the magic setters, and
-  add() method.
-
-
-2.1.6 (2014-12-10)
-------------------
-
-* Fixed: Minor change to make sure that unittests succeed on every PHP version.
-
-
-2.1.5 (2014-06-03)
-------------------
-
-* Fixed: #94: Better parameter escaping.
-* Changed: Documentation cleanups.
-
-
-2.1.4 (2014-03-30)
-------------------
-
-* Fixed: Issue #87: Several compatibility fixes related to timezone handling
-  changes in PHP 5.5.10.
-
-
-2.1.3 (2013-10-02)
-------------------
-
-* Fixed: Issue #55. \r must be stripped from property values.
-* Fixed: Issue #65. Putting quotes around parameter values that contain a colon.
-
-
-2.1.2 (2013-08-02)
-------------------
-
-* Fixed: Issue #53. A regression in RecurrenceIterator.
-
-
-2.1.1 (2013-07-27)
-------------------
-
-* Fixed: Issue #50. RecurrenceIterator gives incorrect result when exception
-  events are out of order in the iCalendar file.
-* Fixed: Issue #48. Overridden events in the recurrence iterator that were past
-  the UNTIL date were ignored.
-
-
-2.1.0 (2013-06-17)
-------------------
-
-* This version is fully backwards compatible with 2.0.\*. However, it contains a
-  few new API's that mimic the VObject 3 API. This allows it to be used a
-  'bridge' version. Specifically, this new version exists so SabreDAV 1.7 and
-  1.8 can run with both the 2 and 3 versions of this library.
-* Added: Property\DateTime::hasTime().
-* Added: Property\MultiDateTime::hasTime().
-* Added: Property::getValue().
-* Added: Document class.
-* Added: Document::createComponent and Document::createProperty.
-* Added: Parameter::getValue().
-
-
-2.0.7 (2013-03-05)
-------------------
-
-* Fixed: Microsoft re-uses their magic numbers for different timezones,
-  specifically id 2 for both Sarajevo and Lisbon). A workaround was added to
-  deal with this.
-
-
-2.0.6 (2013-02-17)
-------------------
-
-* Fixed: The reader now properly parses parameters without a value.
-
-
-2.0.5 (2012-11-05)
-------------------
-
-* Fixed: The FreeBusyGenerator is now properly using the factory methods for
-  creation of components and properties.
-
-
-2.0.4 (2012-11-02)
-------------------
-
-* Added: Known Lotus Notes / Domino timezone id's.
-
-
-2.0.3 (2012-10-29)
-------------------
-
-* Added: Support for 'GMT+????' format in TZID's.
-* Added: Support for formats like SystemV/EST5EDT in TZID's.
-* Fixed: RecurrenceIterator now repairs recurrence rules where UNTIL < DTSTART.
-* Added: Support for BYHOUR in FREQ=DAILY (@hollodk).
-* Added: Support for BYHOUR and BYDAY in FREQ=WEEKLY.
-
-
-2.0.2 (2012-10-06)
-------------------
-
-* Added: includes.php file, to load the entire library in one go.
-* Fixed: A problem with determining alarm triggers for TODO's.
-
-
-2.0.1 (2012-09-22)
-------------------
-
-* Removed: Element class. It wasn't used.
-* Added: Basic validation and repair methods for broken input data.
-* Fixed: RecurrenceIterator could infinitely loop when an INTERVAL of 0 was
-  specified.
-* Added: A cli script that can validate and automatically repair vcards and
-  iCalendar objects.
-* Added: A new 'Compound' property, that can automatically split up parts for
-  properties such as N, ADR, ORG and CATEGORIES.
-* Added: Splitter classes, that can split up large objects (such as exports)
-  into individual objects (thanks @DominikTO and @armin-hackmann).
-* Added: VFREEBUSY component, which allows easily checking wether timeslots are
-  available.
-* Added: The Reader class now has a 'FORGIVING' option, which allows it to parse
-  properties with incorrect characters in the name (at this time, it just allows
-  underscores).
-* Added: Also added the 'IGNORE_INVALID_LINES' option, to completely disregard
-  any invalid lines.
-* Fixed: A bug in Windows timezone-id mappings for times created in Greenlands
-  timezone (sorry Greenlanders! I do care!).
-* Fixed: DTEND was not generated correctly for VFREEBUSY reports.
-* Fixed: Parser is at least 25% faster with real-world data.
-
-
-2.0.0 (2012-08-08)
-------------------
-
-* VObject is now a separate project from SabreDAV. See the SabreDAV changelog
-  for version information before 2.0.
-* New: VObject library now uses PHP 5.3 namespaces.
-* New: It's possible to specify lists of parameters when constructing
-  properties.
-* New: made it easier to construct the FreeBusyGenerator.
-
-[iTip]: http://tools.ietf.org/html/rfc5546
--- a/vendor/sabre/vobject/LICENSE	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/)
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name Sabre nor the names of its contributors
-      may be used to endorse or promote products derived from this software
-      without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-    POSSIBILITY OF SUCH DAMAGE.
--- a/vendor/sabre/vobject/README.md	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-sabre/vobject
-=============
-
-The VObject library allows you to easily parse and manipulate [iCalendar](https://tools.ietf.org/html/rfc5545)
-and [vCard](https://tools.ietf.org/html/rfc6350) objects using PHP.
-
-The goal of the VObject library is to create a very complete library, with an easy to use API.
-
-Build status
-------------
-
-| branch | status |
-| ------ | ------ |
-| master | [![Build Status](https://travis-ci.org/fruux/sabre-vobject.png?branch=master)](https://travis-ci.org/fruux/sabre-vobject) |
-| 3.3    | [![Build Status](https://travis-ci.org/fruux/sabre-vobject.png?branch=3.3)](https://travis-ci.org/fruux/sabre-vobject) |
-| 3.1    | [![Build Status](https://travis-ci.org/fruux/sabre-vobject.png?branch=3.1)](https://travis-ci.org/fruux/sabre-vobject) |
-| 2.1    | [![Build Status](https://travis-ci.org/fruux/sabre-vobject.png?branch=2.1)](https://travis-ci.org/fruux/sabre-vobject) |
-| 2.0    | [![Build Status](https://travis-ci.org/fruux/sabre-vobject.png?branch=2.0)](https://travis-ci.org/fruux/sabre-vobject) |
-
-
-Installation
-------------
-
-VObject requires PHP 5.3, and should be installed using composer.
-The general composer instructions can be found on the [composer website](http://getcomposer.org/doc/00-intro.md composer website).
-
-After that, just declare the vobject dependency as follows:
-
-    "require" : {
-        "sabre/vobject" : "~3.3"
-    }
-
-Then, run `composer.phar update` and you should be good.
-
-Usage
------
-
-* [3.x documentation](http://sabre.io/vobject/usage/)
-* [2.x documentation](http://sabre.io/vobject/usage_2/)
-* [Migrating from 2.x to 3.x](http://sabre.io/vobject/upgrade/)
-
-Support
--------
-
-Head over to the [SabreDAV mailing list](http://groups.google.com/group/sabredav-discuss) for any questions.
-
-Made at fruux
--------------
-
-This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support.
--- a/vendor/sabre/vobject/bin/bench.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-include __DIR__ . '/../vendor/autoload.php';
-
-$data = stream_get_contents(STDIN);
-
-$start = microtime(true); 
-
-$lol = Sabre\VObject\Reader::read($data);
-
-echo "time: " . (microtime(true)-$start) . "\n";
--- a/vendor/sabre/vobject/bin/fetch_windows_zones.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-$windowsZonesUrl = 'http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml';
-$outputFile = __DIR__ . '/../lib/timezonedata/windowszones.php';
-
-echo "Fetching timezone map from: " . $windowsZonesUrl, "\n";
-
-$data = file_get_contents($windowsZonesUrl);
-
-$xml = simplexml_load_string($data);
-
-$map = [];
-
-foreach($xml->xpath('//mapZone') as $mapZone) {
-
-    $from = (string)$mapZone['other'];
-    $to = (string)$mapZone['type'];
-
-    list($to) = explode(' ', $to, 2);
-
-    if (!isset($map[$from])) {
-        $map[$from] = $to;
-    }
-
-}
-
-ksort($map);
-echo "Writing to: $outputFile\n";
-
-$f = fopen($outputFile,'w');
-fwrite($f, "<?php\n\n");
-fwrite($f, "/**\n");
-fwrite($f, " * Automatically generated timezone file\n");
-fwrite($f, " *\n");
-fwrite($f, " * Last update: " . date(DATE_W3C) . "\n");
-fwrite($f, " * Source: " .$windowsZonesUrl . "\n");
-fwrite($f, " *\n");
-fwrite($f, " * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).\n");
-fwrite($f, " * @license http://sabre.io/license/ Modified BSD License\n");
-fwrite($f, " */\n");
-fwrite($f, "\n");
-fwrite($f, "return ");
-fwrite($f, var_export($map, true) . ';');
-fclose($f);
-
-echo "Done\n";
--- a/vendor/sabre/vobject/bin/generate_vcards	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-namespace Sabre\VObject;
-
-// This sucks.. we have to try to find the composer autoloader. But chances
-// are, we can't find it this way. So we'll do our bestest
-$paths = array(
-    __DIR__ . '/../vendor/autoload.php',  // In case vobject is cloned directly
-    __DIR__ . '/../../../autoload.php',   // In case vobject is a composer dependency.
-);
-
-foreach($paths as $path) {
-    if (file_exists($path)) {
-        include $path;
-        break;
-    }
-}
-
-if (!class_exists('Sabre\\VObject\\Version')) {
-    fwrite(STDERR, "Composer autoloader could not be properly loaded.\n");
-    die(1);
-}
-
-if ($argc < 2) {
-
-    $version = Version::VERSION;
-
-    $help = <<<HI
-sabre/vobject $version
-Usage:
-    generate_vcards [count]
-
-Options:
-    count   The number of random vcards to generate
-
-Examples:
-    generate_vcards 1000 > testdata.vcf
-
-HI;
-
-    fwrite(STDERR, $help);
-    exit(2);
-}
-
-$count = (int)$argv[1];
-if ($count < 1) {
-    fwrite(STDERR, "Count must be at least 1\n");
-    exit(2);
-}
-
-fwrite(STDERR, "sabre/vobject " . Version::VERSION . "\n");
-fwrite(STDERR, "Generating " . $count . " vcards in vCard 4.0 format\n");
-
-/**
- * The following list is just some random data we compiled from various
- * sources online.
- *
- * Very little thought went into compiling this list, and certainly nothing
- * political or ethical.
- *
- * We would _love_ more additions to this to add more variation to this list.
- *
- * Send us PR's and don't be shy adding your own first and last name for fun.
- */
-
-$sets = [
-    "nl" => [
-        "country" => "Netherlands",
-        "boys" => [
-            "Anno",
-            "Bram",
-            "Daan",
-            "Evert",
-            "Finn",
-            "Jayden",
-            "Jens",
-            "Jesse",
-            "Levi",
-            "Lucas",
-            "Luuk",
-            "Milan",
-            "René",
-            "Sem",
-            "Sibrand",
-            "Willem",
-        ],
-        "girls" => [
-            "Celia",
-            "Emma",
-            "Fenna",
-            "Geke",
-            "Inge",
-            "Julia",
-            "Lisa",
-            "Lotte",
-            "Mila",
-            "Sara",
-            "Sophie",
-            "Tess",
-            "Zoë",
-        ],
-        "last" => [
-            "Bakker",
-            "Bos",
-            "De Boer",
-            "De Groot",
-            "De Jong",
-            "De Vries",
-            "Jansen",
-            "Janssen",
-            "Meyer",
-            "Mulder",
-            "Peters",
-            "Smit",
-            "Van Dijk",
-            "Van den Berg",
-            "Visser",
-            "Vos",
-        ],
-    ],
-    "us" => [
-        "country" => "United States",
-        "boys" => [
-            "Aiden",
-            "Alexander",
-            "Charles",
-            "David",
-            "Ethan",
-            "Jacob",
-            "James",
-            "Jayden",
-            "John",
-            "Joseph",
-            "Liam",
-            "Mason",
-            "Michael",
-            "Noah",
-            "Richard",
-            "Robert",
-            "Thomas",
-            "William",
-        ],
-        "girls" => [
-            "Ava",
-            "Barbara",
-            "Chloe",
-            "Dorothy",
-            "Elizabeth",
-            "Emily",
-            "Emma",
-            "Isabella",
-            "Jennifer",
-            "Lily",
-            "Linda",
-            "Margaret",
-            "Maria",
-            "Mary",
-            "Mia",
-            "Olivia",
-            "Patricia",
-            "Roxy",
-            "Sophia",
-            "Susan",
-            "Zoe",
-        ],
-        "last" => [
-            "Smith",
-            "Johnson",
-            "Williams",
-            "Jones",
-            "Brown",
-            "Davis",
-            "Miller",
-            "Wilson",
-            "Moore",
-            "Taylor",
-            "Anderson",
-            "Thomas",
-            "Jackson",
-            "White",
-            "Harris",
-            "Martin",
-            "Thompson",
-            "Garcia",
-            "Martinez",
-            "Robinson",
-        ],
-    ],
-];
-
-$current = 0;
-
-$r = function($arr) {
-
-    return $arr[mt_rand(0,count($arr)-1)];
-
-};
-
-$bdayStart = strtotime('-85 years');
-$bdayEnd = strtotime('-20 years');
-
-while($current < $count) {
-
-    $current++;
-    fwrite(STDERR, "\033[100D$current/$count");
-
-    $country = array_rand($sets);
-    $gender = mt_rand(0,1)?'girls':'boys';
-
-    $vcard = new Component\VCard([
-        'VERSION' => '4.0',
-        'FN' => $r($sets[$country][$gender]) . ' ' . $r($sets[$country]['last']),
-        'UID' => UUIDUtil::getUUID(),
-    ]);
-
-    $bdayRatio = mt_rand(0,9);
-
-    if($bdayRatio < 2) {
-        // 20% has a birthday property with a full date
-        $dt = new \DateTime('@' . mt_rand($bdayStart, $bdayEnd));
-        $vcard->add('BDAY', $dt->format('Ymd'));
-
-    } elseif ($bdayRatio < 3) {
-        // 10% we only know the month and date of
-        $dt = new \DateTime('@' . mt_rand($bdayStart, $bdayEnd));
-        $vcard->add('BDAY', '--' . $dt->format('md'));
-    }
-    if ($result = $vcard->validate()) {
-        ob_start();
-        echo "\nWe produced an invalid vcard somehow!\n";
-        foreach($result as $message) {
-            echo "  " . $message['message'] . "\n";
-        }
-        fwrite(STDERR, ob_get_clean());
-    }
-    echo $vcard->serialize();
-
-}
-
-fwrite(STDERR,"\nDone.\n");
--- a/vendor/sabre/vobject/bin/generateicalendardata.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-use Sabre\VObject;
-
-if ($argc<2) {
-    $cmd = $argv[0];
-    fwrite(STDERR, <<<HI
-Fruux test data generator
-
-This script generates a lot of test data. This is used for profiling and stuff.
-Currently it just generates events in a single calendar.
-
-The iCalendar output goes to stdout. Other messages to stderr.
-
-{$cmd} [events]
-
-
-HI
-    );
-    die();
-}
-
-$events = 100;
-
-if (isset($argv[1])) $events = (int)$argv[1];
-
-include __DIR__ . '/../vendor/autoload.php';
-
-fwrite(STDERR, "Generating " . $events . " events\n");
-
-$currentDate = new DateTime('-' . round($events/2) .  ' days');
-
-$calendar = VObject\Component::create('VCALENDAR');
-$calendar->version = '2.0';
-$calendar->calscale = 'GREGORIAN';
-
-$ii=0;
-
-while($ii < $events) {
-
-    $ii++;
-
-    $event = VObject\Component::create('VEVENT');
-    $event->DTSTART = 'bla';
-    $event->SUMMARY = 'Event #' . $ii;
-    $event->UID = md5(microtime(true));
-
-    $doctorRandom = mt_rand(1,1000);
-
-    switch($doctorRandom) {
-        // All-day event
-        case 1 : 
-            $event->DTEND = 'bla';
-            $dtStart = clone $currentDate;
-            $dtEnd = clone $currentDate;
-            $dtEnd->modify('+' . mt_rand(1,3) . ' days');
-            $event->DTSTART->setDateTime($dtStart, VObject\Property\DateTime::DATE);
-            $event->DTEND->setDateTime($dtEnd, VObject\Property\DateTime::DATE);
-            break;
-        case 2 :
-            $event->RRULE = 'FREQ=DAILY;COUNT=' . mt_rand(1,10);
-            // No break intentional
-        default :
-            $dtStart = clone $currentDate;
-            $dtStart->setTime(mt_rand(1,23), mt_rand(0,59), mt_rand(0,59));
-            $event->DTSTART->setDateTime($dtStart, VObject\Property\DateTime::UTC);
-            $event->DURATION = 'PT'.mt_rand(1,3).'H';
-            break;
-
-    }
-    
-    $calendar->add($event);
-    $currentDate->modify('+ ' . mt_rand(0,3) . ' days');
-
-}
-fwrite(STDERR, "Validating\n");
-
-$result = $calendar->validate();
-if ($result) {
-    fwrite(STDERR, "Errors!\n");
-    fwrite(STDERR, print_r($result,true));
-    die(-1);
-}
-
-fwrite(STDERR, "Serializing this beast\n");
-
-echo $calendar->serialize();
-
-fwrite(STDERR, "done.\n");
-
--- a/vendor/sabre/vobject/bin/vobject	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-namespace Sabre\VObject;
-
-// This sucks.. we have to try to find the composer autoloader. But chances
-// are, we can't find it this way. So we'll do our bestest
-$paths = array(
-    __DIR__ . '/../vendor/autoload.php',  // In case vobject is cloned directly
-    __DIR__ . '/../../../autoload.php',   // In case vobject is a composer dependency.
-);
-
-foreach($paths as $path) {
-    if (file_exists($path)) {
-        include $path;
-        break;
-    }
-}
-
-if (!class_exists('Sabre\\VObject\\Version')) {
-    fwrite(STDERR, "Composer autoloader could not be loaded.\n");
-    die(1);
-}
-
-$cli = new Cli();
-exit($cli->main($argv));
-
--- a/vendor/sabre/vobject/composer.json	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-{
-    "name": "sabre/vobject",
-    "description" : "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
-    "keywords" : [ "VObject", "iCalendar", "vCard", "jCard", "jCal" ],
-    "homepage" : "http://sabre.io/vobject/",
-    "license" : "BSD-3-Clause",
-    "require" : {
-        "php"          : ">=5.3.1",
-        "ext-mbstring" : "*"
-    },
-    "require-dev" : {
-        "phpunit/phpunit" : "*",
-        "squizlabs/php_codesniffer": "*"
-    },
-    "authors" : [
-        {
-            "name" : "Evert Pot",
-            "email" : "me@evertpot.com",
-            "homepage" : "http://evertpot.com/",
-            "role" : "Developer"
-        },
-        {
-            "name" : "Dominik Tobschall",
-            "email" : "dominik@fruux.com",
-            "homepage" : "http://tobschall.de/",
-            "role" : "Developer"
-        }
-    ],
-    "support" : {
-        "forum" : "https://groups.google.com/group/sabredav-discuss",
-        "source" : "https://github.com/fruux/sabre-vobject"
-    },
-    "autoload" : {
-        "psr-4" : {
-            "Sabre\\VObject\\" : "lib/"
-        }
-    },
-    "bin" : [
-        "bin/vobject",
-        "bin/generate_vcards"
-    ],
-    "extra" : {
-        "branch-alias" : {
-            "dev-master" : "3.2.x-dev"
-        }
-    },
-    "config" : {
-        "bin-dir" : "bin"
-    }
-}
--- a/vendor/sabre/vobject/lib/Cli.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,761 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    InvalidArgumentException;
-
-/**
- * This is the CLI interface for sabre-vobject.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Cli {
-
-    /**
-     * No output
-     *
-     * @var bool
-     */
-    protected $quiet = false;
-
-    /**
-     * Help display
-     *
-     * @var bool
-     */
-    protected $showHelp = false;
-
-    /**
-     * Wether to spit out 'mimedir' or 'json' format.
-     *
-     * @var string
-     */
-    protected $format;
-
-    /**
-     * JSON pretty print
-     *
-     * @var bool
-     */
-    protected $pretty;
-
-    /**
-     * Source file
-     *
-     * @var string
-     */
-    protected $inputPath;
-
-    /**
-     * Destination file
-     *
-     * @var string
-     */
-    protected $outputPath;
-
-    /**
-     * output stream
-     *
-     * @var resource
-     */
-    protected $stdout;
-
-    /**
-     * stdin
-     *
-     * @var resource
-     */
-    protected $stdin;
-
-    /**
-     * stderr
-     *
-     * @var resource
-     */
-    protected $stderr;
-
-    /**
-     * Input format (one of json or mimedir)
-     *
-     * @var string
-     */
-    protected $inputFormat;
-
-    /**
-     * Makes the parser less strict.
-     *
-     * @var bool
-     */
-    protected $forgiving = false;
-
-    /**
-     * Main function
-     *
-     * @return int
-     */
-    public function main(array $argv) {
-
-        // @codeCoverageIgnoreStart
-        // We cannot easily test this, so we'll skip it. Pretty basic anyway.
-
-        if (!$this->stderr) {
-            $this->stderr = fopen('php://stderr', 'w');
-        }
-        if (!$this->stdout) {
-            $this->stdout = fopen('php://stdout', 'w');
-        }
-        if (!$this->stdin) {
-            $this->stdin = fopen('php://stdin', 'r');
-        }
-
-        // @codeCoverageIgnoreEnd
-
-
-        try {
-
-            list($options, $positional) = $this->parseArguments($argv);
-
-            if (isset($options['q'])) {
-                $this->quiet = true;
-            }
-            $this->log($this->colorize('green', "sabre/vobject ") . $this->colorize('yellow', Version::VERSION));
-
-            foreach($options as $name=>$value) {
-
-                switch($name) {
-
-                    case 'q' :
-                        // Already handled earlier.
-                        break;
-                    case 'h' :
-                    case 'help' :
-                        $this->showHelp();
-                        return 0;
-                        break;
-                    case 'format' :
-                        switch($value) {
-
-                            // jcard/jcal documents
-                            case 'jcard' :
-                            case 'jcal' :
-
-                            // specific document versions
-                            case 'vcard21' :
-                            case 'vcard30' :
-                            case 'vcard40' :
-                            case 'icalendar20' :
-
-                            // specific formats
-                            case 'json' :
-                            case 'mimedir' :
-
-                            // icalendar/vcad
-                            case 'icalendar' :
-                            case 'vcard' :
-                                $this->format = $value;
-                                break;
-
-                            default :
-                                throw new InvalidArgumentException('Unknown format: ' . $value);
-
-                        }
-                        break;
-                    case 'pretty' :
-                        if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
-                            $this->pretty = true;
-                        }
-                        break;
-                    case 'forgiving' :
-                        $this->forgiving = true;
-                        break;
-                    case 'inputformat' :
-                        switch($value) {
-                            // json formats
-                            case 'jcard' :
-                            case 'jcal' :
-                            case 'json' :
-                                $this->inputFormat = 'json';
-                                break;
-
-                            // mimedir formats
-                            case 'mimedir' :
-                            case 'icalendar' :
-                            case 'vcard' :
-                            case 'vcard21' :
-                            case 'vcard30' :
-                            case 'vcard40' :
-                            case 'icalendar20' :
-
-                                $this->inputFormat = 'mimedir';
-                                break;
-
-                            default :
-                                throw new InvalidArgumentException('Unknown format: ' . $value);
-
-                        }
-                        break;
-                    default :
-                        throw new InvalidArgumentException('Unknown option: ' . $name);
-
-                }
-
-            }
-
-            if (count($positional) === 0) {
-                $this->showHelp();
-                return 1;
-            }
-
-            if (count($positional) === 1) {
-                throw new InvalidArgumentException('Inputfile is a required argument');
-            }
-
-            if (count($positional) > 3) {
-                throw new InvalidArgumentException('Too many arguments');
-            }
-
-            if (!in_array($positional[0], array('validate','repair','convert','color'))) {
-                throw new InvalidArgumentException('Uknown command: ' . $positional[0]);
-            }
-
-        } catch (InvalidArgumentException $e) {
-            $this->showHelp();
-            $this->log('Error: ' . $e->getMessage(), 'red');
-            return 1;
-        }
-
-        $command = $positional[0];
-
-        $this->inputPath = $positional[1];
-        $this->outputPath = isset($positional[2])?$positional[2]:'-';
-
-        if ($this->outputPath !== '-') {
-            $this->stdout = fopen($this->outputPath, 'w');
-        }
-
-        if (!$this->inputFormat) {
-            if (substr($this->inputPath, -5)==='.json') {
-                $this->inputFormat = 'json';
-            } else {
-                $this->inputFormat = 'mimedir';
-            }
-        }
-        if (!$this->format) {
-            if (substr($this->outputPath,-5)==='.json') {
-                $this->format = 'json';
-            } else {
-                $this->format = 'mimedir';
-            }
-        }
-
-
-        $realCode = 0;
-
-        try {
-
-            while($input = $this->readInput()) {
-
-                $returnCode = $this->$command($input);
-                if ($returnCode!==0) $realCode = $returnCode;
-
-            }
-
-        } catch (EofException $e) {
-            // end of file
-        } catch (\Exception $e) {
-            $this->log('Error: ' . $e->getMessage(),'red');
-            return 2;
-        }
-
-        return $realCode;
-
-    }
-
-    /**
-     * Shows the help message.
-     *
-     * @return void
-     */
-    protected function showHelp() {
-
-        $this->log('Usage:', 'yellow');
-        $this->log("  vobject [options] command [arguments]");
-        $this->log('');
-        $this->log('Options:', 'yellow');
-        $this->log($this->colorize('green', '  -q            ') . "Don't output anything.");
-        $this->log($this->colorize('green', '  -help -h      ') . "Display this help message.");
-        $this->log($this->colorize('green', '  --format      ') . "Convert to a specific format. Must be one of: vcard, vcard21,");
-        $this->log($this->colorize('green', '  --forgiving   ') . "Makes the parser less strict.");
-        $this->log("                vcard30, vcard40, icalendar20, jcal, jcard, json, mimedir.");
-        $this->log($this->colorize('green', '  --inputformat ') . "If the input format cannot be guessed from the extension, it");
-        $this->log("                must be specified here.");
-        // Only PHP 5.4 and up
-        if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
-            $this->log($this->colorize('green', '  --pretty      ') . "json pretty-print.");
-        }
-        $this->log('');
-        $this->log('Commands:', 'yellow');
-        $this->log($this->colorize('green', '  validate') . ' source_file              Validates a file for correctness.');
-        $this->log($this->colorize('green', '  repair') . ' source_file [output_file]  Repairs a file.');
-        $this->log($this->colorize('green', '  convert') . ' source_file [output_file] Converts a file.');
-        $this->log($this->colorize('green', '  color') . ' source_file                 Colorize a file, useful for debbugging.');
-        $this->log(
-        <<<HELP
-
-If source_file is set as '-', STDIN will be used.
-If output_file is omitted, STDOUT will be used.
-All other output is sent to STDERR.
-
-HELP
-        );
-
-        $this->log('Examples:', 'yellow');
-        $this->log('   vobject convert contact.vcf contact.json');
-        $this->log('   vobject convert --format=vcard40 old.vcf new.vcf');
-        $this->log('   vobject convert --inputformat=json --format=mimedir - -');
-        $this->log('   vobject color calendar.ics');
-        $this->log('');
-        $this->log('https://github.com/fruux/sabre-vobject','purple');
-
-    }
-
-    /**
-     * Validates a VObject file
-     *
-     * @param Component $vObj
-     * @return int
-     */
-    protected function validate($vObj) {
-
-        $returnCode = 0;
-
-        switch($vObj->name) {
-            case 'VCALENDAR' :
-                $this->log("iCalendar: " . (string)$vObj->VERSION);
-                break;
-            case 'VCARD' :
-                $this->log("vCard: " . (string)$vObj->VERSION);
-                break;
-        }
-
-        $warnings = $vObj->validate();
-        if (!count($warnings)) {
-            $this->log("  No warnings!");
-        } else {
-
-            $levels = array(
-                1 => 'REPAIRED',
-                2 => 'WARNING',
-                3 => 'ERROR',
-            );
-            $returnCode = 2;
-            foreach($warnings as $warn) {
-
-                $extra = '';
-                if ($warn['node'] instanceof Property) {
-                    $extra = ' (property: "' . $warn['node']->name . '")';
-                }
-                $this->log("  [" . $levels[$warn['level']] . '] ' . $warn['message'] . $extra);
-
-            }
-
-        }
-
-        return $returnCode;
-
-    }
-
-    /**
-     * Repairs a VObject file
-     *
-     * @param Component $vObj
-     * @return int
-     */
-    protected function repair($vObj) {
-
-        $returnCode = 0;
-
-        switch($vObj->name) {
-            case 'VCALENDAR' :
-                $this->log("iCalendar: " . (string)$vObj->VERSION);
-                break;
-            case 'VCARD' :
-                $this->log("vCard: " . (string)$vObj->VERSION);
-                break;
-        }
-
-        $warnings = $vObj->validate(Node::REPAIR);
-        if (!count($warnings)) {
-            $this->log("  No warnings!");
-        } else {
-
-            $levels = array(
-                1 => 'REPAIRED',
-                2 => 'WARNING',
-                3 => 'ERROR',
-            );
-            $returnCode = 2;
-            foreach($warnings as $warn) {
-
-                $extra = '';
-                if ($warn['node'] instanceof Property) {
-                    $extra = ' (property: "' . $warn['node']->name . '")';
-                }
-                $this->log("  [" . $levels[$warn['level']] . '] ' . $warn['message'] . $extra);
-
-            }
-
-        }
-        fwrite($this->stdout, $vObj->serialize());
-
-        return $returnCode;
-
-    }
-
-    /**
-     * Converts a vObject file to a new format.
-     *
-     * @param Component $vObj
-     * @return int
-     */
-    protected function convert($vObj) {
-
-        $json = false;
-        $convertVersion = null;
-        $forceInput = null;
-
-        switch($this->format) {
-            case 'json' :
-                $json = true;
-                if ($vObj->name === 'VCARD') {
-                    $convertVersion = Document::VCARD40;
-                }
-                break;
-            case 'jcard' :
-                $json = true;
-                $forceInput = 'VCARD';
-                $convertVersion = Document::VCARD40;
-                break;
-            case 'jcal' :
-                $json = true;
-                $forceInput = 'VCALENDAR';
-                break;
-            case 'mimedir' :
-            case 'icalendar' :
-            case 'icalendar20' :
-            case 'vcard' :
-                break;
-            case 'vcard21' :
-                $convertVersion = Document::VCARD21;
-                break;
-            case 'vcard30' :
-                $convertVersion = Document::VCARD30;
-                break;
-            case 'vcard40' :
-                $convertVersion = Document::VCARD40;
-                break;
-
-        }
-
-        if ($forceInput && $vObj->name !== $forceInput) {
-            throw new \Exception('You cannot convert a ' . strtolower($vObj->name) . ' to ' . $this->format);
-        }
-        if ($convertVersion) {
-            $vObj = $vObj->convert($convertVersion);
-        }
-        if ($json) {
-            $jsonOptions = 0;
-            if ($this->pretty) {
-                $jsonOptions = JSON_PRETTY_PRINT;
-            }
-            fwrite($this->stdout, json_encode($vObj->jsonSerialize(), $jsonOptions));
-        } else {
-            fwrite($this->stdout, $vObj->serialize());
-        }
-
-        return 0;
-
-    }
-
-    /**
-     * Colorizes a file
-     *
-     * @param Component $vObj
-     * @return int
-     */
-    protected function color($vObj) {
-
-        fwrite($this->stdout, $this->serializeComponent($vObj));
-
-    }
-
-    /**
-     * Returns an ansi color string for a color name.
-     *
-     * @param string $color
-     * @return string
-     */
-    protected function colorize($color, $str, $resetTo = 'default') {
-
-        $colors = array(
-            'cyan'    => '1;36',
-            'red'     => '1;31',
-            'yellow'  => '1;33',
-            'blue'    => '0;34',
-            'green'   => '0;32',
-            'default' => '0',
-            'purple'  => '0;35',
-        );
-        return "\033[" . $colors[$color] . 'm' . $str . "\033[".$colors[$resetTo]."m";
-
-    }
-
-    /**
-     * Writes out a string in specific color.
-     *
-     * @param string $color
-     * @param string $str
-     * @return void
-     */
-    protected function cWrite($color, $str) {
-
-        fwrite($this->stdout, $this->colorize($color, $str));
-
-    }
-
-    protected function serializeComponent(Component $vObj) {
-
-        $this->cWrite('cyan', 'BEGIN');
-        $this->cWrite('red', ':');
-        $this->cWrite('yellow', $vObj->name . "\n");
-
-        /**
-         * Gives a component a 'score' for sorting purposes.
-         *
-         * This is solely used by the childrenSort method.
-         *
-         * A higher score means the item will be lower in the list.
-         * To avoid score collisions, each "score category" has a reasonable
-         * space to accomodate elements. The $key is added to the $score to
-         * preserve the original relative order of elements.
-         *
-         * @param int $key
-         * @param array $array
-         * @return int
-         */
-        $sortScore = function($key, $array) {
-
-            if ($array[$key] instanceof Component) {
-
-                // We want to encode VTIMEZONE first, this is a personal
-                // preference.
-                if ($array[$key]->name === 'VTIMEZONE') {
-                    $score=300000000;
-                    return $score+$key;
-                } else {
-                    $score=400000000;
-                    return $score+$key;
-                }
-            } else {
-                // Properties get encoded first
-                // VCARD version 4.0 wants the VERSION property to appear first
-                if ($array[$key] instanceof Property) {
-                    if ($array[$key]->name === 'VERSION') {
-                        $score=100000000;
-                        return $score+$key;
-                    } else {
-                        // All other properties
-                        $score=200000000;
-                        return $score+$key;
-                    }
-                }
-            }
-
-        };
-
-        $tmp = $vObj->children;
-        uksort(
-            $vObj->children,
-            function($a, $b) use ($sortScore, $tmp) {
-
-                $sA = $sortScore($a, $tmp);
-                $sB = $sortScore($b, $tmp);
-
-                return $sA - $sB;
-
-            }
-        );
-
-        foreach($vObj->children as $child) {
-            if ($child instanceof Component) {
-                $this->serializeComponent($child);
-            } else {
-                $this->serializeProperty($child);
-            }
-        }
-
-        $this->cWrite('cyan', 'END');
-        $this->cWrite('red', ':');
-        $this->cWrite('yellow', $vObj->name . "\n");
-
-    }
-
-    /**
-     * Colorizes a property.
-     *
-     * @param Property $property
-     * @return void
-     */
-    protected function serializeProperty(Property $property) {
-
-        if ($property->group) {
-            $this->cWrite('default', $property->group);
-            $this->cWrite('red', '.');
-        }
-
-        $str = '';
-        $this->cWrite('yellow', $property->name);
-
-        foreach($property->parameters as $param) {
-
-            $this->cWrite('red',';');
-            $this->cWrite('blue', $param->serialize());
-
-        }
-        $this->cWrite('red',':');
-
-        if ($property instanceof Property\Binary) {
-
-            $this->cWrite('default', 'embedded binary stripped. (' . strlen($property->getValue()) . ' bytes)');
-
-        } else {
-
-            $parts = $property->getParts();
-            $first1 = true;
-            // Looping through property values
-            foreach($parts as $part) {
-                if ($first1) {
-                    $first1 = false;
-                } else {
-                    $this->cWrite('red', $property->delimiter);
-                }
-                $first2 = true;
-                // Looping through property sub-values
-                foreach((array)$part as $subPart) {
-                    if ($first2) {
-                        $first2 = false;
-                    } else {
-                        // The sub-value delimiter is always comma
-                        $this->cWrite('red', ',');
-                    }
-
-                    $subPart = strtr(
-                        $subPart,
-                        array(
-                            '\\' => $this->colorize('purple', '\\\\', 'green'),
-                            ';'  => $this->colorize('purple', '\;', 'green'),
-                            ','  => $this->colorize('purple', '\,', 'green'),
-                            "\n" => $this->colorize('purple', "\\n\n\t", 'green'),
-                            "\r" => "",
-                        )
-                    );
-
-                    $this->cWrite('green', $subPart);
-                }
-            }
-
-        }
-        $this->cWrite("default", "\n");
-
-    }
-
-    /**
-     * Parses the list of arguments.
-     *
-     * @param array $argv
-     * @return void
-     */
-    protected function parseArguments(array $argv) {
-
-        $positional = array();
-        $options = array();
-
-        for($ii=0; $ii < count($argv); $ii++) {
-
-            // Skipping the first argument.
-            if ($ii===0) continue;
-
-            $v = $argv[$ii];
-
-            if (substr($v,0,2)==='--') {
-                // This is a long-form option.
-                $optionName = substr($v,2);
-                $optionValue = true;
-                if (strpos($optionName,'=')) {
-                    list($optionName, $optionValue) = explode('=', $optionName);
-                }
-                $options[$optionName] = $optionValue;
-            } elseif (substr($v,0,1) === '-' && strlen($v)>1) {
-                // This is a short-form option.
-                foreach(str_split(substr($v,1)) as $option) {
-                    $options[$option] = true;
-                }
-
-            } else {
-
-                $positional[] = $v;
-
-            }
-
-        }
-
-        return array($options, $positional);
-
-    }
-
-    protected $parser;
-
-    /**
-     * Reads the input file
-     *
-     * @return Component
-     */
-    protected function readInput() {
-
-        if (!$this->parser) {
-            if ($this->inputPath!=='-') {
-                $this->stdin = fopen($this->inputPath,'r');
-            }
-
-            if ($this->inputFormat === 'mimedir') {
-                $this->parser = new Parser\MimeDir($this->stdin, ($this->forgiving?Reader::OPTION_FORGIVING:0));
-            } else {
-                $this->parser = new Parser\Json($this->stdin, ($this->forgiving?Reader::OPTION_FORGIVING:0));
-            }
-        }
-
-        return $this->parser->parse();
-
-    }
-
-    /**
-     * Sends a message to STDERR.
-     *
-     * @param string $msg
-     * @return void
-     */
-    protected function log($msg, $color = 'default') {
-
-        if (!$this->quiet) {
-            if ($color!=='default') {
-                $msg = $this->colorize($color, $msg);
-            }
-            fwrite($this->stderr, $msg . "\n");
-        }
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Component.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,595 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Component
- *
- * A component represents a group of properties, such as VCALENDAR, VEVENT, or
- * VCARD.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Component extends Node {
-
-    /**
-     * Component name.
-     *
-     * This will contain a string such as VEVENT, VTODO, VCALENDAR, VCARD.
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * A list of properties and/or sub-components.
-     *
-     * @var array
-     */
-    public $children = array();
-
-    /**
-     * Creates a new component.
-     *
-     * You can specify the children either in key=>value syntax, in which case
-     * properties will automatically be created, or you can just pass a list of
-     * Component and Property object.
-     *
-     * By default, a set of sensible values will be added to the component. For
-     * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To
-     * ensure that this does not happen, set $defaults to false.
-     *
-     * @param Document $root
-     * @param string $name such as VCALENDAR, VEVENT.
-     * @param array $children
-     * @param bool $defaults
-     * @return void
-     */
-    function __construct(Document $root, $name, array $children = array(), $defaults = true) {
-
-        $this->name = strtoupper($name);
-        $this->root = $root;
-
-        if ($defaults) {
-            // This is a terribly convoluted way to do this, but this ensures
-            // that the order of properties as they are specified in both
-            // defaults and the childrens list, are inserted in the object in a
-            // natural way.
-            $list = $this->getDefaults();
-            $nodes = array();
-            foreach($children as $key=>$value) {
-                if ($value instanceof Node) {
-                    if (isset($list[$value->name])) {
-                        unset($list[$value->name]);
-                    }
-                    $nodes[] = $value;
-                } else {
-                    $list[$key] = $value;
-                }
-            }
-            foreach($list as $key=>$value) {
-                $this->add($key, $value);
-            }
-            foreach($nodes as $node) {
-                $this->add($node);
-            }
-        } else {
-            foreach($children as $k=>$child) {
-                if ($child instanceof Node) {
-
-                    // Component or Property
-                    $this->add($child);
-                } else {
-
-                    // Property key=>value
-                    $this->add($k, $child);
-                }
-            }
-        }
-
-    }
-
-    /**
-     * Adds a new property or component, and returns the new item.
-     *
-     * This method has 3 possible signatures:
-     *
-     * add(Component $comp) // Adds a new component
-     * add(Property $prop)  // Adds a new property
-     * add($name, $value, array $parameters = array()) // Adds a new property
-     * add($name, array $children = array()) // Adds a new component
-     * by name.
-     *
-     * @return Node
-     */
-    function add($a1, $a2 = null, $a3 = null) {
-
-        if ($a1 instanceof Node) {
-            if (!is_null($a2)) {
-                throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject Node');
-            }
-            $a1->parent = $this;
-            $this->children[] = $a1;
-
-            return $a1;
-
-        } elseif(is_string($a1)) {
-
-            $item = $this->root->create($a1, $a2, $a3);
-            $item->parent = $this;
-            $this->children[] = $item;
-
-            return $item;
-
-        } else {
-
-            throw new \InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string');
-
-        }
-
-    }
-
-    /**
-     * This method removes a component or property from this component.
-     *
-     * You can either specify the item by name (like DTSTART), in which case
-     * all properties/components with that name will be removed, or you can
-     * pass an instance of a property or component, in which case only that
-     * exact item will be removed.
-     *
-     * The removed item will be returned. In case there were more than 1 items
-     * removed, only the last one will be returned.
-     *
-     * @param mixed $item
-     * @return void
-     */
-    function remove($item) {
-
-        if (is_string($item)) {
-            $children = $this->select($item);
-            foreach($children as $k=>$child) {
-                unset($this->children[$k]);
-            }
-            return $child;
-        } else {
-            foreach($this->children as $k => $child) {
-                if ($child===$item) {
-                    unset($this->children[$k]);
-                    return $child;
-                }
-            }
-
-            throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component');
-
-        }
-
-    }
-
-    /**
-     * Returns an iterable list of children
-     *
-     * @return array
-     */
-    function children() {
-
-        return $this->children;
-
-    }
-
-    /**
-     * This method only returns a list of sub-components. Properties are
-     * ignored.
-     *
-     * @return array
-     */
-    function getComponents() {
-
-        $result = array();
-        foreach($this->children as $child) {
-            if ($child instanceof Component) {
-                $result[] = $child;
-            }
-        }
-
-        return $result;
-
-    }
-
-    /**
-     * Returns an array with elements that match the specified name.
-     *
-     * This function is also aware of MIME-Directory groups (as they appear in
-     * vcards). This means that if a property is grouped as "HOME.EMAIL", it
-     * will also be returned when searching for just "EMAIL". If you want to
-     * search for a property in a specific group, you can select on the entire
-     * string ("HOME.EMAIL"). If you want to search on a specific property that
-     * has not been assigned a group, specify ".EMAIL".
-     *
-     * Keys are retained from the 'children' array, which may be confusing in
-     * certain cases.
-     *
-     * @param string $name
-     * @return array
-     */
-    function select($name) {
-
-        $group = null;
-        $name = strtoupper($name);
-        if (strpos($name,'.')!==false) {
-            list($group,$name) = explode('.', $name, 2);
-        }
-
-        $result = array();
-        foreach($this->children as $key=>$child) {
-
-            if (
-                (
-                    strtoupper($child->name) === $name
-                    && (is_null($group) || ( $child instanceof Property && strtoupper($child->group) === $group))
-                )
-                ||
-                (
-                    $name === '' && $child instanceof Property && strtoupper($child->group) === $group
-                )
-            ) {
-
-                $result[$key] = $child;
-
-            }
-        }
-
-        reset($result);
-        return $result;
-
-    }
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    function serialize() {
-
-        $str = "BEGIN:" . $this->name . "\r\n";
-
-        /**
-         * Gives a component a 'score' for sorting purposes.
-         *
-         * This is solely used by the childrenSort method.
-         *
-         * A higher score means the item will be lower in the list.
-         * To avoid score collisions, each "score category" has a reasonable
-         * space to accomodate elements. The $key is added to the $score to
-         * preserve the original relative order of elements.
-         *
-         * @param int $key
-         * @param array $array
-         * @return int
-         */
-        $sortScore = function($key, $array) {
-
-            if ($array[$key] instanceof Component) {
-
-                // We want to encode VTIMEZONE first, this is a personal
-                // preference.
-                if ($array[$key]->name === 'VTIMEZONE') {
-                    $score=300000000;
-                    return $score+$key;
-                } else {
-                    $score=400000000;
-                    return $score+$key;
-                }
-            } else {
-                // Properties get encoded first
-                // VCARD version 4.0 wants the VERSION property to appear first
-                if ($array[$key] instanceof Property) {
-                    if ($array[$key]->name === 'VERSION') {
-                        $score=100000000;
-                        return $score+$key;
-                    } else {
-                        // All other properties
-                        $score=200000000;
-                        return $score+$key;
-                    }
-                }
-            }
-
-        };
-
-        $tmp = $this->children;
-        uksort(
-            $this->children,
-            function($a, $b) use ($sortScore, $tmp) {
-
-                $sA = $sortScore($a, $tmp);
-                $sB = $sortScore($b, $tmp);
-
-                return $sA - $sB;
-
-            }
-        );
-
-        foreach($this->children as $child) $str.=$child->serialize();
-        $str.= "END:" . $this->name . "\r\n";
-
-        return $str;
-
-    }
-
-    /**
-     * This method returns an array, with the representation as it should be
-     * encoded in json. This is used to create jCard or jCal documents.
-     *
-     * @return array
-     */
-    function jsonSerialize() {
-
-        $components = array();
-        $properties = array();
-
-        foreach($this->children as $child) {
-            if ($child instanceof Component) {
-                $components[] = $child->jsonSerialize();
-            } else {
-                $properties[] = $child->jsonSerialize();
-            }
-        }
-
-        return array(
-            strtolower($this->name),
-            $properties,
-            $components
-        );
-
-    }
-
-    /**
-     * This method should return a list of default property values.
-     *
-     * @return array
-     */
-    protected function getDefaults() {
-
-        return array();
-
-    }
-
-    /* Magic property accessors {{{ */
-
-    /**
-     * Using 'get' you will either get a property or component.
-     *
-     * If there were no child-elements found with the specified name,
-     * null is returned.
-     *
-     * To use this, this may look something like this:
-     *
-     * $event = $calendar->VEVENT;
-     *
-     * @param string $name
-     * @return Property
-     */
-    function __get($name) {
-
-        $matches = $this->select($name);
-        if (count($matches)===0) {
-            return null;
-        } else {
-            $firstMatch = current($matches);
-            /** @var $firstMatch Property */
-            $firstMatch->setIterator(new ElementList(array_values($matches)));
-            return $firstMatch;
-        }
-
-    }
-
-    /**
-     * This method checks if a sub-element with the specified name exists.
-     *
-     * @param string $name
-     * @return bool
-     */
-    function __isset($name) {
-
-        $matches = $this->select($name);
-        return count($matches)>0;
-
-    }
-
-    /**
-     * Using the setter method you can add properties or subcomponents
-     *
-     * You can either pass a Component, Property
-     * object, or a string to automatically create a Property.
-     *
-     * If the item already exists, it will be removed. If you want to add
-     * a new item with the same name, always use the add() method.
-     *
-     * @param string $name
-     * @param mixed $value
-     * @return void
-     */
-    function __set($name, $value) {
-
-        $matches = $this->select($name);
-        $overWrite = count($matches)?key($matches):null;
-
-        if ($value instanceof Component || $value instanceof Property) {
-            $value->parent = $this;
-            if (!is_null($overWrite)) {
-                $this->children[$overWrite] = $value;
-            } else {
-                $this->children[] = $value;
-            }
-        } else {
-            $property = $this->root->create($name,$value);
-            $property->parent = $this;
-            if (!is_null($overWrite)) {
-                $this->children[$overWrite] = $property;
-            } else {
-                $this->children[] = $property;
-            }
-        }
-    }
-
-    /**
-     * Removes all properties and components within this component with the
-     * specified name.
-     *
-     * @param string $name
-     * @return void
-     */
-    function __unset($name) {
-
-        $matches = $this->select($name);
-        foreach($matches as $k=>$child) {
-
-            unset($this->children[$k]);
-            $child->parent = null;
-
-        }
-
-    }
-
-    /* }}} */
-
-    /**
-     * This method is automatically called when the object is cloned.
-     * Specifically, this will ensure all child elements are also cloned.
-     *
-     * @return void
-     */
-    function __clone() {
-
-        foreach($this->children as $key=>$child) {
-            $this->children[$key] = clone $child;
-            $this->children[$key]->parent = $this;
-        }
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *   * ? - May appear, but not more than once.
-     *
-     * It is also possible to specify defaults and severity levels for
-     * violating the rule.
-     *
-     * See the VEVENT implementation for getValidationRules for a more complex
-     * example.
-     *
-     * @var array
-     */
-    function getValidationRules() {
-
-        return array();
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
-     *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on).
-     *   2 - A warning.
-     *   3 - An error.
-     *
-     * @param int $options
-     * @return array
-     */
-    function validate($options = 0) {
-
-        $rules = $this->getValidationRules();
-        $defaults = $this->getDefaults();
-
-        $propertyCounters = array();
-
-        $messages = array();
-
-        foreach($this->children as $child) {
-            $name = strtoupper($child->name);
-            if (!isset($propertyCounters[$name])) {
-                $propertyCounters[$name] = 1;
-            } else {
-                $propertyCounters[$name]++;
-            }
-            $messages = array_merge($messages, $child->validate($options));
-        }
-
-        foreach($rules as $propName => $rule) {
-
-            switch($rule) {
-                case '0' :
-                    if (isset($propertyCounters[$propName])) {
-                        $messages[] = array(
-                            'level' => 3,
-                            'message' => $propName . ' MUST NOT appear in a ' . $this->name . ' component',
-                            'node' => $this,
-                        );
-                    }
-                    break;
-                case '1' :
-                    if (!isset($propertyCounters[$propName]) || $propertyCounters[$propName]!==1) {
-                        $repaired = false;
-                        if ($options & self::REPAIR && isset($defaults[$propName])) {
-                            $this->add($propName, $defaults[$propName]);
-                        }
-                        $messages[] = array(
-                            'level' => $repaired?1:3,
-                            'message' => $propName . ' MUST appear exactly once in a ' . $this->name . ' component',
-                            'node' => $this,
-                        );
-                    }
-                    break;
-                case '+' :
-                    if (!isset($propertyCounters[$propName]) || $propertyCounters[$propName] < 1) {
-                        $messages[] = array(
-                            'level' => 3,
-                            'message' => $propName . ' MUST appear at least once in a ' . $this->name . ' component',
-                            'node' => $this,
-                        );
-                    }
-                    break;
-                case '*' :
-                    break;
-                case '?' :
-                    if (isset($propertyCounters[$propName]) && $propertyCounters[$propName] > 1) {
-                        $messages[] = array(
-                            'level' => 3,
-                            'message' => $propName . ' MUST NOT appear more than once in a ' . $this->name . ' component',
-                            'node' => $this,
-                        );
-                    }
-                    break;
-
-            }
-
-        }
-        return $messages;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Component/VAlarm.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-use Sabre\VObject;
-
-/**
- * VAlarm component
- *
- * This component contains some additional functionality specific for VALARMs.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VAlarm extends VObject\Component {
-
-    /**
-     * Returns a DateTime object when this alarm is going to trigger.
-     *
-     * This ignores repeated alarm, only the first trigger is returned.
-     *
-     * @return DateTime
-     */
-    public function getEffectiveTriggerTime() {
-
-        $trigger = $this->TRIGGER;
-        if(!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
-            $triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER);
-            $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
-
-            $parentComponent = $this->parent;
-            if ($related === 'START') {
-
-                if ($parentComponent->name === 'VTODO') {
-                    $propName = 'DUE';
-                } else {
-                    $propName = 'DTSTART';
-                }
-
-                $effectiveTrigger = clone $parentComponent->$propName->getDateTime();
-                $effectiveTrigger->add($triggerDuration);
-            } else {
-                if ($parentComponent->name === 'VTODO') {
-                    $endProp = 'DUE';
-                } elseif ($parentComponent->name === 'VEVENT') {
-                    $endProp = 'DTEND';
-                } else {
-                    throw new \LogicException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
-                }
-
-                if (isset($parentComponent->$endProp)) {
-                    $effectiveTrigger = clone $parentComponent->$endProp->getDateTime();
-                    $effectiveTrigger->add($triggerDuration);
-                } elseif (isset($parentComponent->DURATION)) {
-                    $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
-                    $duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION);
-                    $effectiveTrigger->add($duration);
-                    $effectiveTrigger->add($triggerDuration);
-                } else {
-                    $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
-                    $effectiveTrigger->add($triggerDuration);
-                }
-            }
-        } else {
-            $effectiveTrigger = $trigger->getDateTime();
-        }
-        return $effectiveTrigger;
-
-    }
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param \DateTime $start
-     * @param \DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        $effectiveTrigger = $this->getEffectiveTriggerTime();
-
-        if (isset($this->DURATION)) {
-            $duration = VObject\DateTimeParser::parseDuration($this->DURATION);
-            $repeat = (string)$this->repeat;
-            if (!$repeat) {
-                $repeat = 1;
-            }
-
-            $period = new \DatePeriod($effectiveTrigger, $duration, (int)$repeat);
-
-            foreach($period as $occurrence) {
-
-                if ($start <= $occurrence && $end > $occurrence) {
-                    return true;
-                }
-            }
-            return false;
-        } else {
-            return ($start <= $effectiveTrigger && $end > $effectiveTrigger);
-        }
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    public function getValidationRules() {
-
-        return array(
-            'ACTION' => 1,
-            'TRIGGER' => 1,
-
-            'DURATION' => '?',
-            'REPEAT' => '?',
-
-            'ATTACH' => '?',
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Component/VCalendar.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,490 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use DateTime;
-use DateTimeZone;
-use Sabre\VObject;
-use Sabre\VObject\Component;
-use Sabre\VObject\Recur\EventIterator;
-use Sabre\VObject\Recur\NoInstancesException;
-
-/**
- * The VCalendar component
- *
- * This component adds functionality to a component, specific for a VCALENDAR.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VCalendar extends VObject\Document {
-
-    /**
-     * The default name for this component.
-     *
-     * This should be 'VCALENDAR' or 'VCARD'.
-     *
-     * @var string
-     */
-    static $defaultName = 'VCALENDAR';
-
-    /**
-     * This is a list of components, and which classes they should map to.
-     *
-     * @var array
-     */
-    static $componentMap = array(
-        'VALARM'    => 'Sabre\\VObject\\Component\\VAlarm',
-        'VEVENT'    => 'Sabre\\VObject\\Component\\VEvent',
-        'VFREEBUSY' => 'Sabre\\VObject\\Component\\VFreeBusy',
-        'VJOURNAL'  => 'Sabre\\VObject\\Component\\VJournal',
-        'VTIMEZONE' => 'Sabre\\VObject\\Component\\VTimeZone',
-        'VTODO'     => 'Sabre\\VObject\\Component\\VTodo',
-    );
-
-    /**
-     * List of value-types, and which classes they map to.
-     *
-     * @var array
-     */
-    static $valueMap = array(
-        'BINARY'           => 'Sabre\\VObject\\Property\\Binary',
-        'BOOLEAN'          => 'Sabre\\VObject\\Property\\Boolean',
-        'CAL-ADDRESS'      => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
-        'DATE'             => 'Sabre\\VObject\\Property\\ICalendar\\Date',
-        'DATE-TIME'        => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'DURATION'         => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
-        'FLOAT'            => 'Sabre\\VObject\\Property\\Float',
-        'INTEGER'          => 'Sabre\\VObject\\Property\\Integer',
-        'PERIOD'           => 'Sabre\\VObject\\Property\\ICalendar\\Period',
-        'RECUR'            => 'Sabre\\VObject\\Property\\ICalendar\\Recur',
-        'TEXT'             => 'Sabre\\VObject\\Property\\Text',
-        'TIME'             => 'Sabre\\VObject\\Property\\Time',
-        'UNKNOWN'          => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only.
-        'URI'              => 'Sabre\\VObject\\Property\\Uri',
-        'UTC-OFFSET'       => 'Sabre\\VObject\\Property\\UtcOffset',
-    );
-
-    /**
-     * List of properties, and which classes they map to.
-     *
-     * @var array
-     */
-    static $propertyMap = array(
-        // Calendar properties
-        'CALSCALE'      => 'Sabre\\VObject\\Property\\FlatText',
-        'METHOD'        => 'Sabre\\VObject\\Property\\FlatText',
-        'PRODID'        => 'Sabre\\VObject\\Property\\FlatText',
-        'VERSION'       => 'Sabre\\VObject\\Property\\FlatText',
-
-        // Component properties
-        'ATTACH'            => 'Sabre\\VObject\\Property\\Uri',
-        'CATEGORIES'        => 'Sabre\\VObject\\Property\\Text',
-        'CLASS'             => 'Sabre\\VObject\\Property\\FlatText',
-        'COMMENT'           => 'Sabre\\VObject\\Property\\FlatText',
-        'DESCRIPTION'       => 'Sabre\\VObject\\Property\\FlatText',
-        'GEO'               => 'Sabre\\VObject\\Property\\Float',
-        'LOCATION'          => 'Sabre\\VObject\\Property\\FlatText',
-        'PERCENT-COMPLETE'  => 'Sabre\\VObject\\Property\\Integer',
-        'PRIORITY'          => 'Sabre\\VObject\\Property\\Integer',
-        'RESOURCES'         => 'Sabre\\VObject\\Property\\Text',
-        'STATUS'            => 'Sabre\\VObject\\Property\\FlatText',
-        'SUMMARY'           => 'Sabre\\VObject\\Property\\FlatText',
-
-        // Date and Time Component Properties
-        'COMPLETED'     => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'DTEND'         => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'DUE'           => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'DTSTART'       => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'DURATION'      => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
-        'FREEBUSY'      => 'Sabre\\VObject\\Property\\ICalendar\\Period',
-        'TRANSP'        => 'Sabre\\VObject\\Property\\FlatText',
-
-        // Time Zone Component Properties
-        'TZID'          => 'Sabre\\VObject\\Property\\FlatText',
-        'TZNAME'        => 'Sabre\\VObject\\Property\\FlatText',
-        'TZOFFSETFROM'  => 'Sabre\\VObject\\Property\\UtcOffset',
-        'TZOFFSETTO'    => 'Sabre\\VObject\\Property\\UtcOffset',
-        'TZURL'         => 'Sabre\\VObject\\Property\\Uri',
-
-        // Relationship Component Properties
-        'ATTENDEE'      => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
-        'CONTACT'       => 'Sabre\\VObject\\Property\\FlatText',
-        'ORGANIZER'     => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
-        'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'RELATED-TO'    => 'Sabre\\VObject\\Property\\FlatText',
-        'URL'           => 'Sabre\\VObject\\Property\\Uri',
-        'UID'           => 'Sabre\\VObject\\Property\\FlatText',
-
-        // Recurrence Component Properties
-        'EXDATE'        => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'RDATE'         => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'RRULE'         => 'Sabre\\VObject\\Property\\ICalendar\\Recur',
-        'EXRULE'        => 'Sabre\\VObject\\Property\\ICalendar\\Recur', // Deprecated since rfc5545
-
-        // Alarm Component Properties
-        'ACTION'        => 'Sabre\\VObject\\Property\\FlatText',
-        'REPEAT'        => 'Sabre\\VObject\\Property\\Integer',
-        'TRIGGER'       => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
-
-        // Change Management Component Properties
-        'CREATED'       => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'DTSTAMP'       => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'SEQUENCE'      => 'Sabre\\VObject\\Property\\Integer',
-
-        // Request Status
-        'REQUEST-STATUS' => 'Sabre\\VObject\\Property\\Text',
-
-        // Additions from draft-daboo-valarm-extensions-04
-        'ALARM-AGENT'    => 'Sabre\\VObject\\Property\\Text',
-        'ACKNOWLEDGED'   => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
-        'PROXIMITY'      => 'Sabre\\VObject\\Property\\Text',
-        'DEFAULT-ALARM'  => 'Sabre\\VObject\\Property\\Boolean',
-
-    );
-
-    /**
-     * Returns the current document type.
-     *
-     * @return void
-     */
-    function getDocumentType() {
-
-        return self::ICALENDAR20;
-
-    }
-
-    /**
-     * Returns a list of all 'base components'. For instance, if an Event has
-     * a recurrence rule, and one instance is overridden, the overridden event
-     * will have the same UID, but will be excluded from this list.
-     *
-     * VTIMEZONE components will always be excluded.
-     *
-     * @param string $componentName filter by component name
-     * @return VObject\Component[]
-     */
-    function getBaseComponents($componentName = null) {
-
-        $components = array();
-        foreach($this->children as $component) {
-
-            if (!$component instanceof VObject\Component)
-                continue;
-
-            if (isset($component->{'RECURRENCE-ID'}))
-                continue;
-
-            if ($componentName && $component->name !== strtoupper($componentName))
-                continue;
-
-            if ($component->name === 'VTIMEZONE')
-                continue;
-
-            $components[] = $component;
-
-        }
-
-        return $components;
-
-    }
-
-    /**
-     * Returns the first component that is not a VTIMEZONE, and does not have
-     * an RECURRENCE-ID.
-     *
-     * If there is no such component, null will be returned.
-     *
-     * @param string $componentName filter by component name
-     * @return VObject\Component|null
-     */
-    function getBaseComponent($componentName = null) {
-
-        foreach($this->children as $component) {
-
-            if (!$component instanceof VObject\Component)
-                continue;
-
-            if (isset($component->{'RECURRENCE-ID'}))
-                continue;
-
-            if ($componentName && $component->name !== strtoupper($componentName))
-                continue;
-
-            if ($component->name === 'VTIMEZONE')
-                continue;
-
-            return $component;
-
-        }
-
-    }
-
-    /**
-     * If this calendar object, has events with recurrence rules, this method
-     * can be used to expand the event into multiple sub-events.
-     *
-     * Each event will be stripped from it's recurrence information, and only
-     * the instances of the event in the specified timerange will be left
-     * alone.
-     *
-     * In addition, this method will cause timezone information to be stripped,
-     * and normalized to UTC.
-     *
-     * This method will alter the VCalendar. This cannot be reversed.
-     *
-     * This functionality is specifically used by the CalDAV standard. It is
-     * possible for clients to request expand events, if they are rather simple
-     * clients and do not have the possibility to calculate recurrences.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @param DateTimeZone $timeZone reference timezone for floating dates and
-     *                     times.
-     * @return void
-     */
-    function expand(DateTime $start, DateTime $end, DateTimeZone $timeZone = null) {
-
-        $newEvents = array();
-
-        if (!$timeZone) {
-            $timeZone = new DateTimeZone('UTC');
-        }
-
-        foreach($this->select('VEVENT') as $key=>$vevent) {
-
-            if (isset($vevent->{'RECURRENCE-ID'})) {
-                unset($this->children[$key]);
-                continue;
-            }
-
-
-            if (!$vevent->rrule) {
-                unset($this->children[$key]);
-                if ($vevent->isInTimeRange($start, $end)) {
-                    $newEvents[] = $vevent;
-                }
-                continue;
-            }
-
-
-
-            $uid = (string)$vevent->uid;
-            if (!$uid) {
-                throw new \LogicException('Event did not have a UID!');
-            }
-
-            try {
-                $it = new EventIterator($this, $vevent->uid, $timeZone);
-            } catch (NoInstancesException $e) {
-                // This event is recurring, but it doesn't have a single
-                // instance. We are skipping this event from the output
-                // entirely.
-                unset($this->children[$key]);
-                continue;
-            }
-            $it->fastForward($start);
-
-            while($it->valid() && $it->getDTStart() < $end) {
-
-                if ($it->getDTEnd() > $start) {
-
-                    $newEvents[] = $it->getEventObject();
-
-                }
-                $it->next();
-
-            }
-
-            unset($this->children[$key]);
-
-        }
-
-        // Setting all properties to UTC time.
-        foreach($newEvents as $newEvent) {
-
-            foreach($newEvent->children as $child) {
-                if ($child instanceof VObject\Property\ICalendar\DateTime && $child->hasTime()) {
-                    $dt = $child->getDateTimes($timeZone);
-                    // We only need to update the first timezone, because
-                    // setDateTimes will match all other timezones to the
-                    // first.
-                    $dt[0]->setTimeZone(new DateTimeZone('UTC'));
-                    $child->setDateTimes($dt);
-                }
-
-            }
-
-            $this->add($newEvent);
-
-        }
-
-        // Removing all VTIMEZONE components
-        unset($this->VTIMEZONE);
-
-    }
-
-    /**
-     * This method should return a list of default property values.
-     *
-     * @return array
-     */
-    protected function getDefaults() {
-
-        return array(
-            'VERSION' => '2.0',
-            'PRODID' => '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN',
-            'CALSCALE' => 'GREGORIAN',
-        );
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    function getValidationRules() {
-
-        return array(
-            'PRODID' => 1,
-            'VERSION' => 1,
-
-            'CALSCALE' => '?',
-            'METHOD' => '?',
-        );
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
-     *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on).
-     *   2 - A warning.
-     *   3 - An error.
-     *
-     * @param int $options
-     * @return array
-     */
-    function validate($options = 0) {
-
-        $warnings = parent::validate($options);
-
-        if ($ver = $this->VERSION) {
-            if ((string)$ver !== '2.0') {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
-                    'node' => $this,
-                );
-            }
-
-        }
-
-        $uidList = array();
-
-        $componentsFound = 0;
-
-        $componentTypes = array();
-
-        foreach($this->children as $child) {
-            if($child instanceof Component) {
-                $componentsFound++;
-
-                if (!in_array($child->name, array('VEVENT', 'VTODO', 'VJOURNAL'))) {
-                    continue;
-                }
-                $componentTypes[] = $child->name;
-
-                $uid = (string)$child->UID;
-                $isMaster = isset($child->{'RECURRENCE-ID'})?0:1;
-                if (isset($uidList[$uid])) {
-                    $uidList[$uid]['count']++;
-                    if ($isMaster && $uidList[$uid]['hasMaster']) {
-                        $warnings[] = array(
-                            'level' => 3,
-                            'message' => 'More than one master object was found for the object with UID ' . $uid,
-                            'node' => $this,
-                        );
-                    }
-                    $uidList[$uid]['hasMaster']+=$isMaster;
-                } else {
-                    $uidList[$uid] = array(
-                        'count' => 1,
-                        'hasMaster' => $isMaster,
-                    );
-                }
-
-            }
-        }
-
-        if ($componentsFound===0) {
-            $warnings[] = array(
-                'level' => 3,
-                'message' => 'An iCalendar object must have at least 1 component.',
-                'node' => $this,
-            );
-        }
-
-        if ($options & self::PROFILE_CALDAV) {
-            if (count($uidList)>1) {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'A calendar object on a CalDAV server may only have components with the same UID.',
-                    'node' => $this,
-                );
-            }
-            if (count(array_unique($componentTypes))===0) {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL).',
-                    'node' => $this,
-                );
-            }
-            if (count(array_unique($componentTypes))>1) {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL).',
-                    'node' => $this,
-                );
-            }
-
-            if (isset($this->METHOD)) {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'A calendar object on a CalDAV server MUST NOT have a METHOD property.',
-                    'node' => $this,
-                );
-            }
-        }
-
-        return $warnings;
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/lib/Component/VCard.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use
-    Sabre\VObject;
-
-/**
- * The VCard component
- *
- * This component represents the BEGIN:VCARD and END:VCARD found in every
- * vcard.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VCard extends VObject\Document {
-
-    /**
-     * The default name for this component.
-     *
-     * This should be 'VCALENDAR' or 'VCARD'.
-     *
-     * @var string
-     */
-    static $defaultName = 'VCARD';
-
-    /**
-     * Caching the version number
-     *
-     * @var int
-     */
-    private $version = null;
-
-    /**
-     * List of value-types, and which classes they map to.
-     *
-     * @var array
-     */
-    static $valueMap = array(
-        'BINARY'           => 'Sabre\\VObject\\Property\\Binary',
-        'BOOLEAN'          => 'Sabre\\VObject\\Property\\Boolean',
-        'CONTENT-ID'       => 'Sabre\\VObject\\Property\\FlatText',   // vCard 2.1 only
-        'DATE'             => 'Sabre\\VObject\\Property\\VCard\\Date',
-        'DATE-TIME'        => 'Sabre\\VObject\\Property\\VCard\\DateTime',
-        'DATE-AND-OR-TIME' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime', // vCard only
-        'FLOAT'            => 'Sabre\\VObject\\Property\\Float',
-        'INTEGER'          => 'Sabre\\VObject\\Property\\Integer',
-        'LANGUAGE-TAG'     => 'Sabre\\VObject\\Property\\VCard\\LanguageTag',
-        'TIMESTAMP'        => 'Sabre\\VObject\\Property\\VCard\\TimeStamp',
-        'TEXT'             => 'Sabre\\VObject\\Property\\Text',
-        'TIME'             => 'Sabre\\VObject\\Property\\Time',
-        'UNKNOWN'          => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only.
-        'URI'              => 'Sabre\\VObject\\Property\\Uri',
-        'URL'              => 'Sabre\\VObject\\Property\\Uri', // vCard 2.1 only
-        'UTC-OFFSET'       => 'Sabre\\VObject\\Property\\UtcOffset',
-    );
-
-    /**
-     * List of properties, and which classes they map to.
-     *
-     * @var array
-     */
-    static $propertyMap = array(
-
-        // vCard 2.1 properties and up
-        'N'       => 'Sabre\\VObject\\Property\\Text',
-        'FN'      => 'Sabre\\VObject\\Property\\FlatText',
-        'PHOTO'   => 'Sabre\\VObject\\Property\\Binary', // Todo: we should add a class for Binary values.
-        'BDAY'    => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
-        'ADR'     => 'Sabre\\VObject\\Property\\Text',
-        'LABEL'   => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
-        'TEL'     => 'Sabre\\VObject\\Property\\FlatText',
-        'EMAIL'   => 'Sabre\\VObject\\Property\\FlatText',
-        'MAILER'  => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
-        'GEO'     => 'Sabre\\VObject\\Property\\FlatText',
-        'TITLE'   => 'Sabre\\VObject\\Property\\FlatText',
-        'ROLE'    => 'Sabre\\VObject\\Property\\FlatText',
-        'LOGO'    => 'Sabre\\VObject\\Property\\Binary',
-        // 'AGENT'   => 'Sabre\\VObject\\Property\\',      // Todo: is an embedded vCard. Probably rare, so
-                                 // not supported at the moment
-        'ORG'     => 'Sabre\\VObject\\Property\\Text',
-        'NOTE'    => 'Sabre\\VObject\\Property\\FlatText',
-        'REV'     => 'Sabre\\VObject\\Property\\VCard\\TimeStamp',
-        'SOUND'   => 'Sabre\\VObject\\Property\\FlatText',
-        'URL'     => 'Sabre\\VObject\\Property\\Uri',
-        'UID'     => 'Sabre\\VObject\\Property\\FlatText',
-        'VERSION' => 'Sabre\\VObject\\Property\\FlatText',
-        'KEY'     => 'Sabre\\VObject\\Property\\FlatText',
-        'TZ'      => 'Sabre\\VObject\\Property\\Text',
-
-        // vCard 3.0 properties
-        'CATEGORIES'  => 'Sabre\\VObject\\Property\\Text',
-        'SORT-STRING' => 'Sabre\\VObject\\Property\\FlatText',
-        'PRODID'      => 'Sabre\\VObject\\Property\\FlatText',
-        'NICKNAME'    => 'Sabre\\VObject\\Property\\Text',
-        'CLASS'       => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
-
-        // rfc2739 properties
-        'FBURL'        => 'Sabre\\VObject\\Property\\Uri',
-        'CAPURI'       => 'Sabre\\VObject\\Property\\Uri',
-        'CALURI'       => 'Sabre\\VObject\\Property\\Uri',
-
-        // rfc4770 properties
-        'IMPP'         => 'Sabre\\VObject\\Property\\Uri',
-
-        // vCard 4.0 properties
-        'XML'          => 'Sabre\\VObject\\Property\\FlatText',
-        'ANNIVERSARY'  => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
-        'CLIENTPIDMAP' => 'Sabre\\VObject\\Property\\Text',
-        'LANG'         => 'Sabre\\VObject\\Property\\VCard\\LanguageTag',
-        'GENDER'       => 'Sabre\\VObject\\Property\\Text',
-        'KIND'         => 'Sabre\\VObject\\Property\\FlatText',
-
-        // rfc6474 properties
-        'BIRTHPLACE'    => 'Sabre\\VObject\\Property\\FlatText',
-        'DEATHPLACE'    => 'Sabre\\VObject\\Property\\FlatText',
-        'DEATHDATE'     => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
-
-        // rfc6715 properties
-        'EXPERTISE'     => 'Sabre\\VObject\\Property\\FlatText',
-        'HOBBY'         => 'Sabre\\VObject\\Property\\FlatText',
-        'INTEREST'      => 'Sabre\\VObject\\Property\\FlatText',
-        'ORG-DIRECTORY' => 'Sabre\\VObject\\Property\\FlatText',
-
-    );
-
-    /**
-     * Returns the current document type.
-     *
-     * @return void
-     */
-    function getDocumentType() {
-
-        if (!$this->version) {
-            $version = (string)$this->VERSION;
-            switch($version) {
-                case '2.1' :
-                    $this->version = self::VCARD21;
-                    break;
-                case '3.0' :
-                    $this->version = self::VCARD30;
-                    break;
-                case '4.0' :
-                    $this->version = self::VCARD40;
-                    break;
-                default :
-                    $this->version = self::UNKNOWN;
-                    break;
-
-            }
-        }
-
-        return $this->version;
-
-    }
-
-    /**
-     * Converts the document to a different vcard version.
-     *
-     * Use one of the VCARD constants for the target. This method will return
-     * a copy of the vcard in the new version.
-     *
-     * At the moment the only supported conversion is from 3.0 to 4.0.
-     *
-     * If input and output version are identical, a clone is returned.
-     *
-     * @param int $target
-     * @return VCard
-     */
-    function convert($target) {
-
-        $converter = new VObject\VCardConverter();
-        return $converter->convert($this, $target);
-
-    }
-
-    /**
-     * VCards with version 2.1, 3.0 and 4.0 are found.
-     *
-     * If the VCARD doesn't know its version, 2.1 is assumed.
-     */
-    const DEFAULT_VERSION = self::VCARD21;
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
-     *   2 - An inconsequential issue
-     *   3 - A severe issue.
-     *
-     * @param int $options
-     * @return array
-     */
-    function validate($options = 0) {
-
-        $warnings = array();
-
-        $versionMap = array(
-            self::VCARD21 => '2.1',
-            self::VCARD30 => '3.0',
-            self::VCARD40 => '4.0',
-        );
-
-        $version = $this->select('VERSION');
-        if (count($version)===1) {
-            $version = (string)$this->VERSION;
-            if ($version!=='2.1' && $version!=='3.0' && $version!=='4.0') {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
-                    'node' => $this,
-                );
-                if ($options & self::REPAIR) {
-                    $this->VERSION = $versionMap[self::DEFAULT_VERSION];
-                }
-            }
-            if ($version === '2.1' && ($options & self::PROFILE_CARDDAV)) {
-                $warnings[] = array(
-                    'level' => 3,
-                    'message' => 'CardDAV servers are not allowed to accept vCard 2.1.',
-                    'node' => $this,
-                );
-            }
-
-        }
-        $uid = $this->select('UID');
-        if (count($uid) === 0) {
-            if ($options & self::PROFILE_CARDDAV) {
-                // Required for CardDAV
-                $warningLevel = 3;
-                $message = 'vCards on CardDAV servers MUST have a UID property.';
-            } else {
-                // Not required for regular vcards
-                $warningLevel = 2;
-                $message = 'Adding a UID to a vCard property is recommended.';
-            }
-            if ($options & self::REPAIR) {
-                $this->UID = VObject\UUIDUtil::getUUID();
-                $warningLevel = 1;
-            }
-            $warnings[] = array(
-                'level' => $warningLevel,
-                'message' => $message,
-                'node' => $this,
-            );
-        }
-
-        $fn = $this->select('FN');
-        if (count($fn)!==1) {
-
-            $repaired = false;
-            if (($options & self::REPAIR) && count($fn) === 0) {
-                // We're going to try to see if we can use the contents of the
-                // N property.
-                if (isset($this->N)) {
-                    $value = explode(';', (string)$this->N);
-                    if (isset($value[1]) && $value[1]) {
-                        $this->FN = $value[1] . ' ' . $value[0];
-                    } else {
-                        $this->FN = $value[0];
-                    }
-                    $repaired = true;
-
-                // Otherwise, the ORG property may work
-                } elseif (isset($this->ORG)) {
-                    $this->FN = (string)$this->ORG;
-                    $repaired = true;
-                }
-
-            }
-            $warnings[] = array(
-                'level' => $repaired?1:3,
-                'message' => 'The FN property must appear in the VCARD component exactly 1 time',
-                'node' => $this,
-            );
-        }
-
-        return array_merge(
-            parent::validate($options),
-            $warnings
-        );
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    function getValidationRules() {
-
-        return array(
-            'ADR'          => '*',
-            'ANNIVERSARY'  => '?',
-            'BDAY'         => '?',
-            'CALADRURI'    => '*',
-            'CALURI'       => '*',
-            'CATEGORIES'   => '*',
-            'CLIENTPIDMAP' => '*',
-            'EMAIL'        => '*',
-            'FBURL'        => '*',
-            'IMPP'         => '*',
-            'GENDER'       => '?',
-            'GEO'          => '*',
-            'KEY'          => '*',
-            'KIND'         => '?',
-            'LANG'         => '*',
-            'LOGO'         => '*',
-            'MEMBER'       => '*',
-            'N'            => '?',
-            'NICKNAME'     => '*',
-            'NOTE'         => '*',
-            'ORG'          => '*',
-            'PHOTO'        => '*',
-            'PRODID'       => '?',
-            'RELATED'      => '*',
-            'REV'          => '?',
-            'ROLE'         => '*',
-            'SOUND'        => '*',
-            'SOURCE'       => '*',
-            'TEL'          => '*',
-            'TITLE'        => '*',
-            'TZ'           => '*',
-            'URL'          => '*',
-            'VERSION'      => '1',
-            'XML'          => '*',
-
-            // FN is commented out, because it's already handled by the
-            // validate function, which may also try to repair it.
-            // 'FN'           => '+',
-
-            'UID'          => '?',
-        );
-
-    }
-
-    /**
-     * Returns a preferred field.
-     *
-     * VCards can indicate wether a field such as ADR, TEL or EMAIL is
-     * preferred by specifying TYPE=PREF (vcard 2.1, 3) or PREF=x (vcard 4, x
-     * being a number between 1 and 100).
-     *
-     * If neither of those parameters are specified, the first is returned, if
-     * a field with that name does not exist, null is returned.
-     *
-     * @param string $fieldName
-     * @return VObject\Property|null
-     */
-    function preferred($propertyName) {
-
-        $preferred = null;
-        $lastPref = 101;
-        foreach($this->select($propertyName) as $field) {
-
-            $pref = 101;
-            if (isset($field['TYPE']) && $field['TYPE']->has('PREF')) {
-                $pref = 1;
-            } elseif (isset($field['PREF'])) {
-                $pref = $field['PREF']->getValue();
-            }
-
-            if ($pref < $lastPref || is_null($preferred)) {
-                $preferred = $field;
-                $lastPref = $pref;
-            }
-
-        }
-        return $preferred;
-
-    }
-
-    /**
-     * This method should return a list of default property values.
-     *
-     * @return array
-     */
-    protected function getDefaults() {
-
-        return array(
-            'VERSION' => '3.0',
-            'PRODID' => '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN',
-        );
-
-    }
-
-    /**
-     * This method returns an array, with the representation as it should be
-     * encoded in json. This is used to create jCard or jCal documents.
-     *
-     * @return array
-     */
-    function jsonSerialize() {
-
-        // A vcard does not have sub-components, so we're overriding this
-        // method to remove that array element.
-        $properties = array();
-
-        foreach($this->children as $child) {
-            $properties[] = $child->jsonSerialize();
-        }
-
-        return array(
-            strtolower($this->name),
-            $properties,
-        );
-
-    }
-
-    /**
-     * Returns the default class for a property name.
-     *
-     * @param string $propertyName
-     * @return string
-     */
-    function getClassNameForPropertyName($propertyName) {
-
-        $className = parent::getClassNameForPropertyName($propertyName);
-        // In vCard 4, BINARY no longer exists, and we need URI instead.
-
-        if ($className == 'Sabre\\VObject\\Property\\Binary' && $this->getDocumentType()===self::VCARD40) {
-            return 'Sabre\\VObject\\Property\\Uri';
-        }
-        return $className;
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/lib/Component/VEvent.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-use Sabre\VObject\Recur\EventIterator;
-
-/**
- * VEvent component
- *
- * This component contains some additional functionality specific for VEVENT's.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VEvent extends VObject\Component {
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param \DateTime $start
-     * @param \DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        if ($this->RRULE) {
-            $it = new EventIterator($this);
-            $it->fastForward($start);
-
-            // We fast-forwarded to a spot where the end-time of the
-            // recurrence instance exceeded the start of the requested
-            // time-range.
-            //
-            // If the starttime of the recurrence did not exceed the
-            // end of the time range as well, we have a match.
-            return ($it->getDTStart() < $end && $it->getDTEnd() > $start);
-
-        }
-
-        $effectiveStart = $this->DTSTART->getDateTime();
-        if (isset($this->DTEND)) {
-
-            // The DTEND property is considered non inclusive. So for a 3 day
-            // event in july, dtstart and dtend would have to be July 1st and
-            // July 4th respectively.
-            //
-            // See:
-            // http://tools.ietf.org/html/rfc5545#page-54
-            $effectiveEnd = $this->DTEND->getDateTime();
-
-        } elseif (isset($this->DURATION)) {
-            $effectiveEnd = clone $effectiveStart;
-            $effectiveEnd->add(VObject\DateTimeParser::parseDuration($this->DURATION));
-        } elseif (!$this->DTSTART->hasTime()) {
-            $effectiveEnd = clone $effectiveStart;
-            $effectiveEnd->modify('+1 day');
-        } else {
-            $effectiveEnd = clone $effectiveStart;
-        }
-        return (
-            ($start <= $effectiveEnd) && ($end > $effectiveStart)
-        );
-
-    }
-
-    /**
-     * This method should return a list of default property values.
-     *
-     * @return array
-     */
-    protected function getDefaults() {
-
-        return array(
-            'UID'     => 'sabre-vobject-' . VObject\UUIDUtil::getUUID(),
-            'DTSTAMP' => date('Ymd\\THis\\Z'),
-        );
-
-    }
-
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    public function getValidationRules() {
-
-        $hasMethod = isset($this->parent->METHOD);
-        return array(
-            'UID' => 1,
-            'DTSTAMP' => 1,
-            'DTSTART' => $hasMethod?'?':'1',
-            'CLASS' => '?',
-            'CREATED' => '?',
-            'DESCRIPTION' => '?',
-            'GEO' => '?',
-            'LAST-MODIFICATION' => '?',
-            'LOCATION' => '?',
-            'ORGANIZER' => '?',
-            'PRIORITY' => '?',
-            'SEQUENCE' => '?',
-            'STATUS' => '?',
-            'SUMMARY' => '?',
-            'TRANSP' => '?',
-            'URL' => '?',
-            'RECURRENCE-ID' => '?',
-            'RRULE' => '?',
-            'DTEND' => '?',
-            'DURATION' => '?',
-
-            'ATTACH' => '*',
-            'ATTENDEE' => '*',
-            'CATEGORIES' => '*',
-            'COMMENT' => '*',
-            'CONTACT' => '*',
-            'EXDATE' => '*',
-            'REQUEST-STATUS' => '*',
-            'RELATED-TO' => '*',
-            'RESOURCES' => '*',
-            'RDATE' => '*',
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Component/VFreeBusy.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * The VFreeBusy component
- *
- * This component adds functionality to a component, specific for VFREEBUSY
- * components.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VFreeBusy extends VObject\Component {
-
-    /**
-     * Checks based on the contained FREEBUSY information, if a timeslot is
-     * available.
-     *
-     * @param DateTime $start
-     * @param Datetime $end
-     * @return bool
-     */
-    public function isFree(\DateTime $start, \Datetime $end) {
-
-        foreach($this->select('FREEBUSY') as $freebusy) {
-
-            // We are only interested in FBTYPE=BUSY (the default),
-            // FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE.
-            if (isset($freebusy['FBTYPE']) && strtoupper(substr((string)$freebusy['FBTYPE'],0,4))!=='BUSY') {
-                continue;
-            }
-
-            // The freebusy component can hold more than 1 value, separated by
-            // commas.
-            $periods = explode(',', (string)$freebusy);
-
-            foreach($periods as $period) {
-                // Every period is formatted as [start]/[end]. The start is an
-                // absolute UTC time, the end may be an absolute UTC time, or
-                // duration (relative) value.
-                list($busyStart, $busyEnd) = explode('/', $period);
-
-                $busyStart = VObject\DateTimeParser::parse($busyStart);
-                $busyEnd = VObject\DateTimeParser::parse($busyEnd);
-                if ($busyEnd instanceof \DateInterval) {
-                    $tmp = clone $busyStart;
-                    $tmp->add($busyEnd);
-                    $busyEnd = $tmp;
-                }
-
-                if($start < $busyEnd && $end > $busyStart) {
-                    return false;
-                }
-
-            }
-
-        }
-
-        return true;
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    public function getValidationRules() {
-
-        return array(
-            'UID' => 1,
-            'DTSTAMP' => 1,
-
-            'CONTACT' => '?',
-            'DTSTART' => '?',
-            'DTEND' => '?',
-            'ORGANIZER' => '?',
-            'URL' => '?',
-
-            'ATTENDEE' => '*',
-            'COMMENT' => '*',
-            'FREEBUSY' => '*',
-            'REQUEST-STATUS' => '*',
-        );
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/lib/Component/VJournal.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * VJournal component
- *
- * This component contains some additional functionality specific for VJOURNALs.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VJournal extends VObject\Component {
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
-        if ($dtstart) {
-            $effectiveEnd = clone $dtstart;
-            if (!$this->DTSTART->hasTime()) {
-                $effectiveEnd->modify('+1 day');
-            }
-
-            return ($start <= $effectiveEnd && $end > $dtstart);
-
-        }
-        return false;
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    public function getValidationRules() {
-
-        return array(
-            'UID' => 1,
-            'DTSTAMP' => 1,
-
-            'CLASS' => '?',
-            'CREATED' => '?',
-            'DTSTART' => '?',
-            'LAST-MODIFICATION' => '?',
-            'ORGANIZER' => '?',
-            'RECURRENCE-ID' => '?',
-            'SEQUENCE' => '?',
-            'STATUS' => '?',
-            'SUMMARY' => '?',
-            'URL' => '?',
-
-            'RRULE' => '?',
-
-            'ATTACH' => '*',
-            'ATTENDEE' => '*',
-            'CATEGORIES' => '*',
-            'COMMENT' => '*',
-            'CONTACT' => '*',
-            'DESCRIPTION' => '*',
-            'EXDATE' => '*',
-            'RELATED-TO' => '*',
-            'RDATE' => '*',
-        );
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Component/VTimeZone.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * The VTimeZone component
- *
- * This component adds functionality to a component, specific for VTIMEZONE
- * components.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VTimeZone extends VObject\Component {
-
-    /**
-     * Returns the PHP DateTimeZone for this VTIMEZONE component.
-     *
-     * If we can't accurately determine the timezone, this method will return
-     * UTC.
-     *
-     * @return \DateTimeZone
-     */
-    function getTimeZone() {
-
-        return VObject\TimeZoneUtil::getTimeZone((string)$this->TZID, $this->root);
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    function getValidationRules() {
-
-        return array(
-            'TZID' => 1,
-
-            'LAST-MODIFICATION' => '?',
-            'TZURL' => '?',
-
-            // At least 1 STANDARD or DAYLIGHT must appear, or more. But both
-            // cannot appear in the same VTIMEZONE.
-            //
-            // The validator is not specific yet to pick this up, so these
-            // rules are too loose.
-            'STANDARD' => '*',
-            'DAYLIGHT' => '*',
-        );
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/lib/Component/VTodo.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-/**
- * VTodo component
- *
- * This component contains some additional functionality specific for VTODOs.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VTodo extends VObject\Component {
-
-    /**
-     * Returns true or false depending on if the event falls in the specified
-     * time-range. This is used for filtering purposes.
-     *
-     * The rules used to determine if an event falls within the specified
-     * time-range is based on the CalDAV specification.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return bool
-     */
-    public function isInTimeRange(\DateTime $start, \DateTime $end) {
-
-        $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
-        $duration = isset($this->DURATION)?VObject\DateTimeParser::parseDuration($this->DURATION):null;
-        $due = isset($this->DUE)?$this->DUE->getDateTime():null;
-        $completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null;
-        $created = isset($this->CREATED)?$this->CREATED->getDateTime():null;
-
-        if ($dtstart) {
-            if ($duration) {
-                $effectiveEnd = clone $dtstart;
-                $effectiveEnd->add($duration);
-                return $start <= $effectiveEnd && $end > $dtstart;
-            } elseif ($due) {
-                return
-                    ($start < $due || $start <= $dtstart) &&
-                    ($end > $dtstart || $end >= $due);
-            } else {
-                return $start <= $dtstart && $end > $dtstart;
-            }
-        }
-        if ($due) {
-            return ($start < $due && $end >= $due);
-        }
-        if ($completed && $created) {
-            return
-                ($start <= $created || $start <= $completed) &&
-                ($end >= $created || $end >= $completed);
-        }
-        if ($completed) {
-            return ($start <= $completed && $end >= $completed);
-        }
-        if ($created) {
-            return ($end > $created);
-        }
-        return true;
-
-    }
-
-    /**
-     * A simple list of validation rules.
-     *
-     * This is simply a list of properties, and how many times they either
-     * must or must not appear.
-     *
-     * Possible values per property:
-     *   * 0 - Must not appear.
-     *   * 1 - Must appear exactly once.
-     *   * + - Must appear at least once.
-     *   * * - Can appear any number of times.
-     *
-     * @var array
-     */
-    public function getValidationRules() {
-
-        return array(
-            'UID' => 1,
-            'DTSTAMP' => 1,
-
-            'CLASS' => '?',
-            'COMPLETED' => '?',
-            'CREATED' => '?',
-            'DESCRIPTION' => '?',
-            'DTSTART' => '?',
-            'GEO' => '?',
-            'LAST-MODIFICATION' => '?',
-            'LOCATION' => '?',
-            'ORGANIZER' => '?',
-            'PERCENT' => '?',
-            'PRIORITY' => '?',
-            'RECURRENCE-ID' => '?',
-            'SEQUENCE' => '?',
-            'STATUS' => '?',
-            'SUMMARY' => '?',
-            'URL' => '?',
-
-            'RRULE' => '?',
-            'DUE' => '?',
-            'DURATION' => '?',
-
-            'ATTACH' => '*',
-            'ATTENDEE' => '*',
-            'CATEGORIES' => '*',
-            'COMMENT' => '*',
-            'CONTACT' => '*',
-            'EXDATE' => '*',
-            'REQUEST-STATUS' => '*',
-            'RELATED-TO' => '*',
-            'RESOURCES' => '*',
-            'RDATE' => '*',
-        );
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
-     *   2 - An inconsequential issue
-     *   3 - A severe issue.
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $result = parent::validate($options);
-        if (isset($this->DUE) && isset($this->DTSTART)) {
-
-            $due = $this->DUE;
-            $dtStart = $this->DTSTART;
-
-            if ($due->getValueType() !== $dtStart->getValueType()) {
-
-                $result[] = array(
-                    'level'   => 3,
-                    'message' => 'The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART',
-                    'node' => $due,
-                );
-
-            } elseif ($due->getDateTime() < $dtStart->getDateTime()) {
-
-                $result[] = array(
-                    'level'   => 3,
-                    'message' => 'DUE must occur after DTSTART',
-                    'node' => $due,
-                );
-
-            }
-
-        }
-
-        return $result;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/DateTimeParser.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use DateTime;
-use DateTimeZone;
-use DateInterval;
-use InvalidArgumentException;
-use LogicException;
-
-/**
- * DateTimeParser
- *
- * This class is responsible for parsing the several different date and time
- * formats iCalendar and vCards have.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class DateTimeParser {
-
-    /**
-     * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
-     *
-     * Specifying a reference timezone is optional. It will only be used
-     * if the non-UTC format is used. The argument is used as a reference, the
-     * returned DateTime object will still be in the UTC timezone.
-     *
-     * @param string $dt
-     * @param DateTimeZone $tz
-     * @return DateTime
-     */
-    static public function parseDateTime($dt, DateTimeZone $tz = null) {
-
-        // Format is YYYYMMDD + "T" + hhmmss
-        $result = preg_match('/^([0-9]{4})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
-
-        if (!$result) {
-            throw new LogicException('The supplied iCalendar datetime value is incorrect: ' . $dt);
-        }
-
-        if ($matches[7]==='Z' || is_null($tz)) {
-            $tz = new DateTimeZone('UTC');
-        }
-        $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
-
-        // Still resetting the timezone, to normalize everything to UTC
-        // $date->setTimeZone(new \DateTimeZone('UTC'));
-        return $date;
-
-    }
-
-    /**
-     * Parses an iCalendar (rfc5545) formatted date and returns a DateTime object.
-     *
-     * @param string $date
-     * @param DateTimeZone $tz
-     * @return DateTime
-     */
-    static public function parseDate($date, DateTimeZone $tz = null) {
-
-        // Format is YYYYMMDD
-        $result = preg_match('/^([0-9]{4})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
-
-        if (!$result) {
-            throw new LogicException('The supplied iCalendar date value is incorrect: ' . $date);
-        }
-
-        if (is_null($tz)) {
-            $tz = new DateTimeZone('UTC');
-        }
-
-        $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], $tz);
-        return $date;
-
-    }
-
-    /**
-     * Parses an iCalendar (RFC5545) formatted duration value.
-     *
-     * This method will either return a DateTimeInterval object, or a string
-     * suitable for strtotime or DateTime::modify.
-     *
-     * @param string $duration
-     * @param bool $asString
-     * @return DateInterval|string
-     */
-    static public function parseDuration($duration, $asString = false) {
-
-        $result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
-        if (!$result) {
-            throw new LogicException('The supplied iCalendar duration value is incorrect: ' . $duration);
-        }
-
-        if (!$asString) {
-            $invert = false;
-            if ($matches['plusminus']==='-') {
-                $invert = true;
-            }
-
-
-            $parts = array(
-                'week',
-                'day',
-                'hour',
-                'minute',
-                'second',
-            );
-            foreach($parts as $part) {
-                $matches[$part] = isset($matches[$part])&&$matches[$part]?(int)$matches[$part]:0;
-            }
-
-
-            // We need to re-construct the $duration string, because weeks and
-            // days are not supported by DateInterval in the same string.
-            $duration = 'P';
-            $days = $matches['day'];
-            if ($matches['week']) {
-                $days+=$matches['week']*7;
-            }
-            if ($days)
-                $duration.=$days . 'D';
-
-            if ($matches['minute'] || $matches['second'] || $matches['hour']) {
-                $duration.='T';
-
-                if ($matches['hour'])
-                    $duration.=$matches['hour'].'H';
-
-                if ($matches['minute'])
-                    $duration.=$matches['minute'].'M';
-
-                if ($matches['second'])
-                    $duration.=$matches['second'].'S';
-
-            }
-
-            if ($duration==='P') {
-                $duration = 'PT0S';
-            }
-            $iv = new DateInterval($duration);
-            if ($invert) $iv->invert = true;
-
-            return $iv;
-
-        }
-
-
-
-        $parts = array(
-            'week',
-            'day',
-            'hour',
-            'minute',
-            'second',
-        );
-
-        $newDur = '';
-        foreach($parts as $part) {
-            if (isset($matches[$part]) && $matches[$part]) {
-                $newDur.=' '.$matches[$part] . ' ' . $part . 's';
-            }
-        }
-
-        $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
-        if ($newDur === '+') {
-            $newDur = '+0 seconds';
-        };
-        return $newDur;
-
-    }
-
-    /**
-     * Parses either a Date or DateTime, or Duration value.
-     *
-     * @param string $date
-     * @param DateTimeZone|string $referenceTz
-     * @return DateTime|DateInterval
-     */
-    static public function parse($date, $referenceTz = null) {
-
-        if ($date[0]==='P' || ($date[0]==='-' && $date[1]==='P')) {
-            return self::parseDuration($date);
-        } elseif (strlen($date)===8) {
-            return self::parseDate($date, $referenceTz);
-        } else {
-            return self::parseDateTime($date, $referenceTz);
-        }
-
-    }
-
-    /**
-     * This method parses a vCard date and or time value.
-     *
-     * This can be used for the DATE, DATE-TIME, TIMESTAMP and
-     * DATE-AND-OR-TIME value.
-     *
-     * This method returns an array, not a DateTime value.
-     *
-     * The elements in the array are in the following order:
-     * year, month, date, hour, minute, second, timezone
-     *
-     * Almost any part of the string may be omitted. It's for example legal to
-     * just specify seconds, leave out the year, etc.
-     *
-     * Timezone is either returned as 'Z' or as '+08:00'
-     *
-     * For any non-specified values null is returned.
-     *
-     * List of date formats that are supported:
-     * YYYY
-     * YYYY-MM
-     * YYYYMMDD
-     * --MMDD
-     * ---DD
-     *
-     * YYYY-MM-DD
-     * --MM-DD
-     * ---DD
-     *
-     * List of supported time formats:
-     *
-     * HH
-     * HHMM
-     * HHMMSS
-     * -MMSS
-     * --SS
-     *
-     * HH
-     * HH:MM
-     * HH:MM:SS
-     * -MM:SS
-     * --SS
-     *
-     * A full basic-format date-time string looks like :
-     * 20130603T133901
-     *
-     * A full extended-format date-time string looks like :
-     * 2013-06-03T13:39:01
-     *
-     * Times may be postfixed by a timezone offset. This can be either 'Z' for
-     * UTC, or a string like -0500 or +1100.
-     *
-     * @param string $date
-     * @return array
-     */
-    static public function parseVCardDateTime($date) {
-
-        $regex = '/^
-            (?:  # date part
-                (?:
-                    (?: (?P<year> [0-9]{4}) (?: -)?| --)
-                    (?P<month> [0-9]{2})?
-                |---)
-                (?P<date> [0-9]{2})?
-            )?
-            (?:T  # time part
-                (?P<hour> [0-9]{2} | -)
-                (?P<minute> [0-9]{2} | -)?
-                (?P<second> [0-9]{2})?
-
-                (?P<timezone> # timezone offset
-
-                    Z | (?: \+|-)(?: [0-9]{4})
-
-                )?
-
-            )?
-            $/x';
-
-
-        if (!preg_match($regex, $date, $matches)) {
-
-            // Attempting to parse the extended format.
-            $regex = '/^
-                (?: # date part
-                    (?: (?P<year> [0-9]{4}) - | -- )
-                    (?P<month> [0-9]{2}) -
-                    (?P<date> [0-9]{2})
-                )?
-                (?:T # time part
-
-                    (?: (?P<hour> [0-9]{2}) : | -)
-                    (?: (?P<minute> [0-9]{2}) : | -)?
-                    (?P<second> [0-9]{2})?
-
-                    (?P<timezone> # timezone offset
-
-                        Z | (?: \+|-)(?: [0-9]{2}:[0-9]{2})
-
-                    )?
-
-                )?
-                $/x';
-
-            if (!preg_match($regex, $date, $matches)) {
-                throw new InvalidArgumentException('Invalid vCard date-time string: ' . $date);
-            }
-
-        }
-        $parts = array(
-            'year',
-            'month',
-            'date',
-            'hour',
-            'minute',
-            'second',
-            'timezone'
-        );
-
-        $result = array();
-        foreach($parts as $part) {
-
-            if (empty($matches[$part])) {
-                $result[$part] = null;
-            } elseif ($matches[$part] === '-' || $matches[$part] === '--') {
-                $result[$part] = null;
-            } else {
-                $result[$part] = $matches[$part];
-            }
-
-        }
-
-        return $result;
-
-    }
-
-    /**
-     * This method parses a vCard TIME value.
-     *
-     * This method returns an array, not a DateTime value.
-     *
-     * The elements in the array are in the following order:
-     * hour, minute, second, timezone
-     *
-     * Almost any part of the string may be omitted. It's for example legal to
-     * just specify seconds, leave out the hour etc.
-     *
-     * Timezone is either returned as 'Z' or as '+08:00'
-     *
-     * For any non-specified values null is returned.
-     *
-     * List of supported time formats:
-     *
-     * HH
-     * HHMM
-     * HHMMSS
-     * -MMSS
-     * --SS
-     *
-     * HH
-     * HH:MM
-     * HH:MM:SS
-     * -MM:SS
-     * --SS
-     *
-     * A full basic-format time string looks like :
-     * 133901
-     *
-     * A full extended-format time string looks like :
-     * 13:39:01
-     *
-     * Times may be postfixed by a timezone offset. This can be either 'Z' for
-     * UTC, or a string like -0500 or +11:00.
-     *
-     * @param string $date
-     * @return array
-     */
-    static public function parseVCardTime($date) {
-
-        $regex = '/^
-            (?P<hour> [0-9]{2} | -)
-            (?P<minute> [0-9]{2} | -)?
-            (?P<second> [0-9]{2})?
-
-            (?P<timezone> # timezone offset
-
-                Z | (?: \+|-)(?: [0-9]{4})
-
-            )?
-            $/x';
-
-
-        if (!preg_match($regex, $date, $matches)) {
-
-            // Attempting to parse the extended format.
-            $regex = '/^
-                (?: (?P<hour> [0-9]{2}) : | -)
-                (?: (?P<minute> [0-9]{2}) : | -)?
-                (?P<second> [0-9]{2})?
-
-                (?P<timezone> # timezone offset
-
-                    Z | (?: \+|-)(?: [0-9]{2}:[0-9]{2})
-
-                )?
-                $/x';
-
-            if (!preg_match($regex, $date, $matches)) {
-                throw new InvalidArgumentException('Invalid vCard time string: ' . $date);
-            }
-
-        }
-        $parts = array(
-            'hour',
-            'minute',
-            'second',
-            'timezone'
-        );
-
-        $result = array();
-        foreach($parts as $part) {
-
-            if (empty($matches[$part])) {
-                $result[$part] = null;
-            } elseif ($matches[$part] === '-') {
-                $result[$part] = null;
-            } else {
-                $result[$part] = $matches[$part];
-            }
-
-        }
-
-        return $result;
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Document.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Document
- *
- * A document is just like a component, except that it's also the top level
- * element.
- *
- * Both a VCALENDAR and a VCARD are considered documents.
- *
- * This class also provides a registry for document types.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-abstract class Document extends Component {
-
-    /**
-     * Unknown document type
-     */
-    const UNKNOWN = 1;
-
-    /**
-     * vCalendar 1.0
-     */
-    const VCALENDAR10 = 2;
-
-    /**
-     * iCalendar 2.0
-     */
-    const ICALENDAR20 = 3;
-
-    /**
-     * vCard 2.1
-     */
-    const VCARD21 = 4;
-
-    /**
-     * vCard 3.0
-     */
-    const VCARD30 = 5;
-
-    /**
-     * vCard 4.0
-     */
-    const VCARD40 = 6;
-
-    /**
-     * The default name for this component.
-     *
-     * This should be 'VCALENDAR' or 'VCARD'.
-     *
-     * @var string
-     */
-    static public $defaultName;
-
-    /**
-     * List of properties, and which classes they map to.
-     *
-     * @var array
-     */
-    static public $propertyMap = array();
-
-    /**
-     * List of components, along with which classes they map to.
-     *
-     * @var array
-     */
-    static public $componentMap = array();
-
-    /**
-     * List of value-types, and which classes they map to.
-     *
-     * @var array
-     */
-    static public $valueMap = array();
-
-    /**
-     * Creates a new document.
-     *
-     * We're changing the default behavior slightly here. First, we don't want
-     * to have to specify a name (we already know it), and we want to allow
-     * children to be specified in the first argument.
-     *
-     * But, the default behavior also works.
-     *
-     * So the two sigs:
-     *
-     * new Document(array $children = array(), $defaults = true);
-     * new Document(string $name, array $children = array(), $defaults = true)
-     *
-     * @return void
-     */
-    public function __construct() {
-
-        $args = func_get_args();
-        if (count($args)===0 || is_array($args[0])) {
-            array_unshift($args, $this, static::$defaultName);
-            call_user_func_array(array('parent', '__construct'), $args);
-        } else {
-            array_unshift($args, $this);
-            call_user_func_array(array('parent', '__construct'), $args);
-        }
-
-    }
-
-    /**
-     * Returns the current document type.
-     *
-     * @return void
-     */
-    public function getDocumentType() {
-
-        return self::UNKNOWN;
-
-    }
-
-    /**
-     * Creates a new component or property.
-     *
-     * If it's a known component, we will automatically call createComponent.
-     * otherwise, we'll assume it's a property and call createProperty instead.
-     *
-     * @param string $name
-     * @param string $arg1,... Unlimited number of args
-     * @return mixed
-     */
-    public function create($name) {
-
-        if (isset(static::$componentMap[strtoupper($name)])) {
-
-            return call_user_func_array(array($this,'createComponent'), func_get_args());
-
-        } else {
-
-            return call_user_func_array(array($this,'createProperty'), func_get_args());
-
-        }
-
-    }
-
-    /**
-     * Creates a new component
-     *
-     * This method automatically searches for the correct component class, based
-     * on its name.
-     *
-     * You can specify the children either in key=>value syntax, in which case
-     * properties will automatically be created, or you can just pass a list of
-     * Component and Property object.
-     *
-     * By default, a set of sensible values will be added to the component. For
-     * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To
-     * ensure that this does not happen, set $defaults to false.
-     *
-     * @param string $name
-     * @param array $children
-     * @param bool $defaults
-     * @return Component
-     */
-    public function createComponent($name, array $children = null, $defaults = true) {
-
-        $name = strtoupper($name);
-        $class = 'Sabre\\VObject\\Component';
-
-        if (isset(static::$componentMap[$name])) {
-            $class=static::$componentMap[$name];
-        }
-        if (is_null($children)) $children = array();
-        return new $class($this, $name, $children, $defaults);
-
-    }
-
-    /**
-     * Factory method for creating new properties
-     *
-     * This method automatically searches for the correct property class, based
-     * on its name.
-     *
-     * You can specify the parameters either in key=>value syntax, in which case
-     * parameters will automatically be created, or you can just pass a list of
-     * Parameter objects.
-     *
-     * @param string $name
-     * @param mixed $value
-     * @param array $parameters
-     * @param string $valueType Force a specific valuetype, such as URI or TEXT
-     * @return Property
-     */
-    public function createProperty($name, $value = null, array $parameters = null, $valueType = null) {
-
-        // If there's a . in the name, it means it's prefixed by a groupname.
-        if (($i=strpos($name,'.'))!==false) {
-            $group = substr($name, 0, $i);
-            $name = strtoupper(substr($name, $i+1));
-        } else {
-            $name = strtoupper($name);
-            $group = null;
-        }
-
-        $class = null;
-
-        if ($valueType) {
-            // The valueType argument comes first to figure out the correct
-            // class.
-            $class = $this->getClassNameForPropertyValue($valueType);
-        }
-
-        if (is_null($class) && isset($parameters['VALUE'])) {
-            // If a VALUE parameter is supplied, we should use that.
-            $class = $this->getClassNameForPropertyValue($parameters['VALUE']);
-        }
-        if (is_null($class)) {
-            $class = $this->getClassNameForPropertyName($name);
-        }
-        if (is_null($parameters)) $parameters = array();
-
-        return new $class($this, $name, $value, $parameters, $group);
-
-    }
-
-    /**
-     * This method returns a full class-name for a value parameter.
-     *
-     * For instance, DTSTART may have VALUE=DATE. In that case we will look in
-     * our valueMap table and return the appropriate class name.
-     *
-     * This method returns null if we don't have a specialized class.
-     *
-     * @param string $valueParam
-     * @return void
-     */
-    public function getClassNameForPropertyValue($valueParam) {
-
-        $valueParam = strtoupper($valueParam);
-        if (isset(static::$valueMap[$valueParam])) {
-            return static::$valueMap[$valueParam];
-        }
-
-    }
-
-    /**
-     * Returns the default class for a property name.
-     *
-     * @param string $propertyName
-     * @return string
-     */
-    public function getClassNameForPropertyName($propertyName) {
-
-        if (isset(static::$propertyMap[$propertyName])) {
-            return static::$propertyMap[$propertyName];
-        } else {
-            return 'Sabre\\VObject\\Property\\Unknown';
-        }
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/ElementList.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * VObject ElementList
- *
- * This class represents a list of elements. Lists are the result of queries,
- * such as doing $vcalendar->vevent where there's multiple VEVENT objects.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class ElementList implements \Iterator, \Countable, \ArrayAccess {
-
-    /**
-     * Inner elements
-     *
-     * @var array
-     */
-    protected $elements = array();
-
-    /**
-     * Creates the element list.
-     *
-     * @param array $elements
-     */
-    public function __construct(array $elements) {
-
-        $this->elements = $elements;
-
-    }
-
-    /* {{{ Iterator interface */
-
-    /**
-     * Current position
-     *
-     * @var int
-     */
-    private $key = 0;
-
-    /**
-     * Returns current item in iteration
-     *
-     * @return Element
-     */
-    public function current() {
-
-        return $this->elements[$this->key];
-
-    }
-
-    /**
-     * To the next item in the iterator
-     *
-     * @return void
-     */
-    public function next() {
-
-        $this->key++;
-
-    }
-
-    /**
-     * Returns the current iterator key
-     *
-     * @return int
-     */
-    public function key() {
-
-        return $this->key;
-
-    }
-
-    /**
-     * Returns true if the current position in the iterator is a valid one
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        return isset($this->elements[$this->key]);
-
-    }
-
-    /**
-     * Rewinds the iterator
-     *
-     * @return void
-     */
-    public function rewind() {
-
-        $this->key = 0;
-
-    }
-
-    /* }}} */
-
-    /* {{{ Countable interface */
-
-    /**
-     * Returns the number of elements
-     *
-     * @return int
-     */
-    public function count() {
-
-        return count($this->elements);
-
-    }
-
-    /* }}} */
-
-    /* {{{ ArrayAccess Interface */
-
-
-    /**
-     * Checks if an item exists through ArrayAccess.
-     *
-     * @param int $offset
-     * @return bool
-     */
-    public function offsetExists($offset) {
-
-        return isset($this->elements[$offset]);
-
-    }
-
-    /**
-     * Gets an item through ArrayAccess.
-     *
-     * @param int $offset
-     * @return mixed
-     */
-    public function offsetGet($offset) {
-
-        return $this->elements[$offset];
-
-    }
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * @param int $offset
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($offset, $value) {
-
-        throw new \LogicException('You can not add new objects to an ElementList');
-
-    }
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return void
-     */
-    public function offsetUnset($offset) {
-
-        throw new \LogicException('You can not remove objects from an ElementList');
-
-    }
-
-    /* }}} */
-
-}
--- a/vendor/sabre/vobject/lib/EofException.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Exception thrown by parser when the end of the stream has been reached,
- * before this was expected.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class EofException extends ParseException {
-
-}
--- a/vendor/sabre/vobject/lib/FreeBusyGenerator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,355 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use DateTimeZone;
-use Sabre\VObject\Component\VCalendar;
-use Sabre\VObject\Recur\EventIterator;
-
-/**
- * This class helps with generating FREEBUSY reports based on existing sets of
- * objects.
- *
- * It only looks at VEVENT and VFREEBUSY objects from the sourcedata, and
- * generates a single VFREEBUSY object.
- *
- * VFREEBUSY components are described in RFC5545, The rules for what should
- * go in a single freebusy report is taken from RFC4791, section 7.10.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class FreeBusyGenerator {
-
-    /**
-     * Input objects
-     *
-     * @var array
-     */
-    protected $objects;
-
-    /**
-     * Start of range
-     *
-     * @var DateTime|null
-     */
-    protected $start;
-
-    /**
-     * End of range
-     *
-     * @var DateTime|null
-     */
-    protected $end;
-
-    /**
-     * VCALENDAR object
-     *
-     * @var Component
-     */
-    protected $baseObject;
-
-    /**
-     * Reference timezone.
-     *
-     * When we are calculating busy times, and we come across so-called
-     * floating times (times without a timezone), we use the reference timezone
-     * instead.
-     *
-     * This is also used for all-day events.
-     *
-     * This defaults to UTC.
-     *
-     * @var DateTimeZone
-     */
-    protected $timeZone;
-
-    /**
-     * Creates the generator.
-     *
-     * Check the setTimeRange and setObjects methods for details about the
-     * arguments.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @param mixed $objects
-     * @param DateTimeZone $timeZone
-     * @return void
-     */
-    public function __construct(\DateTime $start = null, \DateTime $end = null, $objects = null, DateTimeZone $timeZone = null) {
-
-        if ($start && $end) {
-            $this->setTimeRange($start, $end);
-        }
-
-        if ($objects) {
-            $this->setObjects($objects);
-        }
-        if (is_null($timeZone)) {
-            $timeZone = new DateTimeZone('UTC');
-        }
-        $this->setTimeZone($timeZone);
-
-    }
-
-    /**
-     * Sets the VCALENDAR object.
-     *
-     * If this is set, it will not be generated for you. You are responsible
-     * for setting things like the METHOD, CALSCALE, VERSION, etc..
-     *
-     * The VFREEBUSY object will be automatically added though.
-     *
-     * @param Component $vcalendar
-     * @return void
-     */
-    public function setBaseObject(Component $vcalendar) {
-
-        $this->baseObject = $vcalendar;
-
-    }
-
-    /**
-     * Sets the input objects
-     *
-     * You must either specify a valendar object as a strong, or as the parse
-     * Component.
-     * It's also possible to specify multiple objects as an array.
-     *
-     * @param mixed $objects
-     * @return void
-     */
-    public function setObjects($objects) {
-
-        if (!is_array($objects)) {
-            $objects = array($objects);
-        }
-
-        $this->objects = array();
-        foreach($objects as $object) {
-
-            if (is_string($object)) {
-                $this->objects[] = Reader::read($object);
-            } elseif ($object instanceof Component) {
-                $this->objects[] = $object;
-            } else {
-                throw new \InvalidArgumentException('You can only pass strings or \\Sabre\\VObject\\Component arguments to setObjects');
-            }
-
-        }
-
-    }
-
-    /**
-     * Sets the time range
-     *
-     * Any freebusy object falling outside of this time range will be ignored.
-     *
-     * @param DateTime $start
-     * @param DateTime $end
-     * @return void
-     */
-    public function setTimeRange(\DateTime $start = null, \DateTime $end = null) {
-
-        $this->start = $start;
-        $this->end = $end;
-
-    }
-
-    /**
-     * Sets the reference timezone for floating times.
-     *
-     * @param DateTimeZone $timeZone
-     * @return void
-     */
-    public function setTimeZone(DateTimeZone $timeZone) {
-
-        $this->timeZone = $timeZone;
-
-    }
-
-    /**
-     * Parses the input data and returns a correct VFREEBUSY object, wrapped in
-     * a VCALENDAR.
-     *
-     * @return Component
-     */
-    public function getResult() {
-
-        $busyTimes = array();
-
-        foreach($this->objects as $object) {
-
-            foreach($object->getBaseComponents() as $component) {
-
-                switch($component->name) {
-
-                    case 'VEVENT' :
-
-                        $FBTYPE = 'BUSY';
-                        if (isset($component->TRANSP) && (strtoupper($component->TRANSP) === 'TRANSPARENT')) {
-                            break;
-                        }
-                        if (isset($component->STATUS)) {
-                            $status = strtoupper($component->STATUS);
-                            if ($status==='CANCELLED') {
-                                break;
-                            }
-                            if ($status==='TENTATIVE') {
-                                $FBTYPE = 'BUSY-TENTATIVE';
-                            }
-                        }
-
-                        $times = array();
-
-                        if ($component->RRULE) {
-
-                            $iterator = new EventIterator($object, (string)$component->uid, $this->timeZone);
-                            if ($this->start) {
-                                $iterator->fastForward($this->start);
-                            }
-
-                            $maxRecurrences = 200;
-
-                            while($iterator->valid() && --$maxRecurrences) {
-
-                                $startTime = $iterator->getDTStart();
-                                if ($this->end && $startTime > $this->end) {
-                                    break;
-                                }
-                                $times[] = array(
-                                    $iterator->getDTStart(),
-                                    $iterator->getDTEnd(),
-                                );
-
-                                $iterator->next();
-
-                            }
-
-                        } else {
-
-                            $startTime = $component->DTSTART->getDateTime($this->timeZone);
-                            if ($this->end && $startTime > $this->end) {
-                                break;
-                            }
-                            $endTime = null;
-                            if (isset($component->DTEND)) {
-                                $endTime = $component->DTEND->getDateTime($this->timeZone);
-                            } elseif (isset($component->DURATION)) {
-                                $duration = DateTimeParser::parseDuration((string)$component->DURATION);
-                                $endTime = clone $startTime;
-                                $endTime->add($duration);
-                            } elseif (!$component->DTSTART->hasTime()) {
-                                $endTime = clone $startTime;
-                                $endTime->modify('+1 day');
-                            } else {
-                                // The event had no duration (0 seconds)
-                                break;
-                            }
-
-                            $times[] = array($startTime, $endTime);
-
-                        }
-
-                        foreach($times as $time) {
-
-                            if ($this->end && $time[0] > $this->end) break;
-                            if ($this->start && $time[1] < $this->start) break;
-
-                            $busyTimes[] = array(
-                                $time[0],
-                                $time[1],
-                                $FBTYPE,
-                            );
-                        }
-                        break;
-
-                    case 'VFREEBUSY' :
-                        foreach($component->FREEBUSY as $freebusy) {
-
-                            $fbType = isset($freebusy['FBTYPE'])?strtoupper($freebusy['FBTYPE']):'BUSY';
-
-                            // Skipping intervals marked as 'free'
-                            if ($fbType==='FREE')
-                                continue;
-
-                            $values = explode(',', $freebusy);
-                            foreach($values as $value) {
-                                list($startTime, $endTime) = explode('/', $value);
-                                $startTime = DateTimeParser::parseDateTime($startTime);
-
-                                if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
-                                    $duration = DateTimeParser::parseDuration($endTime);
-                                    $endTime = clone $startTime;
-                                    $endTime->add($duration);
-                                } else {
-                                    $endTime = DateTimeParser::parseDateTime($endTime);
-                                }
-
-                                if($this->start && $this->start > $endTime) continue;
-                                if($this->end && $this->end < $startTime) continue;
-                                $busyTimes[] = array(
-                                    $startTime,
-                                    $endTime,
-                                    $fbType
-                                );
-
-                            }
-
-
-                        }
-                        break;
-
-
-
-                }
-
-
-            }
-
-        }
-
-        if ($this->baseObject) {
-            $calendar = $this->baseObject;
-        } else {
-            $calendar = new VCalendar();
-        }
-
-        $vfreebusy = $calendar->createComponent('VFREEBUSY');
-        $calendar->add($vfreebusy);
-
-        if ($this->start) {
-            $dtstart = $calendar->createProperty('DTSTART');
-            $dtstart->setDateTime($this->start);
-            $vfreebusy->add($dtstart);
-        }
-        if ($this->end) {
-            $dtend = $calendar->createProperty('DTEND');
-            $dtend->setDateTime($this->end);
-            $vfreebusy->add($dtend);
-        }
-        $dtstamp = $calendar->createProperty('DTSTAMP');
-        $dtstamp->setDateTime(new \DateTime('now', new \DateTimeZone('UTC')));
-        $vfreebusy->add($dtstamp);
-
-        foreach($busyTimes as $busyTime) {
-
-            $busyTime[0]->setTimeZone(new \DateTimeZone('UTC'));
-            $busyTime[1]->setTimeZone(new \DateTimeZone('UTC'));
-
-            $prop = $calendar->createProperty(
-                'FREEBUSY',
-                $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
-            );
-            $prop['FBTYPE'] = $busyTime[2];
-            $vfreebusy->add($prop);
-
-        }
-
-        return $calendar;
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/lib/ITip/Broker.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,942 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-use Sabre\VObject\Component\VCalendar;
-use Sabre\VObject\DateTimeParser;
-use Sabre\VObject\Reader;
-use Sabre\VObject\Recur\EventIterator;
-
-/**
- * The ITip\Broker class is a utility class that helps with processing
- * so-called iTip messages.
- *
- * iTip is defined in rfc5546, stands for iCalendar Transport-Independent
- * Interoperability Protocol, and describes the underlying mechanism for
- * using iCalendar for scheduling for for example through email (also known as
- * IMip) and CalDAV Scheduling.
- *
- * This class helps by:
- *
- * 1. Creating individual invites based on an iCalendar event for each
- *    attendee.
- * 2. Generating invite updates based on an iCalendar update. This may result
- *    in new invites, updates and cancellations for attendees, if that list
- *    changed.
- * 3. On the receiving end, it can create a local iCalendar event based on
- *    a received invite.
- * 4. It can also process an invite update on a local event, ensuring that any
- *    overridden properties from attendees are retained.
- * 5. It can create a accepted or declined iTip reply based on an invite.
- * 6. It can process a reply from an invite and update an events attendee
- *     status based on a reply.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Broker {
-
-    /**
-     * This setting determines whether the rules for the SCHEDULE-AGENT
-     * parameter should be followed.
-     *
-     * This is a parameter defined on ATTENDEE properties, introduced by RFC
-     * 6638. This parameter allows a caldav client to tell the server 'Don't do
-     * any scheduling operations'.
-     *
-     * If this setting is turned on, any attendees with SCHEDULE-AGENT set to
-     * CLIENT will be ignored. This is the desired behavior for a CalDAV
-     * server, but if you're writing an iTip application that doesn't deal with
-     * CalDAV, you may want to ignore this parameter.
-     *
-     * @var bool
-     */
-    public $scheduleAgentServerRules = true;
-
-    /**
-     * The broker will try during 'parseEvent' figure out whether the change
-     * was significant.
-     *
-     * It uses a few different ways to do this. One of these ways is seeing if
-     * certain properties changed values. This list of specified here.
-     *
-     * This list is taken from:
-     * * http://tools.ietf.org/html/rfc5546#section-2.1.4
-     *
-     * @var string[]
-     */
-    public $significantChangeProperties = array(
-        'DTSTART',
-        'DTEND',
-        'DURATION',
-        'DUE',
-        'RRULE',
-        'RDATE',
-        'EXDATE',
-        'STATUS',
-    );
-
-    /**
-     * This method is used to process an incoming itip message.
-     *
-     * Examples:
-     *
-     * 1. A user is an attendee to an event. The organizer sends an updated
-     * meeting using a new iTip message with METHOD:REQUEST. This function
-     * will process the message and update the attendee's event accordingly.
-     *
-     * 2. The organizer cancelled the event using METHOD:CANCEL. We will update
-     * the users event to state STATUS:CANCELLED.
-     *
-     * 3. An attendee sent a reply to an invite using METHOD:REPLY. We can
-     * update the organizers event to update the ATTENDEE with its correct
-     * PARTSTAT.
-     *
-     * The $existingObject is updated in-place. If there is no existing object
-     * (because it's a new invite for example) a new object will be created.
-     *
-     * If an existing object does not exist, and the method was CANCEL or
-     * REPLY, the message effectively gets ignored, and no 'existingObject'
-     * will be created.
-     *
-     * The updated $existingObject is also returned from this function.
-     *
-     * If the iTip message was not supported, we will always return false.
-     *
-     * @param Message $itipMessage
-     * @param VCalendar $existingObject
-     * @return VCalendar|null
-     */
-    public function processMessage(Message $itipMessage, VCalendar $existingObject = null) {
-
-        // We only support events at the moment.
-        if ($itipMessage->component !== 'VEVENT') {
-            return false;
-        }
-
-        switch($itipMessage->method) {
-
-            case 'REQUEST' :
-                return $this->processMessageRequest($itipMessage, $existingObject);
-
-            case 'CANCEL' :
-                return $this->processMessageCancel($itipMessage, $existingObject);
-
-            case 'REPLY' :
-                return $this->processMessageReply($itipMessage, $existingObject);
-
-            default :
-                // Unsupported iTip message
-                return null;
-
-        }
-
-        return $existingObject;
-
-    }
-
-    /**
-     * This function parses a VCALENDAR object and figure out if any messages
-     * need to be sent.
-     *
-     * A VCALENDAR object will be created from the perspective of either an
-     * attendee, or an organizer. You must pass a string identifying the
-     * current user, so we can figure out who in the list of attendees or the
-     * organizer we are sending this message on behalf of.
-     *
-     * It's possible to specify the current user as an array, in case the user
-     * has more than one identifying href (such as multiple emails).
-     *
-     * It $oldCalendar is specified, it is assumed that the operation is
-     * updating an existing event, which means that we need to look at the
-     * differences between events, and potentially send old attendees
-     * cancellations, and current attendees updates.
-     *
-     * If $calendar is null, but $oldCalendar is specified, we treat the
-     * operation as if the user has deleted an event. If the user was an
-     * organizer, this means that we need to send cancellation notices to
-     * people. If the user was an attendee, we need to make sure that the
-     * organizer gets the 'declined' message.
-     *
-     * @param VCalendar|string $calendar
-     * @param string|array $userHref
-     * @param VCalendar|string $oldCalendar
-     * @return array
-     */
-    public function parseEvent($calendar = null, $userHref, $oldCalendar = null) {
-
-        if ($oldCalendar) {
-            if (is_string($oldCalendar)) {
-                $oldCalendar = Reader::read($oldCalendar);
-            }
-            if (!isset($oldCalendar->VEVENT)) {
-                // We only support events at the moment
-                return array();
-            }
-
-            $oldEventInfo = $this->parseEventInfo($oldCalendar);
-        } else {
-            $oldEventInfo = array(
-                'organizer' => null,
-                'significantChangeHash' => '',
-                'attendees' => array(),
-            );
-        }
-
-        $userHref = (array)$userHref;
-
-        if (!is_null($calendar)) {
-
-            if (is_string($calendar)) {
-                $calendar = Reader::read($calendar);
-            }
-            if (!isset($calendar->VEVENT)) {
-                // We only support events at the moment
-                return array();
-            }
-            $eventInfo = $this->parseEventInfo($calendar);
-            if (!$eventInfo['attendees'] && !$oldEventInfo['attendees']) {
-                // If there were no attendees on either side of the equation,
-                // we don't need to do anything.
-                return array();
-            }
-            if (!$eventInfo['organizer'] && !$oldEventInfo['organizer']) {
-                // There was no organizer before or after the change.
-                return array();
-            }
-
-            $baseCalendar = $calendar;
-
-            // If the new object didn't have an organizer, the organizer
-            // changed the object from a scheduling object to a non-scheduling
-            // object. We just copy the info from the old object.
-            if (!$eventInfo['organizer'] && $oldEventInfo['organizer']) {
-                $eventInfo['organizer'] = $oldEventInfo['organizer'];
-                $eventInfo['organizerName'] = $oldEventInfo['organizerName'];
-            }
-
-        } else {
-            // The calendar object got deleted, we need to process this as a
-            // cancellation / decline.
-            if (!$oldCalendar) {
-                // No old and no new calendar, there's no thing to do.
-                return array();
-            }
-
-            $eventInfo = $oldEventInfo;
-
-            if (in_array($eventInfo['organizer'], $userHref)) {
-                // This is an organizer deleting the event.
-                $eventInfo['attendees'] = array();
-                // Increasing the sequence, but only if the organizer deleted
-                // the event.
-                $eventInfo['sequence']++;
-            } else {
-                // This is an attendee deleting the event.
-                foreach($eventInfo['attendees'] as $key=>$attendee) {
-                    if (in_array($attendee['href'], $userHref)) {
-                        $eventInfo['attendees'][$key]['instances'] = array('master' =>
-                            array('id'=>'master', 'partstat' => 'DECLINED')
-                        );
-                    }
-                }
-            }
-            $baseCalendar = $oldCalendar;
-
-        }
-
-        if (in_array($eventInfo['organizer'], $userHref)) {
-            return $this->parseEventForOrganizer($baseCalendar, $eventInfo, $oldEventInfo);
-        } elseif ($oldCalendar) {
-            // We need to figure out if the user is an attendee, but we're only
-            // doing so if there's an oldCalendar, because we only want to
-            // process updates, not creation of new events.
-            foreach($eventInfo['attendees'] as $attendee) {
-                if (in_array($attendee['href'], $userHref)) {
-                    return $this->parseEventForAttendee($baseCalendar, $eventInfo, $oldEventInfo, $attendee['href']);
-                }
-            }
-        }
-        return array();
-
-    }
-
-    /**
-     * Processes incoming REQUEST messages.
-     *
-     * This is message from an organizer, and is either a new event
-     * invite, or an update to an existing one.
-     *
-     *
-     * @param Message $itipMessage
-     * @param VCalendar $existingObject
-     * @return VCalendar|null
-     */
-    protected function processMessageRequest(Message $itipMessage, VCalendar $existingObject = null) {
-
-        if (!$existingObject) {
-            // This is a new invite, and we're just going to copy over
-            // all the components from the invite.
-            $existingObject = new VCalendar();
-            foreach($itipMessage->message->getComponents() as $component) {
-                $existingObject->add(clone $component);
-            }
-        } else {
-            // We need to update an existing object with all the new
-            // information. We can just remove all existing components
-            // and create new ones.
-            foreach($existingObject->getComponents() as $component) {
-                $existingObject->remove($component);
-            }
-            foreach($itipMessage->message->getComponents() as $component) {
-                $existingObject->add(clone $component);
-            }
-        }
-        return $existingObject;
-
-    }
-
-    /**
-     * Processes incoming CANCEL messages.
-     *
-     * This is a message from an organizer, and means that either an
-     * attendee got removed from an event, or an event got cancelled
-     * altogether.
-     *
-     * @param Message $itipMessage
-     * @param VCalendar $existingObject
-     * @return VCalendar|null
-     */
-    protected function processMessageCancel(Message $itipMessage, VCalendar $existingObject = null) {
-
-        if (!$existingObject) {
-            // The event didn't exist in the first place, so we're just
-            // ignoring this message.
-        } else {
-            foreach($existingObject->VEVENT as $vevent) {
-                $vevent->STATUS = 'CANCELLED';
-                $vevent->SEQUENCE = $itipMessage->sequence;
-            }
-        }
-        return $existingObject;
-
-    }
-
-    /**
-     * Processes incoming REPLY messages.
-     *
-     * The message is a reply. This is for example an attendee telling
-     * an organizer he accepted the invite, or declined it.
-     *
-     * @param Message $itipMessage
-     * @param VCalendar $existingObject
-     * @return VCalendar|null
-     */
-    protected function processMessageReply(Message $itipMessage, VCalendar $existingObject = null) {
-
-        // A reply can only be processed based on an existing object.
-        // If the object is not available, the reply is ignored.
-        if (!$existingObject) {
-            return null;
-        }
-        $instances = array();
-        $requestStatus = '2.0';
-
-        // Finding all the instances the attendee replied to.
-        foreach($itipMessage->message->VEVENT as $vevent) {
-            $recurId = isset($vevent->{'RECURRENCE-ID'})?$vevent->{'RECURRENCE-ID'}->getValue():'master';
-            $attendee = $vevent->ATTENDEE;
-            $instances[$recurId] = $attendee['PARTSTAT']->getValue();
-            if (isset($vevent->{'REQUEST-STATUS'})) {
-                $requestStatus = $vevent->{'REQUEST-STATUS'}->getValue();
-                list($requestStatus) = explode(';', $requestStatus);
-            }
-        }
-
-        // Now we need to loop through the original organizer event, to find
-        // all the instances where we have a reply for.
-        $masterObject = null;
-        foreach($existingObject->VEVENT as $vevent) {
-            $recurId = isset($vevent->{'RECURRENCE-ID'})?$vevent->{'RECURRENCE-ID'}->getValue():'master';
-            if ($recurId==='master') {
-                $masterObject = $vevent;
-            }
-            if (isset($instances[$recurId])) {
-                $attendeeFound = false;
-                if (isset($vevent->ATTENDEE)) {
-                    foreach($vevent->ATTENDEE as $attendee) {
-                        if ($attendee->getValue() === $itipMessage->sender) {
-                            $attendeeFound = true;
-                            $attendee['PARTSTAT'] = $instances[$recurId];
-                            $attendee['SCHEDULE-STATUS'] = $requestStatus;
-                            // Un-setting the RSVP status, because we now know
-                            // that the attende already replied.
-                            unset($attendee['RSVP']);
-                            break;
-                        }
-                    }
-                }
-                if (!$attendeeFound) {
-                    // Adding a new attendee. The iTip documentation calls this
-                    // a party crasher.
-                    $attendee = $vevent->add('ATTENDEE', $itipMessage->sender, array(
-                        'PARTSTAT' => $instances[$recurId]
-                    ));
-                    if ($itipMessage->senderName) $attendee['CN'] = $itipMessage->senderName;
-                }
-                unset($instances[$recurId]);
-            }
-        }
-
-        if(!$masterObject) {
-            // No master object, we can't add new instances.
-            return null;
-        }
-        // If we got replies to instances that did not exist in the
-        // original list, it means that new exceptions must be created.
-        foreach($instances as $recurId=>$partstat) {
-
-            $recurrenceIterator = new EventIterator($existingObject, $itipMessage->uid);
-            $found = false;
-            $iterations = 1000;
-            do {
-
-                $newObject = $recurrenceIterator->getEventObject();
-                $recurrenceIterator->next();
-
-                if (isset($newObject->{'RECURRENCE-ID'}) && $newObject->{'RECURRENCE-ID'}->getValue()===$recurId) {
-                    $found = true;
-                }
-                $iterations--;
-
-            } while($recurrenceIterator->valid() && !$found && $iterations);
-
-            // Invalid recurrence id. Skipping this object.
-            if (!$found) continue;
-
-            unset(
-                $newObject->RRULE,
-                $newObject->EXDATE,
-                $newObject->RDATE
-            );
-            $attendeeFound = false;
-            if (isset($newObject->ATTENDEE)) {
-                foreach($newObject->ATTENDEE as $attendee) {
-                    if ($attendee->getValue() === $itipMessage->sender) {
-                        $attendeeFound = true;
-                        $attendee['PARTSTAT'] = $partstat;
-                        break;
-                    }
-                }
-            }
-            if (!$attendeeFound) {
-                // Adding a new attendee
-                $attendee = $newObject->add('ATTENDEE', $itipMessage->sender, array(
-                    'PARTSTAT' => $partstat
-                ));
-                if ($itipMessage->senderName) {
-                    $attendee['CN'] = $itipMessage->senderName;
-                }
-            }
-            $existingObject->add($newObject);
-
-        }
-        return $existingObject;
-
-    }
-
-    /**
-     * This method is used in cases where an event got updated, and we
-     * potentially need to send emails to attendees to let them know of updates
-     * in the events.
-     *
-     * We will detect which attendees got added, which got removed and create
-     * specific messages for these situations.
-     *
-     * @param VCalendar $calendar
-     * @param array $eventInfo
-     * @param array $oldEventInfo
-     * @return array
-     */
-    protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, array $oldEventInfo) {
-
-        // Merging attendee lists.
-        $attendees = array();
-        foreach($oldEventInfo['attendees'] as $attendee) {
-            $attendees[$attendee['href']] = array(
-                'href' => $attendee['href'],
-                'oldInstances' => $attendee['instances'],
-                'newInstances' => array(),
-                'name' => $attendee['name'],
-                'forceSend' => null,
-            );
-        }
-        foreach($eventInfo['attendees'] as $attendee) {
-            if (isset($attendees[$attendee['href']])) {
-                $attendees[$attendee['href']]['name'] = $attendee['name'];
-                $attendees[$attendee['href']]['newInstances'] = $attendee['instances'];
-                $attendees[$attendee['href']]['forceSend'] = $attendee['forceSend'];
-            } else {
-                $attendees[$attendee['href']] = array(
-                    'href' => $attendee['href'],
-                    'oldInstances' => array(),
-                    'newInstances' => $attendee['instances'],
-                    'name' => $attendee['name'],
-                    'forceSend' => $attendee['forceSend'],
-                );
-            }
-        }
-
-        $messages = array();
-
-        foreach($attendees as $attendee) {
-
-            // An organizer can also be an attendee. We should not generate any
-            // messages for those.
-            if ($attendee['href']===$eventInfo['organizer']) {
-                continue;
-            }
-
-            $message = new Message();
-            $message->uid = $eventInfo['uid'];
-            $message->component = 'VEVENT';
-            $message->sequence = $eventInfo['sequence'];
-            $message->sender = $eventInfo['organizer'];
-            $message->senderName = $eventInfo['organizerName'];
-            $message->recipient = $attendee['href'];
-            $message->recipientName = $attendee['name'];
-
-            if (!$attendee['newInstances']) {
-
-                // If there are no instances the attendee is a part of, it
-                // means the attendee was removed and we need to send him a
-                // CANCEL.
-                $message->method = 'CANCEL';
-
-                // Creating the new iCalendar body.
-                $icalMsg = new VCalendar();
-                $icalMsg->METHOD = $message->method;
-                $event = $icalMsg->add('VEVENT', array(
-                    'UID' => $message->uid,
-                    'SEQUENCE' => $message->sequence,
-                ));
-                if (isset($calendar->VEVENT->SUMMARY)) {
-                    $event->add('SUMMARY', $calendar->VEVENT->SUMMARY->getValue());
-                }
-                $event->add(clone $calendar->VEVENT->DTSTART);
-                $org = $event->add('ORGANIZER', $eventInfo['organizer']);
-                if ($eventInfo['organizerName']) $org['CN'] = $eventInfo['organizerName'];
-                $event->add('ATTENDEE', $attendee['href'], array(
-                    'CN' => $attendee['name'],
-                ));
-                $message->significantChange = true;
-
-            } else {
-
-                // The attendee gets the updated event body
-                $message->method = 'REQUEST';
-
-                // Creating the new iCalendar body.
-                $icalMsg = new VCalendar();
-                $icalMsg->METHOD = $message->method;
-
-                foreach($calendar->select('VTIMEZONE') as $timezone) {
-                    $icalMsg->add(clone $timezone);
-                }
-
-                // We need to find out that this change is significant. If it's
-                // not, systems may opt to not send messages.
-                //
-                // We do this based on the 'significantChangeHash' which is
-                // some value that changes if there's a certain set of
-                // properties changed in the event, or simply if there's a
-                // difference in instances that the attendee is invited to.
-
-                $message->significantChange =
-                    $attendee['forceSend'] === 'REQUEST' ||
-                    array_keys($attendee['oldInstances']) != array_keys($attendee['newInstances']) ||
-                    $oldEventInfo['significantChangeHash']!==$eventInfo['significantChangeHash'];
-
-                foreach($attendee['newInstances'] as $instanceId => $instanceInfo) {
-
-                    $currentEvent = clone $eventInfo['instances'][$instanceId];
-                    if ($instanceId === 'master') {
-
-                        // We need to find a list of events that the attendee
-                        // is not a part of to add to the list of exceptions.
-                        $exceptions = array();
-                        foreach($eventInfo['instances'] as $instanceId=>$vevent) {
-                            if (!isset($attendee['newInstances'][$instanceId])) {
-                                $exceptions[] = $instanceId;
-                            }
-                        }
-
-                        // If there were exceptions, we need to add it to an
-                        // existing EXDATE property, if it exists.
-                        if ($exceptions) {
-                            if (isset($currentEvent->EXDATE)) {
-                                $currentEvent->EXDATE->setParts(array_merge(
-                                    $currentEvent->EXDATE->getParts(),
-                                    $exceptions
-                                ));
-                            } else {
-                                $currentEvent->EXDATE = $exceptions;
-                            }
-                        }
-
-                        // Cleaning up any scheduling information that
-                        // shouldn't be sent along.
-                        unset($currentEvent->ORGANIZER['SCHEDULE-FORCE-SEND']);
-                        unset($currentEvent->ORGANIZER['SCHEDULE-STATUS']);
-
-                        foreach($currentEvent->ATTENDEE as $attendee) {
-                            unset($attendee['SCHEDULE-FORCE-SEND']);
-                            unset($attendee['SCHEDULE-STATUS']);
-
-                            // We're adding PARTSTAT=NEEDS-ACTION to ensure that
-                            // iOS shows an "Inbox Item"
-                            if (!isset($attendee['PARTSTAT'])) {
-                                $attendee['PARTSTAT'] = 'NEEDS-ACTION';
-                            }
-
-                        }
-
-                    }
-
-                    $icalMsg->add($currentEvent);
-
-                }
-
-            }
-
-            $message->message = $icalMsg;
-            $messages[] = $message;
-
-        }
-
-        return $messages;
-
-    }
-
-    /**
-     * Parse an event update for an attendee.
-     *
-     * This function figures out if we need to send a reply to an organizer.
-     *
-     * @param VCalendar $calendar
-     * @param array $eventInfo
-     * @param array $oldEventInfo
-     * @param string $attendee
-     * @return Message[]
-     */
-    protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, $attendee) {
-
-        if ($this->scheduleAgentServerRules && $eventInfo['organizerScheduleAgent']==='CLIENT') {
-            return array();
-        }
-
-        // Don't bother generating messages for events that have already been
-        // cancelled.
-        if ($eventInfo['status']==='CANCELLED') {
-            return array();
-        }
-
-        $instances = array();
-        foreach($oldEventInfo['attendees'][$attendee]['instances'] as $instance) {
-
-            $instances[$instance['id']] = array(
-                'id' => $instance['id'],
-                'oldstatus' => $instance['partstat'],
-                'newstatus' => null,
-            );
-
-        }
-        foreach($eventInfo['attendees'][$attendee]['instances'] as $instance) {
-
-            if (isset($instances[$instance['id']])) {
-                $instances[$instance['id']]['newstatus'] = $instance['partstat'];
-            } else {
-                $instances[$instance['id']] = array(
-                    'id' => $instance['id'],
-                    'oldstatus' => null,
-                    'newstatus' => $instance['partstat'],
-                );
-            }
-
-        }
-
-        // We need to also look for differences in EXDATE. If there are new
-        // items in EXDATE, it means that an attendee deleted instances of an
-        // event, which means we need to send DECLINED specifically for those
-        // instances.
-        // We only need to do that though, if the master event is not declined.
-        if ($instances['master']['newstatus'] !== 'DECLINED') {
-            foreach($eventInfo['exdate'] as $exDate) {
-
-                if (!in_array($exDate, $oldEventInfo['exdate'])) {
-                    if (isset($instances[$exDate])) {
-                        $instances[$exDate]['newstatus'] = 'DECLINED';
-                    } else {
-                        $instances[$exDate] = array(
-                            'id' => $exDate,
-                            'oldstatus' => null,
-                            'newstatus' => 'DECLINED',
-                        );
-                    }
-                }
-
-            }
-        }
-
-        // Gathering a few extra properties for each instance.
-        foreach($instances as $recurId=>$instanceInfo) {
-
-            if (isset($eventInfo['instances'][$recurId])) {
-                $instances[$recurId]['dtstart'] = clone $eventInfo['instances'][$recurId]->DTSTART;
-            } else {
-                $instances[$recurId]['dtstart'] = $recurId;
-            }
-
-        }
-
-        $message = new Message();
-        $message->uid = $eventInfo['uid'];
-        $message->method = 'REPLY';
-        $message->component = 'VEVENT';
-        $message->sequence = $eventInfo['sequence'];
-        $message->sender = $attendee;
-        $message->senderName = $eventInfo['attendees'][$attendee]['name'];
-        $message->recipient = $eventInfo['organizer'];
-        $message->recipientName = $eventInfo['organizerName'];
-
-        $icalMsg = new VCalendar();
-        $icalMsg->METHOD = 'REPLY';
-
-        $hasReply = false;
-
-        foreach($instances as $instance) {
-
-            if ($instance['oldstatus']==$instance['newstatus'] && $eventInfo['organizerForceSend'] !== 'REPLY') {
-                // Skip
-                continue;
-            }
-
-            $event = $icalMsg->add('VEVENT', array(
-                'UID' => $message->uid,
-                'SEQUENCE' => $message->sequence,
-            ));
-            $summary = isset($calendar->VEVENT->SUMMARY)?$calendar->VEVENT->SUMMARY->getValue():'';
-            // Adding properties from the correct source instance
-            if (isset($eventInfo['instances'][$instance['id']])) {
-                $instanceObj = $eventInfo['instances'][$instance['id']];
-                $event->add(clone $instanceObj->DTSTART);
-                if (isset($instanceObj->SUMMARY)) {
-                    $event->add('SUMMARY', $instanceObj->SUMMARY->getValue());
-                } elseif ($summary) {
-                    $event->add('SUMMARY', $summary);
-                }
-            } else {
-                // This branch of the code is reached, when a reply is
-                // generated for an instance of a recurring event, through the
-                // fact that the instance has disappeared by showing up in
-                // EXDATE
-                $dt = DateTimeParser::parse($instance['id'], $eventInfo['timezone']);
-                // Treat is as a DATE field
-                if (strlen($instance['id']) <= 8) {
-                    $recur = $event->add('DTSTART', $dt, array('VALUE' => 'DATE'));
-                } else {
-                    $recur = $event->add('DTSTART', $dt);
-                }
-                if ($summary) {
-                    $event->add('SUMMARY', $summary);
-                }
-            }
-            if ($instance['id'] !== 'master') {
-                $dt = DateTimeParser::parse($instance['id'], $eventInfo['timezone']);
-                // Treat is as a DATE field
-                if (strlen($instance['id']) <= 8) {
-                    $recur = $event->add('RECURRENCE-ID', $dt, array('VALUE' => 'DATE'));
-                } else {
-                    $recur = $event->add('RECURRENCE-ID', $dt);
-                }
-            }
-            $organizer = $event->add('ORGANIZER', $message->recipient);
-            if ($message->recipientName) {
-                $organizer['CN'] = $message->recipientName;
-            }
-            $attendee = $event->add('ATTENDEE', $message->sender, array(
-                'PARTSTAT' => $instance['newstatus']
-            ));
-            if ($message->senderName) {
-                $attendee['CN'] = $message->senderName;
-            }
-            $hasReply = true;
-
-        }
-
-        if ($hasReply) {
-            $message->message = $icalMsg;
-            return array($message);
-        } else {
-            return array();
-        }
-
-    }
-
-    /**
-     * Returns attendee information and information about instances of an
-     * event.
-     *
-     * Returns an array with the following keys:
-     *
-     * 1. uid
-     * 2. organizer
-     * 3. organizerName
-     * 4. attendees
-     * 5. instances
-     *
-     * @param VCalendar $calendar
-     * @return array
-     */
-    protected function parseEventInfo(VCalendar $calendar = null) {
-
-        $uid = null;
-        $organizer = null;
-        $organizerName = null;
-        $organizerForceSend = null;
-        $sequence = null;
-        $timezone = null;
-        $status = null;
-        $organizerScheduleAgent = 'SERVER';
-
-        $significantChangeHash = '';
-
-        // Now we need to collect a list of attendees, and which instances they
-        // are a part of.
-        $attendees = array();
-
-        $instances = array();
-        $exdate = array();
-
-        foreach($calendar->VEVENT as $vevent) {
-
-            if (is_null($uid)) {
-                $uid = $vevent->UID->getValue();
-            } else {
-                if ($uid !== $vevent->UID->getValue()) {
-                    throw new ITipException('If a calendar contained more than one event, they must have the same UID.');
-                }
-            }
-
-            if (!isset($vevent->DTSTART)) {
-                throw new ITipException('An event MUST have a DTSTART property.');
-            }
-
-            if (isset($vevent->ORGANIZER)) {
-                if (is_null($organizer)) {
-                    $organizer = $vevent->ORGANIZER->getNormalizedValue();
-                    $organizerName = isset($vevent->ORGANIZER['CN'])?$vevent->ORGANIZER['CN']:null;
-                } else {
-                    if ($organizer !== $vevent->ORGANIZER->getNormalizedValue()) {
-                        throw new SameOrganizerForAllComponentsException('Every instance of the event must have the same organizer.');
-                    }
-                }
-                $organizerForceSend =
-                    isset($vevent->ORGANIZER['SCHEDULE-FORCE-SEND']) ?
-                    strtoupper($vevent->ORGANIZER['SCHEDULE-FORCE-SEND']) :
-                    null;
-                $organizerScheduleAgent =
-                    isset($vevent->ORGANIZER['SCHEDULE-AGENT']) ?
-                    strtoupper((string)$vevent->ORGANIZER['SCHEDULE-AGENT']) :
-                    'SERVER';
-            }
-            if (is_null($sequence) && isset($vevent->SEQUENCE)) {
-                $sequence = $vevent->SEQUENCE->getValue();
-            }
-            if (isset($vevent->EXDATE)) {
-                $exdate = $vevent->EXDATE->getParts();
-            }
-            if (isset($vevent->STATUS)) {
-                $status = strtoupper($vevent->STATUS->getValue());
-            }
-
-            $recurId = isset($vevent->{'RECURRENCE-ID'})?$vevent->{'RECURRENCE-ID'}->getValue():'master';
-            if ($recurId==='master') {
-                $timezone = $vevent->DTSTART->getDateTime()->getTimeZone();
-            }
-            if(isset($vevent->ATTENDEE)) {
-                foreach($vevent->ATTENDEE as $attendee) {
-
-                    if ($this->scheduleAgentServerRules &&
-                        isset($attendee['SCHEDULE-AGENT']) &&
-                        strtoupper($attendee['SCHEDULE-AGENT']->getValue()) === 'CLIENT'
-                    ) {
-                        continue;
-                    }
-                    $partStat =
-                        isset($attendee['PARTSTAT']) ?
-                        strtoupper($attendee['PARTSTAT']) :
-                        'NEEDS-ACTION';
-
-                    $forceSend =
-                        isset($attendee['SCHEDULE-FORCE-SEND']) ?
-                        strtoupper($attendee['SCHEDULE-FORCE-SEND']) :
-                        null;
-
-
-                    if (isset($attendees[$attendee->getNormalizedValue()])) {
-                        $attendees[$attendee->getNormalizedValue()]['instances'][$recurId] = array(
-                            'id' => $recurId,
-                            'partstat' => $partStat,
-                            'force-send' => $forceSend,
-                        );
-                    } else {
-                        $attendees[$attendee->getNormalizedValue()] = array(
-                            'href' => $attendee->getNormalizedValue(),
-                            'instances' => array(
-                                $recurId => array(
-                                    'id' => $recurId,
-                                    'partstat' => $partStat,
-                                ),
-                            ),
-                            'name' => isset($attendee['CN'])?(string)$attendee['CN']:null,
-                            'forceSend' => $forceSend,
-                        );
-                    }
-
-                }
-                $instances[$recurId] = $vevent;
-
-            }
-
-            foreach($this->significantChangeProperties as $prop) {
-                if (isset($vevent->$prop)) {
-                    $significantChangeHash.=$prop.':';
-                    foreach($vevent->select($prop) as $val) {
-                        $significantChangeHash.= $val->getValue().';';
-                    }
-                }
-            }
-
-        }
-        $significantChangeHash = md5($significantChangeHash);
-
-        return compact(
-            'uid',
-            'organizer',
-            'organizerName',
-            'organizerScheduleAgent',
-            'organizerForceSend',
-            'instances',
-            'attendees',
-            'sequence',
-            'exdate',
-            'timezone',
-            'significantChangeHash',
-            'status'
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/ITip/ITipException.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-use Exception;
-
-/**
- * This message is emitted in case of serious problems with iTip messages.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class ITipException extends Exception {
-}
--- a/vendor/sabre/vobject/lib/ITip/Message.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-/**
- * This class represents an iTip message
- *
- * A message holds all the information relevant to the message, including the
- * object itself.
- *
- * It should for the most part be treated as immutable.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Message {
-
-    /**
-     * The object's UID
-     *
-     * @var string
-     */
-    public $uid;
-
-    /**
-     * The component type, such as VEVENT
-     *
-     * @var string
-     */
-    public $component;
-
-    /**
-     * Contains the ITip method, which is something like REQUEST, REPLY or
-     * CANCEL.
-     *
-     * @var string
-     */
-    public $method;
-
-    /**
-     * The current sequence number for the event.
-     *
-     * @var int
-     */
-    public $sequence;
-
-    /**
-     * The senders' email address.
-     *
-     * Note that this does not imply that this has to be used in a From: field
-     * if the message is sent by email. It may also be populated in Reply-To:
-     * or not at all.
-     *
-     * @var string
-     */
-    public $sender;
-
-    /**
-     * The name of the sender. This is often populated from a CN parameter from
-     * either the ORGANIZER or ATTENDEE, depending on the message.
-     *
-     * @var string|null
-     */
-    public $senderName;
-
-    /**
-     * The recipient's email address.
-     *
-     * @var string
-     */
-    public $recipient;
-
-    /**
-     * The name of the recipient. This is usually populated with the CN
-     * parameter from the ATTENDEE or ORGANIZER property, if it's available.
-     *
-     * @var string|null
-     */
-    public $recipientName;
-
-    /**
-     * After the message has been delivered, this should contain a string such
-     * as : 1.1;Sent or 1.2;Delivered.
-     *
-     * In case of a failure, this will hold the error status code.
-     *
-     * See:
-     * http://tools.ietf.org/html/rfc6638#section-7.3
-     *
-     * @var string
-     */
-    public $scheduleStatus;
-
-    /**
-     * The iCalendar / iTip body.
-     *
-     * @var \Sabre\VObject\Component\VCalendar
-     */
-    public $message;
-
-    /**
-     * This will be set to true, if the iTip broker considers the change
-     * 'significant'.
-     *
-     * In practice, this means that we'll only mark it true, if for instance
-     * DTSTART changed. This allows systems to only send iTip messages when
-     * significant changes happened. This is especially useful for iMip, as
-     * normally a ton of messages may be generated for normal calendar use.
-     *
-     * To see the list of properties that are considered 'significant', check
-     * out Sabre\VObject\ITip\Broker::$significantChangeProperties.
-     *
-     * @var bool
-     */
-    public $significantChange = true;
-
-    /**
-     * Returns the schedule status as a string.
-     *
-     * For example:
-     * 1.2
-     *
-     * @return mixed bool|string
-     */
-    public function getScheduleStatus() {
-
-        if(!$this->scheduleStatus) {
-
-            return false;
-
-        } else {
-
-            list($scheduleStatus) = explode(';', $this->scheduleStatus);
-            return $scheduleStatus;
-
-        }
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-/**
- * SameOrganizerForAllComponentsException
- *
- * This exception is emitted when an event is encountered with more than one
- * component (e.g.: exceptions), but the organizer is not identical in every
- * component.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class SameOrganizerForAllComponentsException extends ITipException {
-
-}
--- a/vendor/sabre/vobject/lib/Node.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * A node is the root class for every element in an iCalendar of vCard object.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-abstract class Node implements \IteratorAggregate, \ArrayAccess, \Countable {
-
-    /**
-     * The following constants are used by the validate() method.
-     *
-     * If REPAIR is set, the validator will attempt to repair any broken data
-     * (if possible).
-     */
-    const REPAIR = 1;
-
-    /**
-     * If this option is set, the validator will operate on the vcards on the
-     * assumption that the vcards need to be valid for CardDAV.
-     *
-     * This means for example that the UID is required, whereas it is not for
-     * regular vcards.
-     */
-    const PROFILE_CARDDAV = 2;
-
-    /**
-     * If this option is set, the validator will operate on iCalendar objects
-     * on the assumption that the vcards need to be valid for CalDAV.
-     *
-     * This means for example that calendars can only contain objects with
-     * identical component types and UIDs.
-     */
-    const PROFILE_CALDAV = 4;
-
-    /**
-     * Reference to the parent object, if this is not the top object.
-     *
-     * @var Node
-     */
-    public $parent;
-
-    /**
-     * Iterator override
-     *
-     * @var ElementList
-     */
-    protected $iterator = null;
-
-    /**
-     * The root document
-     *
-     * @var Component
-     */
-    protected $root;
-
-    /**
-     * Serializes the node into a mimedir format
-     *
-     * @return string
-     */
-    abstract public function serialize();
-
-    /**
-     * This method returns an array, with the representation as it should be
-     * encoded in json. This is used to create jCard or jCal documents.
-     *
-     * @return array
-     */
-    abstract public function jsonSerialize();
-
-    /* {{{ IteratorAggregator interface */
-
-    /**
-     * Returns the iterator for this object
-     *
-     * @return ElementList
-     */
-    public function getIterator() {
-
-        if (!is_null($this->iterator))
-            return $this->iterator;
-
-        return new ElementList(array($this));
-
-    }
-
-    /**
-     * Sets the overridden iterator
-     *
-     * Note that this is not actually part of the iterator interface
-     *
-     * @param ElementList $iterator
-     * @return void
-     */
-    public function setIterator(ElementList $iterator) {
-
-        $this->iterator = $iterator;
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
-     *   2 - An inconsequential issue
-     *   3 - A severe issue.
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        return array();
-
-    }
-
-    /* }}} */
-
-    /* {{{ Countable interface */
-
-    /**
-     * Returns the number of elements
-     *
-     * @return int
-     */
-    public function count() {
-
-        $it = $this->getIterator();
-        return $it->count();
-
-    }
-
-    /* }}} */
-
-    /* {{{ ArrayAccess Interface */
-
-
-    /**
-     * Checks if an item exists through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return bool
-     */
-    public function offsetExists($offset) {
-
-        $iterator = $this->getIterator();
-        return $iterator->offsetExists($offset);
-
-    }
-
-    /**
-     * Gets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return mixed
-     */
-    public function offsetGet($offset) {
-
-        $iterator = $this->getIterator();
-        return $iterator->offsetGet($offset);
-
-    }
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($offset, $value) {
-
-        $iterator = $this->getIterator();
-        $iterator->offsetSet($offset,$value);
-
-    // @codeCoverageIgnoreStart
-    //
-    // This method always throws an exception, so we ignore the closing
-    // brace
-    }
-    // @codeCoverageIgnoreEnd
-
-    /**
-     * Sets an item through ArrayAccess.
-     *
-     * This method just forwards the request to the inner iterator
-     *
-     * @param int $offset
-     * @return void
-     */
-    public function offsetUnset($offset) {
-
-        $iterator = $this->getIterator();
-        $iterator->offsetUnset($offset);
-
-    // @codeCoverageIgnoreStart
-    //
-    // This method always throws an exception, so we ignore the closing
-    // brace
-    }
-    // @codeCoverageIgnoreEnd
-
-    /* }}} */
-}
--- a/vendor/sabre/vobject/lib/Parameter.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    ArrayObject;
-
-/**
- * VObject Parameter
- *
- * This class represents a parameter. A parameter is always tied to a property.
- * In the case of:
- *   DTSTART;VALUE=DATE:20101108
- * VALUE=DATE would be the parameter name and value.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Parameter extends Node {
-
-    /**
-     * Parameter name
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * vCard 2.1 allows parameters to be encoded without a name.
-     *
-     * We can deduce the parameter name based on it's value.
-     *
-     * @var bool
-     */
-    public $noName = false;
-
-    /**
-     * Parameter value
-     *
-     * @var string
-     */
-    protected $value;
-
-    /**
-     * Sets up the object.
-     *
-     * It's recommended to use the create:: factory method instead.
-     *
-     * @param string $name
-     * @param string $value
-     */
-    public function __construct(Document $root, $name, $value = null) {
-
-        $this->name = strtoupper($name);
-        $this->root = $root;
-        if (is_null($name)) {
-            $this->noName = true;
-            $this->name = static::guessParameterNameByValue($value);
-        }
-
-        // If guessParameterNameByValue() returns an empty string
-        // above, we're actually dealing with a parameter that has no value.
-        // In that case we have to move the value to the name.
-        if ($this->name === '') {
-            $this->noName = false;
-            $this->name = strtoupper($value);
-        } else {
-            $this->setValue($value);
-        }
-
-    }
-
-    /**
-     * Try to guess property name by value, can be used for vCard 2.1 nameless parameters.
-     *
-     * Figuring out what the name should have been. Note that a ton of
-     * these are rather silly in 2014 and would probably rarely be
-     * used, but we like to be complete.
-     *
-     * @param string $value
-     * @return string
-     */
-    public static function guessParameterNameByValue($value) {
-        switch(strtoupper($value)) {
-
-            // Encodings
-            case '7-BIT' :
-            case 'QUOTED-PRINTABLE' :
-            case 'BASE64' :
-                $name = 'ENCODING';
-                break;
-
-            // Common types
-            case 'WORK' :
-            case 'HOME' :
-            case 'PREF' :
-
-                // Delivery Label Type
-            case 'DOM' :
-            case 'INTL' :
-            case 'POSTAL' :
-            case 'PARCEL' :
-
-                // Telephone types
-            case 'VOICE' :
-            case 'FAX' :
-            case 'MSG' :
-            case 'CELL' :
-            case 'PAGER' :
-            case 'BBS' :
-            case 'MODEM' :
-            case 'CAR' :
-            case 'ISDN' :
-            case 'VIDEO' :
-
-                // EMAIL types (lol)
-            case 'AOL' :
-            case 'APPLELINK' :
-            case 'ATTMAIL' :
-            case 'CIS' :
-            case 'EWORLD' :
-            case 'INTERNET' :
-            case 'IBMMAIL' :
-            case 'MCIMAIL' :
-            case 'POWERSHARE' :
-            case 'PRODIGY' :
-            case 'TLX' :
-            case 'X400' :
-
-                // Photo / Logo format types
-            case 'GIF' :
-            case 'CGM' :
-            case 'WMF' :
-            case 'BMP' :
-            case 'DIB' :
-            case 'PICT' :
-            case 'TIFF' :
-            case 'PDF ':
-            case 'PS' :
-            case 'JPEG' :
-            case 'MPEG' :
-            case 'MPEG2' :
-            case 'AVI' :
-            case 'QTIME' :
-
-                // Sound Digital Audio Type
-            case 'WAVE' :
-            case 'PCM' :
-            case 'AIFF' :
-
-                // Key types
-            case 'X509' :
-            case 'PGP' :
-                $name = 'TYPE';
-                break;
-
-            // Value types
-            case 'INLINE' :
-            case 'URL' :
-            case 'CONTENT-ID' :
-            case 'CID' :
-                $name = 'VALUE';
-                break;
-
-            default:
-                $name = '';
-        }
-
-        return $name;
-    }
-
-    /**
-     * Updates the current value.
-     *
-     * This may be either a single, or multiple strings in an array.
-     *
-     * @param string|array $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        $this->value = $value;
-
-    }
-
-    /**
-     * Returns the current value
-     *
-     * This method will always return a string, or null. If there were multiple
-     * values, it will automatically concatinate them (separated by comma).
-     *
-     * @return string|null
-     */
-    public function getValue() {
-
-        if (is_array($this->value)) {
-            return implode(',' , $this->value);
-        } else {
-            return $this->value;
-        }
-
-    }
-
-    /**
-     * Sets multiple values for this parameter.
-     *
-     * @param array $value
-     * @return void
-     */
-    public function setParts(array $value) {
-
-        $this->value = $value;
-
-    }
-
-    /**
-     * Returns all values for this parameter.
-     *
-     * If there were no values, an empty array will be returned.
-     *
-     * @return array
-     */
-    public function getParts() {
-
-        if (is_array($this->value)) {
-            return $this->value;
-        } elseif (is_null($this->value)) {
-            return array();
-        } else {
-            return array($this->value);
-        }
-
-    }
-
-    /**
-     * Adds a value to this parameter
-     *
-     * If the argument is specified as an array, all items will be added to the
-     * parameter value list.
-     *
-     * @param string|array $part
-     * @return void
-     */
-    public function addValue($part) {
-
-        if (is_null($this->value)) {
-            $this->value = $part;
-        } else {
-            $this->value = array_merge((array)$this->value, (array)$part);
-        }
-
-    }
-
-    /**
-     * Checks if this parameter contains the specified value.
-     *
-     * This is a case-insensitive match. It makes sense to call this for for
-     * instance the TYPE parameter, to see if it contains a keyword such as
-     * 'WORK' or 'FAX'.
-     *
-     * @param string $value
-     * @return bool
-     */
-    public function has($value) {
-
-        return in_array(
-            strtolower($value),
-            array_map('strtolower', (array)$this->value)
-        );
-
-    }
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    public function serialize() {
-
-        $value = $this->getParts();
-
-        if (count($value)===0) {
-            return $this->name . '=';
-        }
-
-        if ($this->root->getDocumentType() === Document::VCARD21 && $this->noName) {
-
-            return implode(';', $value);
-
-        }
-
-        return $this->name . '=' . array_reduce(
-            $value,
-            function($out, $item) {
-
-                if (!is_null($out)) $out.=',';
-
-                // If there's no special characters in the string, we'll use the simple
-                // format.
-                //
-                // The list of special characters is defined as:
-                //
-                // Any character except CONTROL, DQUOTE, ";", ":", ","
-                //
-                // by the iCalendar spec:
-                // https://tools.ietf.org/html/rfc5545#section-3.1
-                //
-                // And we add ^ to that because of:
-                // https://tools.ietf.org/html/rfc6868
-                //
-                // But we've found that iCal (7.0, shipped with OSX 10.9)
-                // severaly trips on + characters not being quoted, so we
-                // added + as well.
-                if (!preg_match('#(?: [\n":;\^,\+] )#x', $item)) {
-                    return $out.$item;
-                } else {
-                    // Enclosing in double-quotes, and using RFC6868 for encoding any
-                    // special characters
-                    $out.='"' . strtr(
-                        $item,
-                        array(
-                            '^'  => '^^',
-                            "\n" => '^n',
-                            '"'  => '^\'',
-                        )
-                    ) . '"';
-                    return $out;
-                }
-
-            }
-        );
-
-    }
-
-    /**
-     * This method returns an array, with the representation as it should be
-     * encoded in json. This is used to create jCard or jCal documents.
-     *
-     * @return array
-     */
-    public function jsonSerialize() {
-
-        return $this->value;
-
-    }
-
-    /**
-     * Called when this object is being cast to a string
-     *
-     * @return string
-     */
-    public function __toString() {
-
-        return (string)$this->getValue();
-
-    }
-
-    /**
-     * Returns the iterator for this object
-     *
-     * @return ElementList
-     */
-    public function getIterator() {
-
-        if (!is_null($this->iterator))
-            return $this->iterator;
-
-        return $this->iterator = new ArrayObject((array)$this->value);
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/ParseException.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Exception thrown by Reader if an invalid object was attempted to be parsed.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class ParseException extends \Exception {
-}
--- a/vendor/sabre/vobject/lib/Parser/Json.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Parser;
-
-use
-    Sabre\VObject\Component\VCalendar,
-    Sabre\VObject\Component\VCard,
-    Sabre\VObject\ParseException,
-    Sabre\VObject\EofException;
-
-/**
- * Json Parser.
- *
- * This parser parses both the jCal and jCard formats.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Json extends Parser {
-
-    /**
-     * The input data
-     *
-     * @var array
-     */
-    protected $input;
-
-    /**
-     * Root component
-     *
-     * @var Document
-     */
-    protected $root;
-
-    /**
-     * This method starts the parsing process.
-     *
-     * If the input was not supplied during construction, it's possible to pass
-     * it here instead.
-     *
-     * If either input or options are not supplied, the defaults will be used.
-     *
-     * @param resource|string|array|null $input
-     * @param int|null $options
-     * @return array
-     */
-    public function parse($input = null, $options = null) {
-
-        if (!is_null($input)) {
-            $this->setInput($input);
-        }
-        if (is_null($this->input)) {
-            throw new EofException('End of input stream, or no input supplied');
-        }
-
-        if (!is_null($options)) {
-            $this->options = $options;
-        }
-
-        switch($this->input[0]) {
-            case 'vcalendar' :
-                $this->root = new VCalendar(array(), false);
-                break;
-            case 'vcard' :
-                $this->root = new VCard(array(), false);
-                break;
-            default :
-                throw new ParseException('The root component must either be a vcalendar, or a vcard');
-
-        }
-        foreach($this->input[1] as $prop) {
-            $this->root->add($this->parseProperty($prop));
-        }
-        if (isset($this->input[2])) foreach($this->input[2] as $comp) {
-            $this->root->add($this->parseComponent($comp));
-        }
-
-        // Resetting the input so we can throw an feof exception the next time.
-        $this->input = null;
-
-        return $this->root;
-
-    }
-
-    /**
-     * Parses a component
-     *
-     * @param array $jComp
-     * @return \Sabre\VObject\Component
-     */
-    public function parseComponent(array $jComp) {
-
-        // We can remove $self from PHP 5.4 onward.
-        $self = $this;
-
-        $properties = array_map(
-            function($jProp) use ($self) {
-                return $self->parseProperty($jProp);
-            },
-            $jComp[1]
-        );
-
-        if (isset($jComp[2])) {
-
-            $components = array_map(
-                function($jComp) use ($self) {
-                    return $self->parseComponent($jComp);
-                },
-                $jComp[2]
-            );
-
-        } else $components = array();
-
-        return $this->root->createComponent(
-            $jComp[0],
-            array_merge($properties, $components),
-            $defaults = false
-        );
-
-    }
-
-    /**
-     * Parses properties.
-     *
-     * @param array $jProp
-     * @return \Sabre\VObject\Property
-     */
-    public function parseProperty(array $jProp) {
-
-        list(
-            $propertyName,
-            $parameters,
-            $valueType
-        ) = $jProp;
-
-        $propertyName = strtoupper($propertyName);
-
-        // This is the default class we would be using if we didn't know the
-        // value type. We're using this value later in this function.
-        $defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName);
-
-        $parameters = (array)$parameters;
-
-        $value = array_slice($jProp, 3);
-
-        $valueType = strtoupper($valueType);
-
-        if (isset($parameters['group'])) {
-            $propertyName = $parameters['group'] . '.' . $propertyName;
-            unset($parameters['group']);
-        }
-
-        $prop = $this->root->createProperty($propertyName, null, $parameters, $valueType);
-        $prop->setJsonValue($value);
-
-        // We have to do something awkward here. FlatText as well as Text
-        // represents TEXT values. We have to normalize these here. In the
-        // future we can get rid of FlatText once we're allowed to break BC
-        // again.
-        if ($defaultPropertyClass === 'Sabre\VObject\Property\FlatText') {
-            $defaultPropertyClass = 'Sabre\VObject\Property\Text';
-        }
-
-        // If the value type we received (e.g.: TEXT) was not the default value
-        // type for the given property (e.g.: BDAY), we need to add a VALUE=
-        // parameter.
-        if ($defaultPropertyClass !== get_class($prop)) {
-            $prop["VALUE"] = $valueType;
-        }
-
-        return $prop;
-
-    }
-
-    /**
-     * Sets the input data
-     *
-     * @param resource|string|array $input
-     * @return void
-     */
-    public function setInput($input) {
-
-        if (is_resource($input)) {
-            $input = stream_get_contents($input);
-        }
-        if (is_string($input)) {
-            $input = json_decode($input);
-        }
-        $this->input = $input;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Parser/MimeDir.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,628 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Parser;
-
-use
-    Sabre\VObject\ParseException,
-    Sabre\VObject\EofException,
-    Sabre\VObject\Component,
-    Sabre\VObject\Property,
-    Sabre\VObject\Component\VCalendar,
-    Sabre\VObject\Component\VCard;
-
-/**
- * MimeDir parser.
- *
- * This class parses iCalendar 2.0 and vCard 2.1, 3.0 and 4.0 files. This
- * parser will return one of the following two objects from the parse method:
- *
- * Sabre\VObject\Component\VCalendar
- * Sabre\VObject\Component\VCard
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class MimeDir extends Parser {
-
-    /**
-     * The input stream.
-     *
-     * @var resource
-     */
-    protected $input;
-
-    /**
-     * Root component
-     *
-     * @var Component
-     */
-    protected $root;
-
-    /**
-     * Parses an iCalendar or vCard file
-     *
-     * Pass a stream or a string. If null is parsed, the existing buffer is
-     * used.
-     *
-     * @param string|resource|null $input
-     * @param int|null $options
-     * @return array
-     */
-    public function parse($input = null, $options = null) {
-
-        $this->root = null;
-        if (!is_null($input)) {
-
-            $this->setInput($input);
-
-        }
-
-        if (!is_null($options)) $this->options = $options;
-
-        $this->parseDocument();
-
-        return $this->root;
-
-    }
-
-    /**
-     * Sets the input buffer. Must be a string or stream.
-     *
-     * @param resource|string $input
-     * @return void
-     */
-    public function setInput($input) {
-
-        // Resetting the parser
-        $this->lineIndex = 0;
-        $this->startLine = 0;
-
-        if (is_string($input)) {
-            // Convering to a stream.
-            $stream = fopen('php://temp', 'r+');
-            fwrite($stream, $input);
-            rewind($stream);
-            $this->input = $stream;
-        } elseif (is_resource($input)) {
-            $this->input = $input;
-        } else {
-            throw new \InvalidArgumentException('This parser can only read from strings or streams.');
-        }
-
-    }
-
-    /**
-     * Parses an entire document.
-     *
-     * @return void
-     */
-    protected function parseDocument() {
-
-        $line = $this->readLine();
-
-        // BOM is ZERO WIDTH NO-BREAK SPACE (U+FEFF).
-        // It's 0xEF 0xBB 0xBF in UTF-8 hex.
-        if (   3 <= strlen($line)
-            && ord($line[0]) === 0xef
-            && ord($line[1]) === 0xbb
-            && ord($line[2]) === 0xbf) {
-            $line = substr($line, 3);
-        }
-
-        switch(strtoupper($line)) {
-            case 'BEGIN:VCALENDAR' :
-                $class = isset(VCalendar::$componentMap['VCALENDAR'])
-                    ? VCalendar::$componentMap[$name]
-                    : 'Sabre\\VObject\\Component\\VCalendar';
-                break;
-            case 'BEGIN:VCARD' :
-                $class = isset(VCard::$componentMap['VCARD'])
-                    ? VCard::$componentMap['VCARD']
-                    : 'Sabre\\VObject\\Component\\VCard';
-                break;
-            default :
-                throw new ParseException('This parser only supports VCARD and VCALENDAR files');
-        }
-
-        $this->root = new $class(array(), false);
-
-        while(true) {
-
-            // Reading until we hit END:
-            $line = $this->readLine();
-            if (strtoupper(substr($line,0,4)) === 'END:') {
-                break;
-            }
-            $result = $this->parseLine($line);
-            if ($result) {
-                $this->root->add($result);
-            }
-
-        }
-
-        $name = strtoupper(substr($line, 4));
-        if ($name!==$this->root->name) {
-            throw new ParseException('Invalid MimeDir file. expected: "END:' . $this->root->name . '" got: "END:' . $name . '"');
-        }
-
-    }
-
-    /**
-     * Parses a line, and if it hits a component, it will also attempt to parse
-     * the entire component
-     *
-     * @param string $line Unfolded line
-     * @return Node
-     */
-    protected function parseLine($line) {
-
-        // Start of a new component
-        if (strtoupper(substr($line, 0, 6)) === 'BEGIN:') {
-
-            $component = $this->root->createComponent(substr($line,6), array(), false);
-
-            while(true) {
-
-                // Reading until we hit END:
-                $line = $this->readLine();
-                if (strtoupper(substr($line,0,4)) === 'END:') {
-                    break;
-                }
-                $result = $this->parseLine($line);
-                if ($result) {
-                    $component->add($result);
-                }
-
-            }
-
-            $name = strtoupper(substr($line, 4));
-            if ($name!==$component->name) {
-                throw new ParseException('Invalid MimeDir file. expected: "END:' . $component->name . '" got: "END:' . $name . '"');
-            }
-
-            return $component;
-
-        } else {
-
-            // Property reader
-            $property = $this->readProperty($line);
-            if (!$property) {
-                // Ignored line
-                return false;
-            }
-            return $property;
-
-        }
-
-    }
-
-    /**
-     * We need to look ahead 1 line every time to see if we need to 'unfold'
-     * the next line.
-     *
-     * If that was not the case, we store it here.
-     *
-     * @var null|string
-     */
-    protected $lineBuffer;
-
-    /**
-     * The real current line number.
-     */
-    protected $lineIndex = 0;
-
-    /**
-     * In the case of unfolded lines, this property holds the line number for
-     * the start of the line.
-     *
-     * @var int
-     */
-    protected $startLine = 0;
-
-    /**
-     * Contains a 'raw' representation of the current line.
-     *
-     * @var string
-     */
-    protected $rawLine;
-
-    /**
-     * Reads a single line from the buffer.
-     *
-     * This method strips any newlines and also takes care of unfolding.
-     *
-     * @throws \Sabre\VObject\EofException
-     * @return string
-     */
-    protected function readLine() {
-
-        if (!is_null($this->lineBuffer)) {
-            $rawLine = $this->lineBuffer;
-            $this->lineBuffer = null;
-        } else {
-            do {
-                $eof = feof($this->input);
-
-                $rawLine = fgets($this->input);
-
-                if ($eof || (feof($this->input) && $rawLine===false)) {
-                    throw new EofException('End of document reached prematurely');
-                }
-                if ($rawLine === false) {
-                    throw new ParseException('Error reading from input stream');
-                }
-                $rawLine = rtrim($rawLine, "\r\n");
-            } while ($rawLine === ''); // Skipping empty lines
-            $this->lineIndex++;
-        }
-        $line = $rawLine;
-
-        $this->startLine = $this->lineIndex;
-
-        // Looking ahead for folded lines.
-        while (true) {
-
-            $nextLine = rtrim(fgets($this->input), "\r\n");
-            $this->lineIndex++;
-            if (!$nextLine) {
-                break;
-            }
-            if ($nextLine[0] === "\t" || $nextLine[0] === " ") {
-                $line .= substr($nextLine, 1);
-                $rawLine .= "\n " . substr($nextLine, 1);
-            } else {
-                $this->lineBuffer = $nextLine;
-                break;
-            }
-
-        }
-        $this->rawLine = $rawLine;
-        return $line;
-
-    }
-
-    /**
-     * Reads a property or component from a line.
-     *
-     * @return void
-     */
-    protected function readProperty($line) {
-
-        if ($this->options & self::OPTION_FORGIVING) {
-            $propNameToken = 'A-Z0-9\-\._\\/';
-        } else {
-            $propNameToken = 'A-Z0-9\-\.';
-        }
-
-        $paramNameToken = 'A-Z0-9\-';
-        $safeChar = '^";:,';
-        $qSafeChar = '^"';
-
-        $regex = "/
-            ^(?P<name> [$propNameToken]+ ) (?=[;:])        # property name
-            |
-            (?<=:)(?P<propValue> .+)$                      # property value
-            |
-            ;(?P<paramName> [$paramNameToken]+) (?=[=;:])  # parameter name
-            |
-            (=|,)(?P<paramValue>                           # parameter value
-                (?: [$safeChar]*) |
-                \"(?: [$qSafeChar]+)\"
-            ) (?=[;:,])
-            /xi";
-
-        //echo $regex, "\n"; die();
-        preg_match_all($regex, $line, $matches,  PREG_SET_ORDER);
-
-        $property = array(
-            'name' => null,
-            'parameters' => array(),
-            'value' => null
-        );
-
-        $lastParam = null;
-
-        /**
-         * Looping through all the tokens.
-         *
-         * Note that we are looping through them in reverse order, because if a
-         * sub-pattern matched, the subsequent named patterns will not show up
-         * in the result.
-         */
-        foreach($matches as $match) {
-
-            if (isset($match['paramValue'])) {
-                if ($match['paramValue'] && $match['paramValue'][0] === '"') {
-                    $value = substr($match['paramValue'], 1, -1);
-                } else {
-                    $value = $match['paramValue'];
-                }
-
-                $value = $this->unescapeParam($value);
-
-                if (is_null($property['parameters'][$lastParam])) {
-                    $property['parameters'][$lastParam] = $value;
-                } elseif (is_array($property['parameters'][$lastParam])) {
-                    $property['parameters'][$lastParam][] = $value;
-                } else {
-                    $property['parameters'][$lastParam] = array(
-                        $property['parameters'][$lastParam],
-                        $value
-                    );
-                }
-                continue;
-            }
-            if (isset($match['paramName'])) {
-                $lastParam = strtoupper($match['paramName']);
-                if (!isset($property['parameters'][$lastParam])) {
-                    $property['parameters'][$lastParam] = null;
-                }
-                continue;
-            }
-            if (isset($match['propValue'])) {
-                $property['value'] = $match['propValue'];
-                continue;
-            }
-            if (isset($match['name']) && $match['name']) {
-                $property['name'] = strtoupper($match['name']);
-                continue;
-            }
-
-            // @codeCoverageIgnoreStart
-            throw new \LogicException('This code should not be reachable');
-            // @codeCoverageIgnoreEnd
-
-        }
-
-        if (is_null($property['value'])) {
-            $property['value'] = '';
-        }
-        if (!$property['name']) {
-            if ($this->options & self::OPTION_IGNORE_INVALID_LINES) {
-                return false;
-            }
-            throw new ParseException('Invalid Mimedir file. Line starting at ' . $this->startLine . ' did not follow iCalendar/vCard conventions');
-        }
-
-        // vCard 2.1 states that parameters may appear without a name, and only
-        // a value. We can deduce the value based on it's name.
-        //
-        // Our parser will get those as parameters without a value instead, so
-        // we're filtering these parameters out first.
-        $namedParameters = array();
-        $namelessParameters = array();
-
-        foreach($property['parameters'] as $name=>$value) {
-            if (!is_null($value)) {
-                $namedParameters[$name] = $value;
-            } else {
-                $namelessParameters[] = $name;
-            }
-        }
-
-        $propObj = $this->root->createProperty($property['name'], null, $namedParameters);
-
-        foreach($namelessParameters as $namelessParameter) {
-            $propObj->add(null, $namelessParameter);
-        }
-
-        if (strtoupper($propObj['ENCODING']) === 'QUOTED-PRINTABLE') {
-            $propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue());
-        } else {
-            $propObj->setRawMimeDirValue($property['value']);
-        }
-
-        return $propObj;
-
-    }
-
-    /**
-     * Unescapes a property value.
-     *
-     * vCard 2.1 says:
-     *   * Semi-colons must be escaped in some property values, specifically
-     *     ADR, ORG and N.
-     *   * Semi-colons must be escaped in parameter values, because semi-colons
-     *     are also use to separate values.
-     *   * No mention of escaping backslashes with another backslash.
-     *   * newlines are not escaped either, instead QUOTED-PRINTABLE is used to
-     *     span values over more than 1 line.
-     *
-     * vCard 3.0 says:
-     *   * (rfc2425) Backslashes, newlines (\n or \N) and comma's must be
-     *     escaped, all time time.
-     *   * Comma's are used for delimeters in multiple values
-     *   * (rfc2426) Adds to to this that the semi-colon MUST also be escaped,
-     *     as in some properties semi-colon is used for separators.
-     *   * Properties using semi-colons: N, ADR, GEO, ORG
-     *   * Both ADR and N's individual parts may be broken up further with a
-     *     comma.
-     *   * Properties using commas: NICKNAME, CATEGORIES
-     *
-     * vCard 4.0 (rfc6350) says:
-     *   * Commas must be escaped.
-     *   * Semi-colons may be escaped, an unescaped semi-colon _may_ be a
-     *     delimiter, depending on the property.
-     *   * Backslashes must be escaped
-     *   * Newlines must be escaped as either \N or \n.
-     *   * Some compound properties may contain multiple parts themselves, so a
-     *     comma within a semi-colon delimited property may also be unescaped
-     *     to denote multiple parts _within_ the compound property.
-     *   * Text-properties using semi-colons: N, ADR, ORG, CLIENTPIDMAP.
-     *   * Text-properties using commas: NICKNAME, RELATED, CATEGORIES, PID.
-     *
-     * Even though the spec says that commas must always be escaped, the
-     * example for GEO in Section 6.5.2 seems to violate this.
-     *
-     * iCalendar 2.0 (rfc5545) says:
-     *   * Commas or semi-colons may be used as delimiters, depending on the
-     *     property.
-     *   * Commas, semi-colons, backslashes, newline (\N or \n) are always
-     *     escaped, unless they are delimiters.
-     *   * Colons shall not be escaped.
-     *   * Commas can be considered the 'default delimiter' and is described as
-     *     the delimiter in cases where the order of the multiple values is
-     *     insignificant.
-     *   * Semi-colons are described as the delimiter for 'structured values'.
-     *     They are specifically used in Semi-colons are used as a delimiter in
-     *     REQUEST-STATUS, RRULE, GEO and EXRULE. EXRULE is deprecated however.
-     *
-     * Now for the parameters
-     *
-     * If delimiter is not set (null) this method will just return a string.
-     * If it's a comma or a semi-colon the string will be split on those
-     * characters, and always return an array.
-     *
-     * @param string $input
-     * @param string $delimiter
-     * @return string|string[]
-     */
-    static public function unescapeValue($input, $delimiter = ';') {
-
-        $regex = '#  (?: (\\\\ (?: \\\\ | N | n | ; | , ) )';
-        if ($delimiter) {
-            $regex .= ' | (' . $delimiter . ')';
-        }
-        $regex .= ') #x';
-
-        $matches = preg_split($regex, $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
-
-        $resultArray = array();
-        $result = '';
-
-        foreach($matches as $match) {
-
-            switch ($match) {
-                case '\\\\' :
-                    $result .='\\';
-                    break;
-                case '\N' :
-                case '\n' :
-                    $result .="\n";
-                    break;
-                case '\;' :
-                    $result .=';';
-                    break;
-                case '\,' :
-                    $result .=',';
-                    break;
-                case $delimiter :
-                    $resultArray[] = $result;
-                    $result = '';
-                    break;
-                default :
-                    $result .= $match;
-                    break;
-
-            }
-
-        }
-
-        $resultArray[] = $result;
-        return $delimiter ? $resultArray : $result;
-
-    }
-
-    /**
-     * Unescapes a parameter value.
-     *
-     * vCard 2.1:
-     *   * Does not mention a mechanism for this. In addition, double quotes
-     *     are never used to wrap values.
-     *   * This means that parameters can simply not contain colons or
-     *     semi-colons.
-     *
-     * vCard 3.0 (rfc2425, rfc2426):
-     *   * Parameters _may_ be surrounded by double quotes.
-     *   * If this is not the case, semi-colon, colon and comma may simply not
-     *     occur (the comma used for multiple parameter values though).
-     *   * If it is surrounded by double-quotes, it may simply not contain
-     *     double-quotes.
-     *   * This means that a parameter can in no case encode double-quotes, or
-     *     newlines.
-     *
-     * vCard 4.0 (rfc6350)
-     *   * Behavior seems to be identical to vCard 3.0
-     *
-     * iCalendar 2.0 (rfc5545)
-     *   * Behavior seems to be identical to vCard 3.0
-     *
-     * Parameter escaping mechanism (rfc6868) :
-     *   * This rfc describes a new way to escape parameter values.
-     *   * New-line is encoded as ^n
-     *   * ^ is encoded as ^^.
-     *   * " is encoded as ^'
-     *
-     * @param string $input
-     * @return void
-     */
-    private function unescapeParam($input) {
-
-        return
-            preg_replace_callback(
-                '#(\^(\^|n|\'))#',
-                function($matches) {
-                    switch($matches[2]) {
-                        case 'n' :
-                            return "\n";
-                        case '^' :
-                            return '^';
-                        case '\'' :
-                            return '"';
-
-                    // @codeCoverageIgnoreStart
-                    }
-                    // @codeCoverageIgnoreEnd
-                },
-                $input
-            );
-    }
-
-    /**
-     * Gets the full quoted printable value.
-     *
-     * We need a special method for this, because newlines have both a meaning
-     * in vCards, and in QuotedPrintable.
-     *
-     * This method does not do any decoding.
-     *
-     * @return string
-     */
-    private function extractQuotedPrintableValue() {
-
-        // We need to parse the raw line again to get the start of the value.
-        //
-        // We are basically looking for the first colon (:), but we need to
-        // skip over the parameters first, as they may contain one.
-        $regex = '/^
-            (?: [^:])+ # Anything but a colon
-            (?: "[^"]")* # A parameter in double quotes
-            : # start of the value we really care about
-            (.*)$
-        /xs';
-
-        preg_match($regex, $this->rawLine, $matches);
-
-        $value = $matches[1];
-        // Removing the first whitespace character from every line. Kind of
-        // like unfolding, but we keep the newline.
-        $value = str_replace("\n ", "\n", $value);
-
-        // Microsoft products don't always correctly fold lines, they may be
-        // missing a whitespace. So if 'forgiving' is turned on, we will take
-        // those as well.
-        if ($this->options & self::OPTION_FORGIVING) {
-            while(substr($value,-1) === '=') {
-                // Reading the line
-                $this->readLine();
-                // Grabbing the raw form
-                $value.="\n" . $this->rawLine;
-            }
-        }
-
-        return $value;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Parser/Parser.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Parser;
-
-/**
- * Abstract parser.
- *
- * This class serves as a base-class for the different parsers.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-abstract class Parser {
-
-    /**
-     * Turning on this option makes the parser more forgiving.
-     *
-     * In the case of the MimeDir parser, this means that the parser will
-     * accept slashes and underscores in property names, and it will also
-     * attempt to fix Microsoft vCard 2.1's broken line folding.
-     */
-    const OPTION_FORGIVING = 1;
-
-    /**
-     * If this option is turned on, any lines we cannot parse will be ignored
-     * by the reader.
-     */
-    const OPTION_IGNORE_INVALID_LINES = 2;
-
-    /**
-     * Bitmask of parser options
-     *
-     * @var int
-     */
-    protected $options;
-
-    /**
-     * Creates the parser.
-     *
-     * Optionally, it's possible to parse the input stream here.
-     *
-     * @param mixed $input
-     * @param int $options Any parser options (OPTION constants).
-     * @return void
-     */
-    public function __construct($input = null, $options = 0) {
-
-        if (!is_null($input)) {
-            $this->setInput($input);
-        }
-        $this->options = $options;
-    }
-
-    /**
-     * This method starts the parsing process.
-     *
-     * If the input was not supplied during construction, it's possible to pass
-     * it here instead.
-     *
-     * If either input or options are not supplied, the defaults will be used.
-     *
-     * @param mixed $input
-     * @param int|null $options
-     * @return array
-     */
-    abstract public function parse($input = null, $options = null);
-
-    /**
-     * Sets the input data
-     *
-     * @param mixed $input
-     * @return void
-     */
-    abstract public function setInput($input);
-
-}
--- a/vendor/sabre/vobject/lib/Property.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,518 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Property
- *
- * A property is always in a KEY:VALUE structure, and may optionally contain
- * parameters.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-abstract class Property extends Node {
-
-    /**
-     * Property name.
-     *
-     * This will contain a string such as DTSTART, SUMMARY, FN.
-     *
-     * @var string
-     */
-    public $name;
-
-    /**
-     * Property group.
-     *
-     * This is only used in vcards
-     *
-     * @var string
-     */
-    public $group;
-
-    /**
-     * List of parameters
-     *
-     * @var array
-     */
-    public $parameters = array();
-
-    /**
-     * Current value
-     *
-     * @var mixed
-     */
-    protected $value;
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = ';';
-
-    /**
-     * Creates the generic property.
-     *
-     * Parameters must be specified in key=>value syntax.
-     *
-     * @param Component $root The root document
-     * @param string $name
-     * @param string|array|null $value
-     * @param array $parameters List of parameters
-     * @param string $group The vcard property group
-     * @return void
-     */
-    public function __construct(Component $root, $name, $value = null, array $parameters = array(), $group = null) {
-
-        $this->name = $name;
-        $this->group = $group;
-
-        $this->root = $root;
-
-        foreach($parameters as $k=>$v) {
-            $this->add($k, $v);
-        }
-
-        if (!is_null($value)) {
-            $this->setValue($value);
-        }
-
-    }
-
-    /**
-     * Updates the current value.
-     *
-     * This may be either a single, or multiple strings in an array.
-     *
-     * @param string|array $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        $this->value = $value;
-
-    }
-
-    /**
-     * Returns the current value.
-     *
-     * This method will always return a singular value. If this was a
-     * multi-value object, some decision will be made first on how to represent
-     * it as a string.
-     *
-     * To get the correct multi-value version, use getParts.
-     *
-     * @return string
-     */
-    public function getValue() {
-
-        if (is_array($this->value)) {
-            if (count($this->value)==0) {
-                return null;
-            } elseif (count($this->value)===1) {
-                return $this->value[0];
-            } else {
-                return $this->getRawMimeDirValue($this->value);
-            }
-        } else {
-            return $this->value;
-        }
-
-    }
-
-    /**
-     * Sets a multi-valued property.
-     *
-     * @param array $parts
-     * @return void
-     */
-    public function setParts(array $parts) {
-
-        $this->value = $parts;
-
-    }
-
-    /**
-     * Returns a multi-valued property.
-     *
-     * This method always returns an array, if there was only a single value,
-     * it will still be wrapped in an array.
-     *
-     * @return array
-     */
-    public function getParts() {
-
-        if (is_null($this->value)) {
-            return array();
-        } elseif (is_array($this->value)) {
-            return $this->value;
-        } else {
-            return array($this->value);
-        }
-
-    }
-
-    /**
-     * Adds a new parameter, and returns the new item.
-     *
-     * If a parameter with same name already existed, the values will be
-     * combined.
-     * If nameless parameter is added, we try to guess it's name.
-     *
-     * @param string $name
-     * @param string|null|array $value
-     * @return Node
-     */
-    public function add($name, $value = null) {
-        $noName = false;
-        if ($name === null) {
-            $name = Parameter::guessParameterNameByValue($value);
-            $noName = true;
-        }
-
-        if (isset($this->parameters[strtoupper($name)])) {
-            $this->parameters[strtoupper($name)]->addValue($value);
-        }
-        else {
-            $param = new Parameter($this->root, $name, $value);
-            $param->noName = $noName;
-            $this->parameters[$param->name] = $param;
-        }
-    }
-
-    /**
-     * Returns an iterable list of children
-     *
-     * @return array
-     */
-    public function parameters() {
-
-        return $this->parameters;
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    abstract public function getValueType();
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    abstract public function setRawMimeDirValue($val);
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    abstract public function getRawMimeDirValue();
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    public function serialize() {
-
-        $str = $this->name;
-        if ($this->group) $str = $this->group . '.' . $this->name;
-
-        foreach($this->parameters as $param) {
-
-            $str.=';' . $param->serialize();
-
-        }
-
-        $str.=':' . $this->getRawMimeDirValue();
-
-        $out = '';
-        while(strlen($str)>0) {
-            if (strlen($str)>75) {
-                $out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
-                $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
-            } else {
-                $out.=$str . "\r\n";
-                $str='';
-                break;
-            }
-        }
-
-        return $out;
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        return $this->getParts();
-
-    }
-
-    /**
-     * Sets the json value, as it would appear in a jCard or jCal object.
-     *
-     * The value must always be an array.
-     *
-     * @param array $value
-     * @return void
-     */
-    public function setJsonValue(array $value) {
-
-        if (count($value)===1) {
-            $this->setValue(reset($value));
-        } else {
-            $this->setValue($value);
-        }
-
-    }
-
-    /**
-     * This method returns an array, with the representation as it should be
-     * encoded in json. This is used to create jCard or jCal documents.
-     *
-     * @return array
-     */
-    public function jsonSerialize() {
-
-        $parameters = array();
-
-        foreach($this->parameters as $parameter) {
-            if ($parameter->name === 'VALUE') {
-                continue;
-            }
-            $parameters[strtolower($parameter->name)] = $parameter->jsonSerialize();
-        }
-        // In jCard, we need to encode the property-group as a separate 'group'
-        // parameter.
-        if ($this->group) {
-            $parameters['group'] = $this->group;
-        }
-
-        return array_merge(
-            array(
-                strtolower($this->name),
-                (object)$parameters,
-                strtolower($this->getValueType()),
-            ),
-            $this->getJsonValue()
-        );
-    }
-
-
-    /**
-     * Called when this object is being cast to a string.
-     *
-     * If the property only had a single value, you will get just that. In the
-     * case the property had multiple values, the contents will be escaped and
-     * combined with ,.
-     *
-     * @return string
-     */
-    public function __toString() {
-
-        return (string)$this->getValue();
-
-    }
-
-    /* ArrayAccess interface {{{ */
-
-    /**
-     * Checks if an array element exists
-     *
-     * @param mixed $name
-     * @return bool
-     */
-    public function offsetExists($name) {
-
-        if (is_int($name)) return parent::offsetExists($name);
-
-        $name = strtoupper($name);
-
-        foreach($this->parameters as $parameter) {
-            if ($parameter->name == $name) return true;
-        }
-        return false;
-
-    }
-
-    /**
-     * Returns a parameter.
-     *
-     * If the parameter does not exist, null is returned.
-     *
-     * @param string $name
-     * @return Node
-     */
-    public function offsetGet($name) {
-
-        if (is_int($name)) return parent::offsetGet($name);
-        $name = strtoupper($name);
-
-        if (!isset($this->parameters[$name])) {
-            return null;
-        }
-
-        return $this->parameters[$name];
-
-    }
-
-    /**
-     * Creates a new parameter
-     *
-     * @param string $name
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($name, $value) {
-
-        if (is_int($name)) {
-            parent::offsetSet($name, $value);
-            // @codeCoverageIgnoreStart
-            // This will never be reached, because an exception is always
-            // thrown.
-            return;
-            // @codeCoverageIgnoreEnd
-        }
-
-        $param = new Parameter($this->root, $name, $value);
-        $this->parameters[$param->name] = $param;
-
-    }
-
-    /**
-     * Removes one or more parameters with the specified name
-     *
-     * @param string $name
-     * @return void
-     */
-    public function offsetUnset($name) {
-
-        if (is_int($name)) {
-            parent::offsetUnset($name);
-            // @codeCoverageIgnoreStart
-            // This will never be reached, because an exception is always
-            // thrown.
-            return;
-            // @codeCoverageIgnoreEnd
-        }
-
-        unset($this->parameters[strtoupper($name)]);
-
-    }
-    /* }}} */
-
-    /**
-     * This method is automatically called when the object is cloned.
-     * Specifically, this will ensure all child elements are also cloned.
-     *
-     * @return void
-     */
-    public function __clone() {
-
-        foreach($this->parameters as $key=>$child) {
-            $this->parameters[$key] = clone $child;
-            $this->parameters[$key]->parent = $this;
-        }
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   - Node::REPAIR - If something is broken, and automatic repair may
-     *                    be attempted.
-     *
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $warnings = array();
-
-        // Checking if our value is UTF-8
-        if (!StringUtil::isUTF8($this->getRawMimeDirValue())) {
-
-            $oldValue = $this->getRawMimeDirValue();
-            $level = 3;
-            if ($options & self::REPAIR) {
-                $newValue = StringUtil::convertToUTF8($oldValue);
-                if (true || StringUtil::isUTF8($newValue)) {
-                    $this->setRawMimeDirValue($newValue);
-                    $level = 1;
-                }
-
-            }
-
-
-            if (preg_match('%([\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', $oldValue, $matches)) {
-                $message = 'Property contained a control character (0x' . bin2hex($matches[1]) . ')';
-            } else {
-                $message = 'Property is not valid UTF-8! ' . $oldValue;
-            }
-
-            $warnings[] = array(
-                'level' => $level,
-                'message' => $message,
-                'node' => $this,
-            );
-        }
-
-        // Checking if the propertyname does not contain any invalid bytes.
-        if (!preg_match('/^([A-Z0-9-]+)$/', $this->name)) {
-            $warnings[] = array(
-                'level' => 1,
-                'message' => 'The propertyname: ' . $this->name . ' contains invalid characters. Only A-Z, 0-9 and - are allowed',
-                'node' => $this,
-            );
-            if ($options & self::REPAIR) {
-                // Uppercasing and converting underscores to dashes.
-                $this->name = strtoupper(
-                    str_replace('_', '-', $this->name)
-                );
-                // Removing every other invalid character
-                $this->name = preg_replace('/([^A-Z0-9-])/u', '', $this->name);
-
-            }
-
-        }
-
-        // Validating inner parameters
-        foreach($this->parameters as $param) {
-            $warnings = array_merge($warnings, $param->validate($options));
-        }
-
-        return $warnings;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/Binary.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use
-    LogicException,
-    Sabre\VObject\Property;
-
-/**
- * BINARY property
- *
- * This object represents BINARY values.
- *
- * Binary values are most commonly used by the iCalendar ATTACH property, and
- * the vCard PHOTO property.
- *
- * This property will transparently encode and decode to base64.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Binary extends Property {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = null;
-
-    /**
-     * Updates the current value.
-     *
-     * This may be either a single, or multiple strings in an array.
-     *
-     * @param string|array $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        if(is_array($value)) {
-
-            if(count($value) === 1) {
-                $this->value = $value[0];
-            } else {
-                throw new \InvalidArgumentException('The argument must either be a string or an array with only one child');
-            }
-
-        } else {
-
-            $this->value = $value;
-
-        }
-
-    }
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->value = base64_decode($val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return base64_encode($this->value);
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return 'BINARY';
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        return array(base64_encode($this->getValue()));
-
-    }
-
-    /**
-     * Sets the json value, as it would appear in a jCard or jCal object.
-     *
-     * The value must always be an array.
-     *
-     * @param array $value
-     * @return void
-     */
-    public function setJsonValue(array $value) {
-
-        $value = array_map('base64_decode', $value);
-        parent::setJsonValue($value);
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/Boolean.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use
-    Sabre\VObject\Property;
-
-/**
- * Boolean property
- *
- * This object represents BOOLEAN values. These are always the case-insenstive
- * string TRUE or FALSE.
- *
- * Automatic conversion to PHP's true and false are done.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Boolean extends Property {
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $val = strtoupper($val)==='TRUE'?true:false;
-        $this->setValue($val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return $this->value?'TRUE':'FALSE';
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return 'BOOLEAN';
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/FlatText.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-/**
- * FlatText property
- *
- * This object represents certain TEXT values.
- *
- * Specifically, this property is used for text values where there is only 1
- * part. Semi-colons and colons will be de-escaped when deserializing, but if
- * any semi-colons or commas appear without a backslash, we will not assume
- * that they are delimiters.
- *
- * vCard 2.1 specifically has a whole bunch of properties where this may
- * happen, as it only defines a delimiter for a few properties.
- *
- * vCard 4.0 states something similar. An unescaped semi-colon _may_ be a
- * delimiter, depending on the property.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class FlatText extends Text {
-
-    /**
-     * Field separator
-     *
-     * @var string
-     */
-    public $delimiter = ',';
-
-    /**
-     * Sets the value as a quoted-printable encoded string.
-     *
-     * Overriding this so we're not splitting on a ; delimiter.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setQuotedPrintableValue($val) {
-
-        $val = quoted_printable_decode($val);
-        $this->setValue($val);
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/Float.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use
-    Sabre\VObject\Property;
-
-/**
- * Float property
- *
- * This object represents FLOAT values. These can be 1 or more floating-point
- * numbers.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Float extends Property {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = ';';
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $val = explode($this->delimiter, $val);
-        foreach($val as &$item) {
-            $item = (float)$item;
-        }
-        $this->setParts($val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return implode(
-            $this->delimiter,
-            $this->getParts()
-        );
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "FLOAT";
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $val = array_map(
-            function($item) {
-
-                return (float)$item;
-
-            },
-            $this->getParts()
-        );
-
-        // Special-casing the GEO property.
-        //
-        // See:
-        // http://tools.ietf.org/html/draft-ietf-jcardcal-jcal-04#section-3.4.1.2
-        if ($this->name==='GEO') {
-            return array($val);
-        } else {
-            return $val;
-        }
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use
-    Sabre\VObject\Property\Text;
-
-/**
- * CalAddress property
- *
- * This object encodes CAL-ADDRESS values, as defined in rfc5545
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class CalAddress extends Text {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = null;
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return 'CAL-ADDRESS';
-
-    }
-
-    /**
-     * This returns a normalized form of the value.
-     *
-     * This is primarily used right now to turn mixed-cased schemes in user
-     * uris to lower-case.
-     *
-     * Evolution in particular tends to encode mailto: as MAILTO:.
-     *
-     * @return string
-     */
-    public function getNormalizedValue() {
-
-        $input = $this->getValue();
-        if (!strpos($input, ':')) {
-            return $input;
-        }
-        list($schema, $everythingElse) = explode(':', $input, 2);
-        return strtolower($schema) . ':' . $everythingElse;
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/ICalendar/Date.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-/**
- * DateTime property
- *
- * This object represents DATE values, as defined here:
- *
- * http://tools.ietf.org/html/rfc5545#section-3.3.5
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Date extends DateTime {
-
-}
--- a/vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,388 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use DateTimeZone;
-use Sabre\VObject\Property;
-use Sabre\VObject\DateTimeParser;
-use Sabre\VObject\TimeZoneUtil;
-
-/**
- * DateTime property
- *
- * This object represents DATE-TIME values, as defined here:
- *
- * http://tools.ietf.org/html/rfc5545#section-3.3.4
- *
- * This particular object has a bit of hackish magic that it may also in some
- * cases represent a DATE value. This is because it's a common usecase to be
- * able to change a DATE-TIME into a DATE.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class DateTime extends Property {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = ',';
-
-    /**
-     * Sets a multi-valued property.
-     *
-     * You may also specify DateTime objects here.
-     *
-     * @param array $parts
-     * @return void
-     */
-    public function setParts(array $parts) {
-
-        if (isset($parts[0]) && $parts[0] instanceof \DateTime) {
-            $this->setDateTimes($parts);
-        } else {
-            parent::setParts($parts);
-        }
-
-    }
-
-    /**
-     * Updates the current value.
-     *
-     * This may be either a single, or multiple strings in an array.
-     *
-     * Instead of strings, you may also use DateTime here.
-     *
-     * @param string|array|\DateTime $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        if (is_array($value) && isset($value[0]) && $value[0] instanceof \DateTime) {
-            $this->setDateTimes($value);
-        } elseif ($value instanceof \DateTime) {
-            $this->setDateTimes(array($value));
-        } else {
-            parent::setValue($value);
-        }
-
-    }
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue(explode($this->delimiter, $val));
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return implode($this->delimiter, $this->getParts());
-
-    }
-
-    /**
-     * Returns true if this is a DATE-TIME value, false if it's a DATE.
-     *
-     * @return bool
-     */
-    public function hasTime() {
-
-        return strtoupper((string)$this['VALUE']) !== 'DATE';
-
-    }
-
-    /**
-     * Returns true if this is a floating DATE or DATE-TIME.
-     *
-     * Note that DATE is always floating.
-     */
-    public function isFloating() {
-
-        return
-            !$this->hasTime() ||
-            (
-                !isset($this['TZID']) &&
-                strpos($this->getValue(),'Z')===false
-            );
-
-    }
-
-    /**
-     * Returns a date-time value.
-     *
-     * Note that if this property contained more than 1 date-time, only the
-     * first will be returned. To get an array with multiple values, call
-     * getDateTimes.
-     *
-     * If no timezone information is known, because it's either an all-day
-     * property or floating time, we will use the DateTimeZone argument to
-     * figure out the exact date.
-     *
-     * @param DateTimeZone $timeZone
-     * @return \DateTime
-     */
-    public function getDateTime(DateTimeZone $timeZone = null) {
-
-        $dt = $this->getDateTimes($timeZone);
-        if (!$dt) return null;
-
-        return $dt[0];
-
-    }
-
-    /**
-     * Returns multiple date-time values.
-     *
-     * If no timezone information is known, because it's either an all-day
-     * property or floating time, we will use the DateTimeZone argument to
-     * figure out the exact date.
-     *
-     * @param DateTimeZone $timeZone
-     * @return \DateTime[]
-     */
-    public function getDateTimes(DateTimeZone $timeZone = null) {
-
-        // Does the property have a TZID?
-        $tzid = $this['TZID'];
-
-        if ($tzid) {
-            $timeZone = TimeZoneUtil::getTimeZone((string)$tzid, $this->root);
-        }
-
-        $dts = array();
-        foreach($this->getParts() as $part) {
-            $dts[] = DateTimeParser::parse($part, $timeZone);
-        }
-        return $dts;
-
-    }
-
-    /**
-     * Sets the property as a DateTime object.
-     *
-     * @param \DateTime $dt
-     * @param bool isFloating If set to true, timezones will be ignored.
-     * @return void
-     */
-    public function setDateTime(\DateTime $dt, $isFloating = false) {
-
-        $this->setDateTimes(array($dt), $isFloating);
-
-    }
-
-    /**
-     * Sets the property as multiple date-time objects.
-     *
-     * The first value will be used as a reference for the timezones, and all
-     * the otehr values will be adjusted for that timezone
-     *
-     * @param \DateTime[] $dt
-     * @param bool isFloating If set to true, timezones will be ignored.
-     * @return void
-     */
-    public function setDateTimes(array $dt, $isFloating = false) {
-
-        $values = array();
-
-        if($this->hasTime()) {
-
-            $tz = null;
-            $isUtc = false;
-
-            foreach($dt as $d) {
-
-                if ($isFloating) {
-                    $values[] = $d->format('Ymd\\THis');
-                    continue;
-                }
-                if (is_null($tz)) {
-                    $tz = $d->getTimeZone();
-                    $isUtc = in_array($tz->getName() , array('UTC', 'GMT', 'Z'));
-                    if (!$isUtc) {
-                        $this->offsetSet('TZID', $tz->getName());
-                    }
-                } else {
-                    $d->setTimeZone($tz);
-                }
-
-                if ($isUtc) {
-                    $values[] = $d->format('Ymd\\THis\\Z');
-                } else {
-                    $values[] = $d->format('Ymd\\THis');
-                }
-
-            }
-            if ($isUtc || $isFloating) {
-                $this->offsetUnset('TZID');
-            }
-
-        } else {
-
-            foreach($dt as $d) {
-
-                $values[] = $d->format('Ymd');
-
-            }
-            $this->offsetUnset('TZID');
-
-        }
-
-        $this->value = $values;
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return $this->hasTime()?'DATE-TIME':'DATE';
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $dts = $this->getDateTimes();
-        $hasTime = $this->hasTime();
-        $isFloating = $this->isFloating();
-
-        $tz = $dts[0]->getTimeZone();
-        $isUtc = $isFloating ? false : in_array($tz->getName() , array('UTC', 'GMT', 'Z'));
-
-        return array_map(
-            function($dt) use ($hasTime, $isUtc) {
-
-                if ($hasTime) {
-                    return $dt->format('Y-m-d\\TH:i:s') . ($isUtc?'Z':'');
-                } else {
-                    return $dt->format('Y-m-d');
-                }
-
-            },
-            $dts
-        );
-
-    }
-
-    /**
-     * Sets the json value, as it would appear in a jCard or jCal object.
-     *
-     * The value must always be an array.
-     *
-     * @param array $value
-     * @return void
-     */
-    public function setJsonValue(array $value) {
-
-        // dates and times in jCal have one difference to dates and times in
-        // iCalendar. In jCal date-parts are separated by dashes, and
-        // time-parts are separated by colons. It makes sense to just remove
-        // those.
-        $this->setValue(
-            array_map(
-                function($item) {
-
-                    return strtr($item, array(':'=>'', '-'=>''));
-
-                },
-                $value
-            )
-        );
-
-    }
-    /**
-     * We need to intercept offsetSet, because it may be used to alter the
-     * VALUE from DATE-TIME to DATE or vice-versa.
-     *
-     * @param string $name
-     * @param mixed $value
-     * @return void
-     */
-    public function offsetSet($name, $value) {
-
-        parent::offsetSet($name, $value);
-        if (strtoupper($name)!=='VALUE') {
-            return;
-        }
-
-        // This will ensure that dates are correctly encoded.
-        $this->setDateTimes($this->getDateTimes());
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
-     *   2 - An inconsequential issue
-     *   3 - A severe issue.
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $messages = parent::validate($options);
-        $valueType = $this->getValueType();
-        $value = $this->getValue();
-        try {
-            switch($valueType) {
-                case 'DATE' :
-                    $foo = DateTimeParser::parseDate($value);
-                    break;
-                case 'DATE-TIME' :
-                    $foo = DateTimeParser::parseDateTime($value);
-                    break;
-            }
-        } catch (\LogicException $e) {
-            $messages[] = array(
-                'level' => 3,
-                'message' => 'The supplied value (' . $value . ') is not a correct ' . $valueType,
-                'node' => $this,
-            );
-        }
-        return $messages;
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/ICalendar/Duration.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use
-    Sabre\VObject\Property,
-    Sabre\VObject\Parser\MimeDir,
-    Sabre\VObject\DateTimeParser;
-
-/**
- * Duration property
- *
- * This object represents DURATION values, as defined here:
- *
- * http://tools.ietf.org/html/rfc5545#section-3.3.6
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Duration extends Property {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = ',';
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue(explode($this->delimiter, $val));
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return implode($this->delimiter, $this->getParts());
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return 'DURATION';
-
-    }
-
-    /**
-     * Returns a DateInterval representation of the Duration property.
-     *
-     * If the property has more than one value, only the first is returned.
-     *
-     * @return \DateInterval
-     */
-    public function getDateInterval() {
-
-        $parts = $this->getParts();
-        $value = $parts[0];
-        return DateTimeParser::parseDuration($value);
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/ICalendar/Period.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use
-    Sabre\VObject\Property,
-    Sabre\VObject\Parser\MimeDir,
-    Sabre\VObject\DateTimeParser;
-
-/**
- * Period property
- *
- * This object represents PERIOD values, as defined here:
- *
- * http://tools.ietf.org/html/rfc5545#section-3.8.2.6
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Period extends Property {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = ',';
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue(explode($this->delimiter, $val));
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return implode($this->delimiter, $this->getParts());
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "PERIOD";
-
-    }
-
-    /**
-     * Sets the json value, as it would appear in a jCard or jCal object.
-     *
-     * The value must always be an array.
-     *
-     * @param array $value
-     * @return void
-     */
-    public function setJsonValue(array $value) {
-
-        $value = array_map(
-            function($item) {
-
-                return strtr(implode('/', $item), array(':' => '', '-' => ''));
-
-            },
-            $value
-        );
-        parent::setJsonValue($value);
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $return = array();
-        foreach($this->getParts() as $item) {
-
-            list($start, $end) = explode('/', $item, 2);
-
-            $start = DateTimeParser::parseDateTime($start);
-
-            // This is a duration value.
-            if ($end[0]==='P') {
-                $return[] = array(
-                    $start->format('Y-m-d\\TH:i:s'),
-                    $end
-                );
-            } else {
-                $end = DateTimeParser::parseDateTime($end);
-                $return[] = array(
-                    $start->format('Y-m-d\\TH:i:s'),
-                    $end->format('Y-m-d\\TH:i:s'),
-                );
-            }
-
-        }
-
-        return $return;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/ICalendar/Recur.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use
-    Sabre\VObject\Property,
-    Sabre\VObject\Parser\MimeDir;
-
-/**
- * Recur property
- *
- * This object represents RECUR properties.
- * These values are just used for RRULE and the now deprecated EXRULE.
- *
- * The RRULE property may look something like this:
- *
- * RRULE:FREQ=MONTHLY;BYDAY=1,2,3;BYHOUR=5.
- *
- * This property exposes this as a key=>value array that is accessible using
- * getParts, and may be set using setParts.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Recur extends Property {
-
-    /**
-     * Updates the current value.
-     *
-     * This may be either a single, or multiple strings in an array.
-     *
-     * @param string|array $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        // If we're getting the data from json, we'll be receiving an object
-        if ($value instanceof \StdClass) {
-            $value = (array)$value;
-        }
-
-        if (is_array($value)) {
-            $newVal = array();
-            foreach($value as $k=>$v) {
-
-                if (is_string($v)) {
-                    $v = strtoupper($v);
-
-                    // The value had multiple sub-values
-                    if (strpos($v,',')!==false) {
-                        $v = explode(',', $v);
-                    }
-                } else {
-                    $v = array_map('strtoupper', $v);
-                }
-
-                $newVal[strtoupper($k)] = $v;
-            }
-            $this->value = $newVal;
-        } elseif (is_string($value)) {
-            $this->value = self::stringToArray($value);
-        } else {
-            throw new \InvalidArgumentException('You must either pass a string, or a key=>value array');
-        }
-
-    }
-
-    /**
-     * Returns the current value.
-     *
-     * This method will always return a singular value. If this was a
-     * multi-value object, some decision will be made first on how to represent
-     * it as a string.
-     *
-     * To get the correct multi-value version, use getParts.
-     *
-     * @return string
-     */
-    public function getValue() {
-
-        $out = array();
-        foreach($this->value as $key=>$value) {
-            $out[] = $key . '=' . (is_array($value)?implode(',', $value):$value);
-        }
-        return strtoupper(implode(';',$out));
-
-    }
-
-    /**
-     * Sets a multi-valued property.
-     *
-     * @param array $parts
-     * @return void
-     */
-    public function setParts(array $parts) {
-
-        $this->setValue($parts);
-
-    }
-
-    /**
-     * Returns a multi-valued property.
-     *
-     * This method always returns an array, if there was only a single value,
-     * it will still be wrapped in an array.
-     *
-     * @return array
-     */
-    public function getParts() {
-
-        return $this->value;
-
-    }
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue($val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return $this->getValue();
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "RECUR";
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $values = array();
-        foreach($this->getParts() as $k=>$v) {
-            $values[strtolower($k)] = $v;
-        }
-        return array($values);
-
-    }
-
-    /**
-     * Parses an RRULE value string, and turns it into a struct-ish array.
-     *
-     * @param string $value
-     * @return array
-     */
-    static function stringToArray($value) {
-
-        $value = strtoupper($value);
-        $newValue = array();
-        foreach(explode(';', $value) as $part) {
-
-            // Skipping empty parts.
-            if (empty($part)) {
-                continue;
-            }
-            list($partName, $partValue) = explode('=', $part);
-
-            // The value itself had multiple values..
-            if (strpos($partValue,',')!==false) {
-                $partValue=explode(',', $partValue);
-            }
-            $newValue[$partName] = $partValue;
-
-        }
-
-        return $newValue;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/Integer.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use
-    Sabre\VObject\Property;
-
-/**
- * Integer property
- *
- * This object represents INTEGER values. These are always a single integer.
- * They may be preceeded by either + or -.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Integer extends Property {
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue((int)$val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return $this->value;
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "INTEGER";
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        return array((int)$this->getValue());
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/Text.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use
-    Sabre\VObject\Property,
-    Sabre\VObject\Component,
-    Sabre\VObject\Parser\MimeDir,
-    Sabre\VObject\Document;
-
-/**
- * Text property
- *
- * This object represents TEXT values.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Text extends Property {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string
-     */
-    public $delimiter = ',';
-
-    /**
-     * List of properties that are considered 'structured'.
-     *
-     * @var array
-     */
-    protected $structuredValues = array(
-        // vCard
-        'N',
-        'ADR',
-        'ORG',
-        'GENDER',
-
-        // iCalendar
-        'REQUEST-STATUS',
-    );
-
-    /**
-     * Some text components have a minimum number of components.
-     *
-     * N must for instance be represented as 5 components, separated by ;, even
-     * if the last few components are unused.
-     *
-     * @var array
-     */
-    protected $minimumPropertyValues = array(
-        'N' => 5,
-        'ADR' => 7,
-    );
-
-    /**
-     * Creates the property.
-     *
-     * You can specify the parameters either in key=>value syntax, in which case
-     * parameters will automatically be created, or you can just pass a list of
-     * Parameter objects.
-     *
-     * @param Component $root The root document
-     * @param string $name
-     * @param string|array|null $value
-     * @param array $parameters List of parameters
-     * @param string $group The vcard property group
-     * @return void
-     */
-    public function __construct(Component $root, $name, $value = null, array $parameters = array(), $group = null) {
-
-        // There's two types of multi-valued text properties:
-        // 1. multivalue properties.
-        // 2. structured value properties
-        //
-        // The former is always separated by a comma, the latter by semi-colon.
-        if (in_array($name, $this->structuredValues)) {
-            $this->delimiter = ';';
-        }
-
-        parent::__construct($root, $name, $value, $parameters, $group);
-
-    }
-
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue(MimeDir::unescapeValue($val, $this->delimiter));
-
-    }
-
-    /**
-     * Sets the value as a quoted-printable encoded string.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setQuotedPrintableValue($val) {
-
-        $val = quoted_printable_decode($val);
-
-        // Quoted printable only appears in vCard 2.1, and the only character
-        // that may be escaped there is ;. So we are simply splitting on just
-        // that.
-        //
-        // We also don't have to unescape \\, so all we need to look for is a ;
-        // that's not preceeded with a \.
-        $regex = '# (?<!\\\\) ; #x';
-        $matches = preg_split($regex, $val);
-        $this->setValue($matches);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        $val = $this->getParts();
-
-        if (isset($this->minimumPropertyValues[$this->name])) {
-            $val = array_pad($val, $this->minimumPropertyValues[$this->name], '');
-        }
-
-        foreach($val as &$item) {
-
-            if (!is_array($item)) {
-                $item = array($item);
-            }
-
-            foreach($item as &$subItem) {
-                $subItem = strtr(
-                    $subItem,
-                    array(
-                        '\\' => '\\\\',
-                        ';'  => '\;',
-                        ','  => '\,',
-                        "\n" => '\n',
-                        "\r" => "",
-                    )
-                );
-            }
-            $item = implode(',', $item);
-
-        }
-
-        return implode($this->delimiter, $val);
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        // Structured text values should always be returned as a single
-        // array-item. Multi-value text should be returned as multiple items in
-        // the top-array.
-        if (in_array($this->name, $this->structuredValues)) {
-            return array($this->getParts());
-        } else {
-            return $this->getParts();
-        }
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "TEXT";
-
-    }
-
-    /**
-     * Turns the object back into a serialized blob.
-     *
-     * @return string
-     */
-    public function serialize() {
-
-        // We need to kick in a special type of encoding, if it's a 2.1 vcard.
-        if ($this->root->getDocumentType() !== Document::VCARD21) {
-            return parent::serialize();
-        }
-
-        $val = $this->getParts();
-
-        if (isset($this->minimumPropertyValues[$this->name])) {
-            $val = array_pad($val, $this->minimumPropertyValues[$this->name], '');
-        }
-
-        // Imploding multiple parts into a single value, and splitting the
-        // values with ;.
-        if (count($val)>1) {
-            foreach($val as $k=>$v) {
-                $val[$k] = str_replace(';','\;', $v);
-            }
-            $val = implode(';', $val);
-        } else {
-            $val = $val[0];
-        }
-
-        $str = $this->name;
-        if ($this->group) $str = $this->group . '.' . $this->name;
-        foreach($this->parameters as $param) {
-
-            if ($param->getValue() === 'QUOTED-PRINTABLE') {
-                continue;
-            }
-            $str.=';' . $param->serialize();
-
-        }
-
-
-
-        // If the resulting value contains a \n, we must encode it as
-        // quoted-printable.
-        if (strpos($val,"\n") !== false) {
-
-            $str.=';ENCODING=QUOTED-PRINTABLE:';
-            $lastLine=$str;
-            $out = null;
-
-            // The PHP built-in quoted-printable-encode does not correctly
-            // encode newlines for us. Specifically, the \r\n sequence must in
-            // vcards be encoded as =0D=OA and we must insert soft-newlines
-            // every 75 bytes.
-            for($ii=0;$ii<strlen($val);$ii++) {
-                $ord = ord($val[$ii]);
-                // These characters are encoded as themselves.
-                if ($ord >= 32 && $ord <=126) {
-                    $lastLine.=$val[$ii];
-                } else {
-                    $lastLine.='=' . strtoupper(bin2hex($val[$ii]));
-                }
-                if (strlen($lastLine)>=75) {
-                    // Soft line break
-                    $out.=$lastLine. "=\r\n ";
-                    $lastLine = null;
-                }
-
-            }
-            if (!is_null($lastLine)) $out.= $lastLine . "\r\n";
-            return $out;
-
-        } else {
-            $str.=':' . $val;
-            $out = '';
-            while(strlen($str)>0) {
-                if (strlen($str)>75) {
-                    $out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
-                    $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
-                } else {
-                    $out.=$str . "\r\n";
-                    $str='';
-                    break;
-                }
-            }
-
-            return $out;
-
-
-        }
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   - Node::REPAIR - If something is broken, and automatic repair may
-     *                    be attempted.
-     *
-     * An array is returned with warnings.
-     *
-     * Every item in the array has the following properties:
-     *    * level - (number between 1 and 3 with severity information)
-     *    * message - (human readable message)
-     *    * node - (reference to the offending node)
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $warnings = parent::validate($options);
-
-        if (isset($this->minimumPropertyValues[$this->name])) {
-
-            $minimum = $this->minimumPropertyValues[$this->name];
-            $parts = $this->getParts();
-            if (count($parts) < $minimum) {
-                $warnings[] = array(
-                    'level' => 1,
-                    'message' => 'This property must have at least ' . $minimum . ' components. It only has ' . count($parts),
-                    'node' => $this,
-                );
-                if ($options & self::REPAIR) {
-                    $parts = array_pad($parts, $minimum, '');
-                    $this->setParts($parts);
-                }
-            }
-
-        }
-        return $warnings;
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/Time.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject\DateTimeParser;
-
-/**
- * Time property
- *
- * This object encodes TIME values.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Time extends Text {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = null;
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "TIME";
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $parts = DateTimeParser::parseVCardTime($this->getValue());
-
-        $timeStr = '';
-
-        // Hour
-        if (!is_null($parts['hour'])) {
-            $timeStr.=$parts['hour'];
-
-            if (!is_null($parts['minute'])) {
-                $timeStr.=':';
-            }
-        } else {
-            // We know either minute or second _must_ be set, so we insert a
-            // dash for an empty value.
-            $timeStr.='-';
-        }
-
-        // Minute
-        if (!is_null($parts['minute'])) {
-            $timeStr.=$parts['minute'];
-
-            if (!is_null($parts['second'])) {
-                $timeStr.=':';
-            }
-        } else {
-            if (isset($parts['second'])) {
-                // Dash for empty minute
-                $timeStr.='-';
-            }
-        }
-
-        // Second
-        if (!is_null($parts['second'])) {
-            $timeStr.=$parts['second'];
-        }
-
-        // Timezone
-        if (!is_null($parts['timezone'])) {
-            $timeStr.=$parts['timezone'];
-        }
-
-        return array($timeStr);
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/Unknown.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use
-    Sabre\VObject\Property,
-    Sabre\VObject\Component,
-    Sabre\VObject\Parser\MimeDir,
-    Sabre\VObject\Document;
-
-/**
- * Unknown property
- *
- * This object represents any properties not recognized by the parser.
- * This type of value has been introduced by the jCal, jCard specs.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Unknown extends Text {
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        return array($this->getRawMimeDirValue());
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "UNKNOWN";
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/Uri.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject\Property;
-
-/**
- * URI property
- *
- * This object encodes URI values. vCard 2.1 calls these URL.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Uri extends Text {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = null;
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "URI";
-
-    }
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        // Normally we don't need to do any type of unescaping for these
-        // properties, however.. we've noticed that Google Contacts
-        // specifically escapes the colon (:) with a blackslash. While I have
-        // no clue why they thought that was a good idea, I'm unescaping it
-        // anyway.
-        //
-        // Good thing backslashes are not allowed in urls. Makes it easy to
-        // assume that a backslash is always intended as an escape character.
-        if ($this->name === 'URL') {
-            $regex = '#  (?: (\\\\ (?: \\\\ | : ) ) ) #x';
-            $matches = preg_split($regex, $val, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
-            $newVal = '';
-            foreach($matches as $match) {
-                switch($match) {
-                    case '\:' :
-                        $newVal.=':';
-                        break;
-                    default :
-                        $newVal.=$match;
-                        break;
-                }
-            }
-            $this->value = $newVal;
-        } else {
-            $this->value = $val;
-        }
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        if (is_array($this->value)) {
-            return $this->value[0];
-        } else {
-            return $this->value;
-        }
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/UtcOffset.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-/**
- * UtcOffset property
- *
- * This object encodes UTC-OFFSET values.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class UtcOffset extends Text {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = null;
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "UTC-OFFSET";
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/VCard/Date.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use
-    Sabre\VObject\DateTimeParser;
-
-/**
- * Date property
- *
- * This object encodes vCard DATE values.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Date extends DateAndOrTime {
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "DATE";
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use
-    Sabre\VObject\DateTimeParser,
-    Sabre\VObject\Property\Text,
-    Sabre\VObject\Property,
-    DateTime;
-
-/**
- * DateAndOrTime property
- *
- * This object encodes DATE-AND-OR-TIME values.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class DateAndOrTime extends Property {
-
-    /**
-     * Field separator
-     *
-     * @var null|string
-     */
-    public $delimiter = null;
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "DATE-AND-OR-TIME";
-
-    }
-
-    /**
-     * Sets a multi-valued property.
-     *
-     * You may also specify DateTime objects here.
-     *
-     * @param array $parts
-     * @return void
-     */
-    public function setParts(array $parts) {
-
-        if (count($parts)>1) {
-            throw new \InvalidArgumentException('Only one value allowed');
-        }
-        if (isset($parts[0]) && $parts[0] instanceof \DateTime) {
-            $this->setDateTime($parts[0]);
-        } else {
-            parent::setParts($parts);
-        }
-
-    }
-
-    /**
-     * Updates the current value.
-     *
-     * This may be either a single, or multiple strings in an array.
-     *
-     * Instead of strings, you may also use DateTime here.
-     *
-     * @param string|array|\DateTime $value
-     * @return void
-     */
-    public function setValue($value) {
-
-        if ($value instanceof \DateTime) {
-            $this->setDateTime($value);
-        } else {
-            parent::setValue($value);
-        }
-
-    }
-
-    /**
-     * Sets the property as a DateTime object.
-     *
-     * @param \DateTime $dt
-     * @return void
-     */
-    public function setDateTime(\DateTime $dt) {
-
-        $values = array();
-
-        $tz = null;
-        $isUtc = false;
-
-        $tz = $dt->getTimeZone();
-        $isUtc = in_array($tz->getName() , array('UTC', 'GMT', 'Z'));
-
-        if ($isUtc) {
-            $value = $dt->format('Ymd\\THis\\Z');
-        } else {
-            // Calculating the offset.
-            $value = $dt->format('Ymd\\THisO');
-        }
-
-        $this->value = $value;
-
-    }
-
-    /**
-     * Returns a date-time value.
-     *
-     * Note that if this property contained more than 1 date-time, only the
-     * first will be returned. To get an array with multiple values, call
-     * getDateTimes.
-     *
-     * If no time was specified, we will always use midnight (in the default
-     * timezone) as the time.
-     *
-     * If parts of the date were omitted, such as the year, we will grab the
-     * current values for those. So at the time of writing, if the year was
-     * omitted, we would have filled in 2014.
-     *
-     * @return \DateTime
-     */
-    public function getDateTime() {
-
-        $dts = array();
-        $now = new DateTime();
-
-        $tzFormat = $now->getTimezone()->getOffset($now)===0?'\\Z':'O';
-        $nowParts = DateTimeParser::parseVCardDateTime($now->format('Ymd\\This' . $tzFormat));
-
-        $value = $this->getValue();
-
-        $dateParts = DateTimeParser::parseVCardDateTime($this->getValue());
-
-        // This sets all the missing parts to the current date/time.
-        // So if the year was missing for a birthday, we're making it 'this
-        // year'.
-        foreach($dateParts as $k=>$v) {
-            if (is_null($v)) {
-                $dateParts[$k] = $nowParts[$k];
-            }
-        }
-        return new DateTime("$dateParts[year]-$dateParts[month]-$dateParts[date] $dateParts[hour]:$dateParts[minute]:$dateParts[second] $dateParts[timezone]");
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $parts = DateTimeParser::parseVCardDateTime($this->getValue());
-
-        $dateStr = '';
-
-        // Year
-        if (!is_null($parts['year'])) {
-            $dateStr.=$parts['year'];
-
-            if (!is_null($parts['month'])) {
-                // If a year and a month is set, we need to insert a separator
-                // dash.
-                $dateStr.='-';
-            }
-
-        } else {
-
-            if (!is_null($parts['month']) || !is_null($parts['date'])) {
-                // Inserting two dashes
-                $dateStr.='--';
-            }
-
-        }
-
-        // Month
-
-        if (!is_null($parts['month'])) {
-            $dateStr.=$parts['month'];
-
-            if (isset($parts['date'])) {
-                // If month and date are set, we need the separator dash.
-                $dateStr.='-';
-            }
-        } else {
-            if (isset($parts['date'])) {
-                // If the month is empty, and a date is set, we need a 'empty
-                // dash'
-                $dateStr.='-';
-            }
-        }
-
-        // Date
-        if (!is_null($parts['date'])) {
-            $dateStr.=$parts['date'];
-        }
-
-
-        // Early exit if we don't have a time string.
-        if (is_null($parts['hour']) && is_null($parts['minute']) && is_null($parts['second'])) {
-            return array($dateStr);
-        }
-
-        $dateStr.='T';
-
-        // Hour
-        if (!is_null($parts['hour'])) {
-            $dateStr.=$parts['hour'];
-
-            if (!is_null($parts['minute'])) {
-                $dateStr.=':';
-            }
-        } else {
-            // We know either minute or second _must_ be set, so we insert a
-            // dash for an empty value.
-            $dateStr.='-';
-        }
-
-        // Minute
-        if (!is_null($parts['minute'])) {
-            $dateStr.=$parts['minute'];
-
-            if (!is_null($parts['second'])) {
-                $dateStr.=':';
-            }
-        } else {
-            if (isset($parts['second'])) {
-                // Dash for empty minute
-                $dateStr.='-';
-            }
-        }
-
-        // Second
-        if (!is_null($parts['second'])) {
-            $dateStr.=$parts['second'];
-        }
-
-        // Timezone
-        if (!is_null($parts['timezone'])) {
-            $dateStr.=$parts['timezone'];
-        }
-
-        return array($dateStr);
-
-    }
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue($val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return implode($this->delimiter, $this->getParts());
-
-    }
-
-    /**
-     * Validates the node for correctness.
-     *
-     * The following options are supported:
-     *   Node::REPAIR - May attempt to automatically repair the problem.
-     *
-     * This method returns an array with detected problems.
-     * Every element has the following properties:
-     *
-     *  * level - problem level.
-     *  * message - A human-readable string describing the issue.
-     *  * node - A reference to the problematic node.
-     *
-     * The level means:
-     *   1 - The issue was repaired (only happens if REPAIR was turned on)
-     *   2 - An inconsequential issue
-     *   3 - A severe issue.
-     *
-     * @param int $options
-     * @return array
-     */
-    public function validate($options = 0) {
-
-        $messages = parent::validate($options);
-        $value = $this->getValue();
-        try {
-            DateTimeParser::parseVCardDateTime($value);
-        } catch (\InvalidArgumentException $e) {
-            $messages[] = array(
-                'level' => 3,
-                'message' => 'The supplied value (' . $value . ') is not a correct DATE-AND-OR-TIME property',
-                'node' => $this,
-            );
-        }
-        return $messages;
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Property/VCard/DateTime.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use
-    Sabre\VObject\DateTimeParser;
-
-/**
- * DateTime property
- *
- * This object encodes DATE-TIME values for vCards.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class DateTime extends DateAndOrTime {
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "DATE-TIME";
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use
-    Sabre\VObject\Property;
-
-/**
- * LanguageTag property
- *
- * This object represents LANGUAGE-TAG values as used in vCards.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class LanguageTag extends Property {
-
-    /**
-     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
-     *
-     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
-     * not yet done, but parameters are not included.
-     *
-     * @param string $val
-     * @return void
-     */
-    public function setRawMimeDirValue($val) {
-
-        $this->setValue($val);
-
-    }
-
-    /**
-     * Returns a raw mime-dir representation of the value.
-     *
-     * @return string
-     */
-    public function getRawMimeDirValue() {
-
-        return $this->value;
-
-    }
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "LANGUAGE-TAG";
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Property/VCard/TimeStamp.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use
-    Sabre\VObject\DateTimeParser,
-    Sabre\VObject\Property\Text;
-
-/**
- * TimeStamp property
- *
- * This object encodes TIMESTAMP values.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class TimeStamp extends Text {
-
-    /**
-     * In case this is a multi-value property. This string will be used as a
-     * delimiter.
-     *
-     * @var string|null
-     */
-    public $delimiter = null;
-
-    /**
-     * Returns the type of value.
-     *
-     * This corresponds to the VALUE= parameter. Every property also has a
-     * 'default' valueType.
-     *
-     * @return string
-     */
-    public function getValueType() {
-
-        return "TIMESTAMP";
-
-    }
-
-    /**
-     * Returns the value, in the format it should be encoded for json.
-     *
-     * This method must always return an array.
-     *
-     * @return array
-     */
-    public function getJsonValue() {
-
-        $parts = DateTimeParser::parseVCardDateTime($this->getValue());
-
-        $dateStr =
-            $parts['year'] . '-' .
-            $parts['month'] . '-' .
-            $parts['date'] . 'T' .
-            $parts['hour'] . ':' .
-            $parts['minute'] . ':' .
-            $parts['second'];
-
-        // Timezone
-        if (!is_null($parts['timezone'])) {
-            $dateStr.=$parts['timezone'];
-        }
-
-        return array($dateStr);
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Reader.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * iCalendar/vCard/jCal/jCard reader object.
- *
- * This object provides a few (static) convenience methods to quickly access
- * the parsers.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Reader {
-
-    /**
-     * If this option is passed to the reader, it will be less strict about the
-     * validity of the lines.
-     */
-    const OPTION_FORGIVING = 1;
-
-    /**
-     * If this option is turned on, any lines we cannot parse will be ignored
-     * by the reader.
-     */
-    const OPTION_IGNORE_INVALID_LINES = 2;
-
-    /**
-     * Parses a vCard or iCalendar object, and returns the top component.
-     *
-     * The options argument is a bitfield. Pass any of the OPTIONS constant to
-     * alter the parsers' behaviour.
-     *
-     * You can either supply a string, or a readable stream for input.
-     *
-     * @param string|resource $data
-     * @param int $options
-     * @return Document
-     */
-    static public function read($data, $options = 0) {
-
-        $parser = new Parser\MimeDir();
-        $result = $parser->parse($data, $options);
-
-        return $result;
-
-    }
-
-    /**
-     * Parses a jCard or jCal object, and returns the top component.
-     *
-     * The options argument is a bitfield. Pass any of the OPTIONS constant to
-     * alter the parsers' behaviour.
-     *
-     * You can either a string, a readable stream, or an array for it's input.
-     * Specifying the array is useful if json_decode was already called on the
-     * input.
-     *
-     * @param string|resource|array $data
-     * @param int $options
-     * @return Node
-     */
-    static public function readJson($data, $options = 0) {
-
-        $parser = new Parser\Json();
-        $result = $parser->parse($data, $options);
-
-        return $result;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Recur/EventIterator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,497 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use InvalidArgumentException;
-use DateTime;
-use DateTimeZone;
-use Sabre\VObject\Component;
-use Sabre\VObject\Component\VEvent;
-
-/**
- * This class is used to determine new for a recurring event, when the next
- * events occur.
- *
- * This iterator may loop infinitely in the future, therefore it is important
- * that if you use this class, you set hard limits for the amount of iterations
- * you want to handle.
- *
- * Note that currently there is not full support for the entire iCalendar
- * specification, as it's very complex and contains a lot of permutations
- * that's not yet used very often in software.
- *
- * For the focus has been on features as they actually appear in Calendaring
- * software, but this may well get expanded as needed / on demand
- *
- * The following RRULE properties are supported
- *   * UNTIL
- *   * INTERVAL
- *   * COUNT
- *   * FREQ=DAILY
- *     * BYDAY
- *     * BYHOUR
- *     * BYMONTH
- *   * FREQ=WEEKLY
- *     * BYDAY
- *     * BYHOUR
- *     * WKST
- *   * FREQ=MONTHLY
- *     * BYMONTHDAY
- *     * BYDAY
- *     * BYSETPOS
- *   * FREQ=YEARLY
- *     * BYMONTH
- *     * BYMONTHDAY (only if BYMONTH is also set)
- *     * BYDAY (only if BYMONTH is also set)
- *
- * Anything beyond this is 'undefined', which means that it may get ignored, or
- * you may get unexpected results. The effect is that in some applications the
- * specified recurrence may look incorrect, or is missing.
- *
- * The recurrence iterator also does not yet support THISANDFUTURE.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class EventIterator implements \Iterator {
-
-    /**
-     * Reference timeZone for floating dates and times.
-     *
-     * @var DateTimeZone
-     */
-    protected $timeZone;
-
-    /**
-     * True if we're iterating an all-day event.
-     *
-     * @var bool
-     */
-    protected $allDay = false;
-
-    /**
-     * Creates the iterator
-     *
-     * You should pass a VCALENDAR component, as well as the UID of the event
-     * we're going to traverse.
-     *
-     * @param Component $vcal
-     * @param string|null $uid
-     * @param DateTimeZone $timeZone Reference timezone for floating dates and
-     *                               times.
-     */
-    public function __construct(Component $vcal, $uid = null, DateTimeZone $timeZone = null) {
-
-        if (is_null($this->timeZone)) {
-            $timeZone = new DateTimeZone('UTC');
-        }
-        $this->timeZone = $timeZone;
-
-        if ($vcal instanceof VEvent) {
-            // Single instance mode.
-            $events = array($vcal);
-        } else {
-            $uid = (string)$uid;
-            if (!$uid) {
-                throw new InvalidArgumentException('The UID argument is required when a VCALENDAR is passed to this constructor');
-            }
-            if (!isset($vcal->VEVENT)) {
-                throw new InvalidArgumentException('No events found in this calendar');
-            }
-            $events = array();
-            foreach($vcal->VEVENT as $event) {
-                if ($event->uid->getValue() === $uid) {
-                    $events[] = $event;
-                }
-            }
-
-        }
-
-        foreach($events as $vevent) {
-
-            if (!isset($vevent->{'RECURRENCE-ID'})) {
-
-                $this->masterEvent = $vevent;
-
-            } else {
-
-                $this->exceptions[
-                    $vevent->{'RECURRENCE-ID'}->getDateTime($this->timeZone)->getTimeStamp()
-                ] = true;
-                $this->overriddenEvents[] = $vevent;
-
-            }
-
-        }
-
-        if (!$this->masterEvent) {
-            // No base event was found. CalDAV does allow cases where only
-            // overridden instances are stored.
-            //
-            // In this particular case, we're just going to grab the first
-            // event and use that instead. This may not always give the
-            // desired result.
-            if (!count($this->overriddenEvents)) {
-                throw new InvalidArgumentException('This VCALENDAR did not have an event with UID: ' . $uid);
-            }
-            $this->masterEvent = array_shift($this->overriddenEvents);
-        }
-
-        $this->startDate = $this->masterEvent->DTSTART->getDateTime($this->timeZone);
-        $this->allDay = !$this->masterEvent->DTSTART->hasTime();
-
-        if (isset($this->masterEvent->EXDATE)) {
-
-            foreach($this->masterEvent->EXDATE as $exDate) {
-
-                foreach($exDate->getDateTimes($this->timeZone) as $dt) {
-                    $this->exceptions[$dt->getTimeStamp()] = true;
-                }
-
-            }
-
-        }
-
-        if (isset($this->masterEvent->DTEND)) {
-            $this->eventDuration =
-                $this->masterEvent->DTEND->getDateTime($this->timeZone)->getTimeStamp() -
-                $this->startDate->getTimeStamp();
-        } elseif (isset($this->masterEvent->DURATION)) {
-            $duration = $this->masterEvent->DURATION->getDateInterval();
-            $end = clone $this->startDate;
-            $end->add($duration);
-            $this->eventDuration = $end->getTimeStamp() - $this->startDate->getTimeStamp();
-        } elseif ($this->allDay) {
-            $this->eventDuration = 3600 * 24;
-        } else {
-            $this->eventDuration = 0;
-        }
-
-        if (isset($this->masterEvent->RDATE)) {
-            $this->recurIterator = new RDateIterator(
-                $this->masterEvent->RDATE->getParts(),
-                $this->startDate
-            );
-        } elseif (isset($this->masterEvent->RRULE)) {
-            $this->recurIterator = new RRuleIterator(
-                $this->masterEvent->RRULE->getParts(),
-                $this->startDate
-            );
-        } else {
-            $this->recurIterator = new RRuleIterator(
-                array(
-                    'FREQ' => 'DAILY',
-                    'COUNT' => 1,
-                ),
-                $this->startDate
-            );
-        }
-
-        $this->rewind();
-        if (!$this->valid()) {
-            throw new NoInstancesException('This recurrence rule does not generate any valid instances');
-        }
-
-    }
-
-    /**
-     * Returns the date for the current position of the iterator.
-     *
-     * @return DateTime
-     */
-    public function current() {
-
-        if ($this->currentDate) {
-            return clone $this->currentDate;
-        }
-
-    }
-
-    /**
-     * This method returns the start date for the current iteration of the
-     * event.
-     *
-     * @return DateTime
-     */
-    public function getDtStart() {
-
-        if ($this->currentDate) {
-            return clone $this->currentDate;
-        }
-
-    }
-
-    /**
-     * This method returns the end date for the current iteration of the
-     * event.
-     *
-     * @return DateTime
-     */
-    public function getDtEnd() {
-
-        if (!$this->valid()) {
-            return null;
-        }
-        $end = clone $this->currentDate;
-        $end->modify('+' . $this->eventDuration . ' seconds');
-        return $end;
-
-    }
-
-    /**
-     * Returns a VEVENT for the current iterations of the event.
-     *
-     * This VEVENT will have a recurrence id, and it's DTSTART and DTEND
-     * altered.
-     *
-     * @return VEvent
-     */
-    public function getEventObject() {
-
-        if ($this->currentOverriddenEvent) {
-            return $this->currentOverriddenEvent;
-        }
-
-        $event = clone $this->masterEvent;
-
-        // Ignoring the following block, because PHPUnit's code coverage
-        // ignores most of these lines, and this messes with our stats.
-        //
-        // @codeCoverageIgnoreStart
-        unset(
-            $event->RRULE,
-            $event->EXDATE,
-            $event->RDATE,
-            $event->EXRULE,
-            $event->{'RECURRENCE-ID'}
-        );
-        // @codeCoverageIgnoreEnd
-
-        $event->DTSTART->setDateTime($this->getDtStart());
-        if (isset($event->DTEND)) {
-            $event->DTEND->setDateTime($this->getDtEnd());
-        }
-        // Including a RECURRENCE-ID to the object, unless this is the first
-        // object.
-        //
-        // The inner recurIterator is always one step ahead, this is why we're
-        // checking for the key being higher than 1.
-        if ($this->recurIterator->key() > 1) {
-            $recurid = clone $event->DTSTART;
-            $recurid->name = 'RECURRENCE-ID';
-            $event->add($recurid);
-        }
-        return $event;
-
-    }
-
-    /**
-     * Returns the current position of the iterator.
-     *
-     * This is for us simply a 0-based index.
-     *
-     * @return int
-     */
-    public function key() {
-
-        // The counter is always 1 ahead.
-        return $this->counter - 1;
-
-    }
-
-    /**
-     * This is called after next, to see if the iterator is still at a valid
-     * position, or if it's at the end.
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        return !!$this->currentDate;
-
-    }
-
-    /**
-     * Sets the iterator back to the starting point.
-     */
-    public function rewind() {
-
-        $this->recurIterator->rewind();
-        // re-creating overridden event index.
-        $index = array();
-        foreach($this->overriddenEvents as $key=>$event) {
-            $stamp = $event->DTSTART->getDateTime($this->timeZone)->getTimeStamp();
-            $index[$stamp] = $key;
-        }
-        krsort($index);
-        $this->counter = 0;
-        $this->overriddenEventsIndex = $index;
-        $this->currentOverriddenEvent = null;
-
-        $this->nextDate = null;
-        $this->currentDate = clone $this->startDate;
-
-        $this->next();
-
-    }
-
-    /**
-     * Advances the iterator with one step.
-     *
-     * @return void
-     */
-    public function next() {
-
-        $this->currentOverriddenEvent = null;
-        $this->counter++;
-        if ($this->nextDate) {
-            // We had a stored value.
-            $nextDate = $this->nextDate;
-            $this->nextDate = null;
-        } else {
-            // We need to ask rruleparser for the next date.
-            // We need to do this until we find a date that's not in the
-            // exception list.
-            do {
-                if (!$this->recurIterator->valid()) {
-                    $nextDate = null;
-                    break;
-                }
-                $nextDate = $this->recurIterator->current();
-                $this->recurIterator->next();
-            } while(isset($this->exceptions[$nextDate->getTimeStamp()]));
-
-        }
-
-
-        // $nextDate now contains what rrule thinks is the next one, but an
-        // overridden event may cut ahead.
-        if ($this->overriddenEventsIndex) {
-
-            $offset = end($this->overriddenEventsIndex);
-            $timestamp = key($this->overriddenEventsIndex);
-            if (!$nextDate || $timestamp < $nextDate->getTimeStamp()) {
-                // Overridden event comes first.
-                $this->currentOverriddenEvent = $this->overriddenEvents[$offset];
-
-                // Putting the rrule next date aside.
-                $this->nextDate = $nextDate;
-                $this->currentDate = $this->currentOverriddenEvent->DTSTART->getDateTime($this->timeZone);
-
-                // Ensuring that this item will only be used once.
-                array_pop($this->overriddenEventsIndex);
-
-                // Exit point!
-                return;
-
-            }
-
-        }
-
-        $this->currentDate = $nextDate;
-
-    }
-
-    /**
-     * Quickly jump to a date in the future.
-     *
-     * @param DateTime $dateTime
-     */
-    public function fastForward(DateTime $dateTime) {
-
-        while($this->valid() && $this->getDtEnd() < $dateTime ) {
-            $this->next();
-        }
-
-    }
-
-    /**
-     * Returns true if this recurring event never ends.
-     *
-     * @return bool
-     */
-    public function isInfinite() {
-
-        return $this->recurIterator->isInfinite();
-
-    }
-
-    /**
-     * RRULE parser
-     *
-     * @var RRuleIterator
-     */
-    protected $recurIterator;
-
-    /**
-     * The duration, in seconds, of the master event.
-     *
-     * We use this to calculate the DTEND for subsequent events.
-     */
-    protected $eventDuration;
-
-    /**
-     * A reference to the main (master) event.
-     *
-     * @var VEVENT
-     */
-    protected $masterEvent;
-
-    /**
-     * List of overridden events.
-     *
-     * @var array
-     */
-    protected $overriddenEvents = array();
-
-    /**
-     * Overridden event index.
-     *
-     * Key is timestamp, value is the index of the item in the $overriddenEvent
-     * property.
-     *
-     * @var array
-     */
-    protected $overriddenEventsIndex;
-
-    /**
-     * A list of recurrence-id's that are either part of EXDATE, or are
-     * overridden.
-     *
-     * @var array
-     */
-    protected $exceptions = array();
-
-    /**
-     * Internal event counter
-     *
-     * @var int
-     */
-    protected $counter;
-
-    /**
-     * The very start of the iteration process.
-     *
-     * @var DateTime
-     */
-    protected $startDate;
-
-    /**
-     * Where we are currently in the iteration process
-     *
-     * @var DateTime
-     */
-    protected $currentDate;
-
-    /**
-     * The next date from the rrule parser.
-     *
-     * Sometimes we need to temporary store the next date, because an
-     * overridden event came before.
-     *
-     * @var DateTime
-     */
-    protected $nextDate;
-
-}
--- a/vendor/sabre/vobject/lib/Recur/NoInstancesException.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use Exception;
-
-/**
- * This exception gets thrown when a recurrence iterator produces 0 instances.
- *
- * This may happen when every occurence in a rrule is also in EXDATE.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class NoInstancesException extends Exception {
-
-}
--- a/vendor/sabre/vobject/lib/Recur/RDateIterator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use DateTime;
-use InvalidArgumentException;
-use Iterator;
-use Sabre\VObject\DateTimeParser;
-
-
-/**
- * RRuleParser
- *
- * This class receives an RRULE string, and allows you to iterate to get a list
- * of dates in that recurrence.
- *
- * For instance, passing: FREQ=DAILY;LIMIT=5 will cause the iterator to contain
- * 5 items, one for each day.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class RDateIterator implements Iterator {
-
-    /**
-     * Creates the Iterator.
-     *
-     * @param string|array $rrule
-     * @param DateTime $start
-     */
-    public function __construct($rrule, DateTime $start) {
-
-        $this->startDate = $start;
-        $this->parseRDate($rrule);
-        $this->currentDate = clone $this->startDate;
-
-    }
-
-    /* Implementation of the Iterator interface {{{ */
-
-    public function current() {
-
-        if (!$this->valid()) return null;
-        return clone $this->currentDate;
-
-    }
-
-    /**
-     * Returns the current item number.
-     *
-     * @return int
-     */
-    public function key() {
-
-        return $this->counter;
-
-    }
-
-    /**
-     * Returns whether the current item is a valid item for the recurrence
-     * iterator.
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        return ($this->counter <= count($this->dates));
-
-    }
-
-    /**
-     * Resets the iterator.
-     *
-     * @return void
-     */
-    public function rewind() {
-
-        $this->currentDate = clone $this->startDate;
-        $this->counter = 0;
-
-    }
-
-    /**
-     * Goes on to the next iteration.
-     *
-     * @return void
-     */
-    public function next() {
-
-        $this->counter++;
-        if (!$this->valid()) return;
-
-        $this->currentDate =
-            DateTimeParser::parse(
-                $this->dates[$this->counter-1]
-            );
-
-    }
-
-    /* End of Iterator implementation }}} */
-
-    /**
-     * Returns true if this recurring event never ends.
-     *
-     * @return bool
-     */
-    public function isInfinite() {
-
-        return false;
-
-    }
-
-    /**
-     * This method allows you to quickly go to the next occurrence after the
-     * specified date.
-     *
-     * @param DateTime $dt
-     * @return void
-     */
-    public function fastForward(\DateTime $dt) {
-
-        while($this->valid() && $this->currentDate < $dt ) {
-            $this->next();
-        }
-
-    }
-
-    /**
-     * The reference start date/time for the rrule.
-     *
-     * All calculations are based on this initial date.
-     *
-     * @var DateTime
-     */
-    protected $startDate;
-
-    /**
-     * The date of the current iteration. You can get this by calling
-     * ->current().
-     *
-     * @var DateTime
-     */
-    protected $currentDate;
-
-    /**
-     * The current item in the list.
-     *
-     * You can get this number with the key() method.
-     *
-     * @var int
-     */
-    protected $counter = 0;
-
-    /* }}} */
-
-    /**
-     * This method receives a string from an RRULE property, and populates this
-     * class with all the values.
-     *
-     * @param string|array $rrule
-     * @return void
-     */
-    protected function parseRDate($rdate) {
-
-        if (is_string($rdate)) {
-            $rdate = explode(',', $rdate);
-        }
-
-        $this->dates = $rdate;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Recur/RRuleIterator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,901 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use DateTime;
-use InvalidArgumentException;
-use Iterator;
-use Sabre\VObject\DateTimeParser;
-use Sabre\VObject\Property;
-
-
-/**
- * RRuleParser
- *
- * This class receives an RRULE string, and allows you to iterate to get a list
- * of dates in that recurrence.
- *
- * For instance, passing: FREQ=DAILY;LIMIT=5 will cause the iterator to contain
- * 5 items, one for each day.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class RRuleIterator implements Iterator {
-
-    /**
-     * Creates the Iterator
-     *
-     * @param string|array $rrule
-     * @param DateTime $start
-     */
-    public function __construct($rrule, DateTime $start) {
-
-        $this->startDate = $start;
-        $this->parseRRule($rrule);
-        $this->currentDate = clone $this->startDate;
-
-    }
-
-    /* Implementation of the Iterator interface {{{ */
-
-    public function current() {
-
-        if (!$this->valid()) return null;
-        return clone $this->currentDate;
-
-    }
-
-    /**
-     * Returns the current item number
-     *
-     * @return int
-     */
-    public function key() {
-
-        return $this->counter;
-
-    }
-
-    /**
-     * Returns whether the current item is a valid item for the recurrence
-     * iterator. This will return false if we've gone beyond the UNTIL or COUNT
-     * statements.
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        if (!is_null($this->count)) {
-            return $this->counter < $this->count;
-        }
-        return is_null($this->until) || $this->currentDate <= $this->until;
-
-    }
-
-    /**
-     * Resets the iterator
-     *
-     * @return void
-     */
-    public function rewind() {
-
-        $this->currentDate = clone $this->startDate;
-        $this->counter = 0;
-
-    }
-
-    /**
-     * Goes on to the next iteration
-     *
-     * @return void
-     */
-    public function next() {
-
-        $previousStamp = $this->currentDate->getTimeStamp();
-
-        // Otherwise, we find the next event in the normal RRULE
-        // sequence.
-        switch($this->frequency) {
-
-            case 'hourly' :
-                $this->nextHourly();
-                break;
-
-            case 'daily' :
-                $this->nextDaily();
-                break;
-
-            case 'weekly' :
-                $this->nextWeekly();
-                break;
-
-            case 'monthly' :
-                $this->nextMonthly();
-                break;
-
-            case 'yearly' :
-                $this->nextYearly();
-                break;
-
-        }
-        $this->counter++;
-
-    }
-
-    /* End of Iterator implementation }}} */
-
-    /**
-     * Returns true if this recurring event never ends.
-     *
-     * @return bool
-     */
-    public function isInfinite() {
-
-        return !$this->count && !$this->until;
-
-    }
-
-    /**
-     * This method allows you to quickly go to the next occurrence after the
-     * specified date.
-     *
-     * @param DateTime $dt
-     * @return void
-     */
-    public function fastForward(\DateTime $dt) {
-
-        while($this->valid() && $this->currentDate < $dt ) {
-            $this->next();
-        }
-
-    }
-
-    /**
-     * The reference start date/time for the rrule.
-     *
-     * All calculations are based on this initial date.
-     *
-     * @var DateTime
-     */
-    protected $startDate;
-
-    /**
-     * The date of the current iteration. You can get this by calling
-     * ->current().
-     *
-     * @var DateTime
-     */
-    protected $currentDate;
-
-    /**
-     * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
-     * yearly.
-     *
-     * @var string
-     */
-    protected $frequency;
-
-    /**
-     * The number of recurrences, or 'null' if infinitely recurring.
-     *
-     * @var int
-     */
-    protected $count;
-
-    /**
-     * The interval.
-     *
-     * If for example frequency is set to daily, interval = 2 would mean every
-     * 2 days.
-     *
-     * @var int
-     */
-    protected $interval = 1;
-
-    /**
-     * The last instance of this recurrence, inclusively
-     *
-     * @var \DateTime|null
-     */
-    protected $until;
-
-    /**
-     * Which seconds to recur.
-     *
-     * This is an array of integers (between 0 and 60)
-     *
-     * @var array
-     */
-    protected $bySecond;
-
-    /**
-     * Which minutes to recur
-     *
-     * This is an array of integers (between 0 and 59)
-     *
-     * @var array
-     */
-    protected $byMinute;
-
-    /**
-     * Which hours to recur
-     *
-     * This is an array of integers (between 0 and 23)
-     *
-     * @var array
-     */
-    protected $byHour;
-
-    /**
-     * The current item in the list.
-     *
-     * You can get this number with the key() method.
-     *
-     * @var int
-     */
-    protected $counter = 0;
-
-    /**
-     * Which weekdays to recur.
-     *
-     * This is an array of weekdays
-     *
-     * This may also be preceeded by a positive or negative integer. If present,
-     * this indicates the nth occurrence of a specific day within the monthly or
-     * yearly rrule. For instance, -2TU indicates the second-last tuesday of
-     * the month, or year.
-     *
-     * @var array
-     */
-    protected $byDay;
-
-    /**
-     * Which days of the month to recur
-     *
-     * This is an array of days of the months (1-31). The value can also be
-     * negative. -5 for instance means the 5th last day of the month.
-     *
-     * @var array
-     */
-    protected $byMonthDay;
-
-    /**
-     * Which days of the year to recur.
-     *
-     * This is an array with days of the year (1 to 366). The values can also
-     * be negative. For instance, -1 will always represent the last day of the
-     * year. (December 31st).
-     *
-     * @var array
-     */
-    protected $byYearDay;
-
-    /**
-     * Which week numbers to recur.
-     *
-     * This is an array of integers from 1 to 53. The values can also be
-     * negative. -1 will always refer to the last week of the year.
-     *
-     * @var array
-     */
-    protected $byWeekNo;
-
-    /**
-     * Which months to recur.
-     *
-     * This is an array of integers from 1 to 12.
-     *
-     * @var array
-     */
-    protected $byMonth;
-
-    /**
-     * Which items in an existing st to recur.
-     *
-     * These numbers work together with an existing by* rule. It specifies
-     * exactly which items of the existing by-rule to filter.
-     *
-     * Valid values are 1 to 366 and -1 to -366. As an example, this can be
-     * used to recur the last workday of the month.
-     *
-     * This would be done by setting frequency to 'monthly', byDay to
-     * 'MO,TU,WE,TH,FR' and bySetPos to -1.
-     *
-     * @var array
-     */
-    protected $bySetPos;
-
-    /**
-     * When the week starts.
-     *
-     * @var string
-     */
-    protected $weekStart = 'MO';
-
-    /* Functions that advance the iterator {{{ */
-
-    /**
-     * Does the processing for advancing the iterator for hourly frequency.
-     *
-     * @return void
-     */
-    protected function nextHourly() {
-
-        $this->currentDate->modify('+' . $this->interval . ' hours');
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for daily frequency.
-     *
-     * @return void
-     */
-    protected function nextDaily() {
-
-        if (!$this->byHour && !$this->byDay) {
-            $this->currentDate->modify('+' . $this->interval . ' days');
-            return;
-        }
-
-        if (isset($this->byHour)) {
-            $recurrenceHours = $this->getHours();
-        }
-
-        if (isset($this->byDay)) {
-            $recurrenceDays = $this->getDays();
-        }
-
-        if (isset($this->byMonth)) {
-            $recurrenceMonths = $this->getMonths();
-        }
-
-        do {
-            if ($this->byHour) {
-                if ($this->currentDate->format('G') == '23') {
-                    // to obey the interval rule
-                    $this->currentDate->modify('+' . $this->interval-1 . ' days');
-                }
-
-                $this->currentDate->modify('+1 hours');
-
-            } else {
-                $this->currentDate->modify('+' . $this->interval . ' days');
-
-            }
-
-            // Current month of the year
-            $currentMonth = $this->currentDate->format('n');
-
-            // Current day of the week
-            $currentDay = $this->currentDate->format('w');
-
-            // Current hour of the day
-            $currentHour = $this->currentDate->format('G');
-
-        } while (
-            ($this->byDay   && !in_array($currentDay, $recurrenceDays)) ||
-            ($this->byHour  && !in_array($currentHour, $recurrenceHours)) ||
-            ($this->byMonth && !in_array($currentMonth, $recurrenceMonths))
-        );
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for weekly frequency.
-     *
-     * @return void
-     */
-    protected function nextWeekly() {
-
-        if (!$this->byHour && !$this->byDay) {
-            $this->currentDate->modify('+' . $this->interval . ' weeks');
-            return;
-        }
-
-        if ($this->byHour) {
-            $recurrenceHours = $this->getHours();
-        }
-
-        if ($this->byDay) {
-            $recurrenceDays = $this->getDays();
-        }
-
-        // First day of the week:
-        $firstDay = $this->dayMap[$this->weekStart];
-
-        do {
-
-            if ($this->byHour) {
-                $this->currentDate->modify('+1 hours');
-            } else {
-                $this->currentDate->modify('+1 days');
-            }
-
-            // Current day of the week
-            $currentDay = (int) $this->currentDate->format('w');
-
-            // Current hour of the day
-            $currentHour = (int) $this->currentDate->format('G');
-
-            // We need to roll over to the next week
-            if ($currentDay === $firstDay && (!$this->byHour || $currentHour == '0')) {
-                $this->currentDate->modify('+' . $this->interval-1 . ' weeks');
-
-                // We need to go to the first day of this week, but only if we
-                // are not already on this first day of this week.
-                if($this->currentDate->format('w') != $firstDay) {
-                    $this->currentDate->modify('last ' . $this->dayNames[$this->dayMap[$this->weekStart]]);
-                }
-            }
-
-            // We have a match
-        } while (($this->byDay && !in_array($currentDay, $recurrenceDays)) || ($this->byHour && !in_array($currentHour, $recurrenceHours)));
-    }
-
-    /**
-     * Does the processing for advancing the iterator for monthly frequency.
-     *
-     * @return void
-     */
-    protected function nextMonthly() {
-
-        $currentDayOfMonth = $this->currentDate->format('j');
-        if (!$this->byMonthDay && !$this->byDay) {
-
-            // If the current day is higher than the 28th, rollover can
-            // occur to the next month. We Must skip these invalid
-            // entries.
-            if ($currentDayOfMonth < 29) {
-                $this->currentDate->modify('+' . $this->interval . ' months');
-            } else {
-                $increase = 0;
-                do {
-                    $increase++;
-                    $tempDate = clone $this->currentDate;
-                    $tempDate->modify('+ ' . ($this->interval*$increase) . ' months');
-                } while ($tempDate->format('j') != $currentDayOfMonth);
-                $this->currentDate = $tempDate;
-            }
-            return;
-        }
-
-        while(true) {
-
-            $occurrences = $this->getMonthlyOccurrences();
-
-            foreach($occurrences as $occurrence) {
-
-                // The first occurrence thats higher than the current
-                // day of the month wins.
-                if ($occurrence > $currentDayOfMonth) {
-                    break 2;
-                }
-
-            }
-
-            // If we made it all the way here, it means there were no
-            // valid occurrences, and we need to advance to the next
-            // month.
-            //
-            // This line does not currently work in hhvm. Temporary workaround
-            // follows:
-            // $this->currentDate->modify('first day of this month');
-            $this->currentDate = new \DateTime($this->currentDate->format('Y-m-1 H:i:s'), $this->currentDate->getTimezone());
-            // end of workaround
-            $this->currentDate->modify('+ ' . $this->interval . ' months');
-
-            // This goes to 0 because we need to start counting at the
-            // beginning.
-            $currentDayOfMonth = 0;
-
-        }
-
-        $this->currentDate->setDate($this->currentDate->format('Y'), $this->currentDate->format('n'), $occurrence);
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for yearly frequency.
-     *
-     * @return void
-     */
-    protected function nextYearly() {
-
-        $currentMonth = $this->currentDate->format('n');
-        $currentYear = $this->currentDate->format('Y');
-        $currentDayOfMonth = $this->currentDate->format('j');
-
-        // No sub-rules, so we just advance by year
-        if (!$this->byMonth) {
-
-            // Unless it was a leap day!
-            if ($currentMonth==2 && $currentDayOfMonth==29) {
-
-                $counter = 0;
-                do {
-                    $counter++;
-                    // Here we increase the year count by the interval, until
-                    // we hit a date that's also in a leap year.
-                    //
-                    // We could just find the next interval that's dividable by
-                    // 4, but that would ignore the rule that there's no leap
-                    // year every year that's dividable by a 100, but not by
-                    // 400. (1800, 1900, 2100). So we just rely on the datetime
-                    // functions instead.
-                    $nextDate = clone $this->currentDate;
-                    $nextDate->modify('+ ' . ($this->interval*$counter) . ' years');
-                } while ($nextDate->format('n')!=2);
-                $this->currentDate = $nextDate;
-
-                return;
-
-            }
-
-            // The easiest form
-            $this->currentDate->modify('+' . $this->interval . ' years');
-            return;
-
-        }
-
-        $currentMonth = $this->currentDate->format('n');
-        $currentYear = $this->currentDate->format('Y');
-        $currentDayOfMonth = $this->currentDate->format('j');
-
-        $advancedToNewMonth = false;
-
-        // If we got a byDay or getMonthDay filter, we must first expand
-        // further.
-        if ($this->byDay || $this->byMonthDay) {
-
-            while(true) {
-
-                $occurrences = $this->getMonthlyOccurrences();
-
-                foreach($occurrences as $occurrence) {
-
-                    // The first occurrence that's higher than the current
-                    // day of the month wins.
-                    // If we advanced to the next month or year, the first
-                    // occurrence is always correct.
-                    if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
-                        break 2;
-                    }
-
-                }
-
-                // If we made it here, it means we need to advance to
-                // the next month or year.
-                $currentDayOfMonth = 1;
-                $advancedToNewMonth = true;
-                do {
-
-                    $currentMonth++;
-                    if ($currentMonth>12) {
-                        $currentYear+=$this->interval;
-                        $currentMonth = 1;
-                    }
-                } while (!in_array($currentMonth, $this->byMonth));
-
-                $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
-
-            }
-
-            // If we made it here, it means we got a valid occurrence
-            $this->currentDate->setDate($currentYear, $currentMonth, $occurrence);
-            return;
-
-        } else {
-
-            // These are the 'byMonth' rules, if there are no byDay or
-            // byMonthDay sub-rules.
-            do {
-
-                $currentMonth++;
-                if ($currentMonth>12) {
-                    $currentYear+=$this->interval;
-                    $currentMonth = 1;
-                }
-            } while (!in_array($currentMonth, $this->byMonth));
-            $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
-
-            return;
-
-        }
-
-    }
-
-    /* }}} */
-
-    /**
-     * This method receives a string from an RRULE property, and populates this
-     * class with all the values.
-     *
-     * @param string|array $rrule
-     * @return void
-     */
-    protected function parseRRule($rrule) {
-
-        if (is_string($rrule)) {
-            $rrule = Property\ICalendar\Recur::stringToArray($rrule);
-        }
-
-        foreach($rrule as $key=>$value) {
-
-            $key = strtoupper($key);
-            switch($key) {
-
-                case 'FREQ' :
-                    $value = strtolower($value);
-                    if (!in_array(
-                        $value,
-                        array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
-                    )) {
-                        throw new InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
-                    }
-                    $this->frequency = $value;
-                    break;
-
-                case 'UNTIL' :
-                    $this->until = DateTimeParser::parse($value, $this->startDate->getTimezone());
-
-                    // In some cases events are generated with an UNTIL=
-                    // parameter before the actual start of the event.
-                    //
-                    // Not sure why this is happening. We assume that the
-                    // intention was that the event only recurs once.
-                    //
-                    // So we are modifying the parameter so our code doesn't
-                    // break.
-                    if($this->until < $this->startDate) {
-                        $this->until = $this->startDate;
-                    }
-                    break;
-
-                case 'INTERVAL' :
-                    // No break
-
-                case 'COUNT' :
-                    $val = (int)$value;
-                    if ($val < 1) {
-                        throw new \InvalidArgumentException(strtoupper($key) . ' in RRULE must be a positive integer!');
-                    }
-                    $key = strtolower($key);
-                    $this->$key = $val;
-                    break;
-
-                case 'BYSECOND' :
-                    $this->bySecond = (array)$value;
-                    break;
-
-                case 'BYMINUTE' :
-                    $this->byMinute = (array)$value;
-                    break;
-
-                case 'BYHOUR' :
-                    $this->byHour = (array)$value;
-                    break;
-
-                case 'BYDAY' :
-                    $value = (array)$value;
-                    foreach($value as $part) {
-                        if (!preg_match('#^  (-|\+)? ([1-5])? (MO|TU|WE|TH|FR|SA|SU) $# xi', $part)) {
-                            throw new \InvalidArgumentException('Invalid part in BYDAY clause: ' . $part);
-                        }
-                    }
-                    $this->byDay = $value;
-                    break;
-
-                case 'BYMONTHDAY' :
-                    $this->byMonthDay = (array)$value;
-                    break;
-
-                case 'BYYEARDAY' :
-                    $this->byYearDay = (array)$value;
-                    break;
-
-                case 'BYWEEKNO' :
-                    $this->byWeekNo = (array)$value;
-                    break;
-
-                case 'BYMONTH' :
-                    $this->byMonth = (array)$value;
-                    break;
-
-                case 'BYSETPOS' :
-                    $this->bySetPos = (array)$value;
-                    break;
-
-                case 'WKST' :
-                    $this->weekStart = strtoupper($value);
-                    break;
-
-                default:
-                    throw new \InvalidArgumentException('Not supported: ' . strtoupper($key));
-
-            }
-
-        }
-
-    }
-
-    /**
-     * Mappings between the day number and english day name.
-     *
-     * @var array
-     */
-    protected $dayNames = array(
-        0 => 'Sunday',
-        1 => 'Monday',
-        2 => 'Tuesday',
-        3 => 'Wednesday',
-        4 => 'Thursday',
-        5 => 'Friday',
-        6 => 'Saturday',
-    );
-
-    /**
-     * Returns all the occurrences for a monthly frequency with a 'byDay' or
-     * 'byMonthDay' expansion for the current month.
-     *
-     * The returned list is an array of integers with the day of month (1-31).
-     *
-     * @return array
-     */
-    protected function getMonthlyOccurrences() {
-
-        $startDate = clone $this->currentDate;
-
-        $byDayResults = array();
-
-        // Our strategy is to simply go through the byDays, advance the date to
-        // that point and add it to the results.
-        if ($this->byDay) foreach($this->byDay as $day) {
-
-            $dayName = $this->dayNames[$this->dayMap[substr($day,-2)]];
-
-
-            // Dayname will be something like 'wednesday'. Now we need to find
-            // all wednesdays in this month.
-            $dayHits = array();
-
-            // workaround for missing 'first day of the month' support in hhvm
-            $checkDate = new \DateTime($startDate->format('Y-m-1'));
-            // workaround modify always advancing the date even if the current day is a $dayName in hhvm
-            if ($checkDate->format('l') !== $dayName) {
-                $checkDate->modify($dayName);
-            }
-
-            do {
-                $dayHits[] = $checkDate->format('j');
-                $checkDate->modify('next ' . $dayName);
-            } while ($checkDate->format('n') === $startDate->format('n'));
-
-            // So now we have 'all wednesdays' for month. It is however
-            // possible that the user only really wanted the 1st, 2nd or last
-            // wednesday.
-            if (strlen($day)>2) {
-                $offset = (int)substr($day,0,-2);
-
-                if ($offset>0) {
-                    // It is possible that the day does not exist, such as a
-                    // 5th or 6th wednesday of the month.
-                    if (isset($dayHits[$offset-1])) {
-                        $byDayResults[] = $dayHits[$offset-1];
-                    }
-                } else {
-
-                    // if it was negative we count from the end of the array
-                    $byDayResults[] = $dayHits[count($dayHits) + $offset];
-                }
-            } else {
-                // There was no counter (first, second, last wednesdays), so we
-                // just need to add the all to the list).
-                $byDayResults = array_merge($byDayResults, $dayHits);
-
-            }
-
-        }
-
-        $byMonthDayResults = array();
-        if ($this->byMonthDay) foreach($this->byMonthDay as $monthDay) {
-
-            // Removing values that are out of range for this month
-            if ($monthDay > $startDate->format('t') ||
-                $monthDay < 0-$startDate->format('t')) {
-                    continue;
-            }
-            if ($monthDay>0) {
-                $byMonthDayResults[] = $monthDay;
-            } else {
-                // Negative values
-                $byMonthDayResults[] = $startDate->format('t') + 1 + $monthDay;
-            }
-        }
-
-        // If there was just byDay or just byMonthDay, they just specify our
-        // (almost) final list. If both were provided, then byDay limits the
-        // list.
-        if ($this->byMonthDay && $this->byDay) {
-            $result = array_intersect($byMonthDayResults, $byDayResults);
-        } elseif ($this->byMonthDay) {
-            $result = $byMonthDayResults;
-        } else {
-            $result = $byDayResults;
-        }
-        $result = array_unique($result);
-        sort($result, SORT_NUMERIC);
-
-        // The last thing that needs checking is the BYSETPOS. If it's set, it
-        // means only certain items in the set survive the filter.
-        if (!$this->bySetPos) {
-            return $result;
-        }
-
-        $filteredResult = array();
-        foreach($this->bySetPos as $setPos) {
-
-            if ($setPos<0) {
-                $setPos = count($result)-($setPos+1);
-            }
-            if (isset($result[$setPos-1])) {
-                $filteredResult[] = $result[$setPos-1];
-            }
-        }
-
-        sort($filteredResult, SORT_NUMERIC);
-        return $filteredResult;
-
-    }
-
-    /**
-     * Simple mapping from iCalendar day names to day numbers
-     *
-     * @var array
-     */
-    protected $dayMap = array(
-        'SU' => 0,
-        'MO' => 1,
-        'TU' => 2,
-        'WE' => 3,
-        'TH' => 4,
-        'FR' => 5,
-        'SA' => 6,
-    );
-
-    protected function getHours()
-    {
-        $recurrenceHours = array();
-        foreach($this->byHour as $byHour) {
-            $recurrenceHours[] = $byHour;
-        }
-
-        return $recurrenceHours;
-    }
-
-    protected function getDays() {
-
-        $recurrenceDays = array();
-        foreach($this->byDay as $byDay) {
-
-            // The day may be preceeded with a positive (+n) or
-            // negative (-n) integer. However, this does not make
-            // sense in 'weekly' so we ignore it here.
-            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
-
-        }
-
-        return $recurrenceDays;
-    }
-
-    protected function getMonths() {
-
-        $recurrenceMonths = array();
-        foreach($this->byMonth as $byMonth) {
-            $recurrenceMonths[] = $byMonth;
-        }
-
-        return $recurrenceMonths;
-    }
-}
--- a/vendor/sabre/vobject/lib/RecurrenceIterator.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use Sabre\VObject\Recur\EventIterator;
-
-/**
- * RecurrenceIterator
- *
- * This class is deprecated. Use Sabre\VObject\Recur\EventIterator instead.
- * This class will be removed from a future version.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @deprecated
- * @license http://sabre.io/license Modified BSD License
- */
-class RecurrenceIterator extends EventIterator {
-
-
-}
--- a/vendor/sabre/vobject/lib/Splitter/ICalendar.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-use
-    Sabre\VObject,
-    Sabre\VObject\Component\VCalendar;
-
-/**
- * Splitter
- *
- * This class is responsible for splitting up iCalendar objects.
- *
- * This class expects a single VCALENDAR object with one or more
- * calendar-objects inside. Objects with identical UID's will be combined into
- * a single object.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Dominik Tobschall
- * @author Armin Hackmann
- * @license http://sabre.io/license/ Modified BSD License
- */
-class ICalendar implements SplitterInterface {
-
-    /**
-     * Timezones
-     *
-     * @var array
-     */
-    protected $vtimezones = array();
-
-    /**
-     * iCalendar objects
-     *
-     * @var array
-     */
-    protected $objects = array();
-
-    /**
-     * Constructor
-     *
-     * The splitter should receive an readable file stream as it's input.
-     *
-     * @param resource $input
-     * @param int $options Parser options, see the OPTIONS constants.
-     */
-    public function __construct($input, $options = 0) {
-
-        $data = VObject\Reader::read($input, $options);
-        $vtimezones = array();
-        $components = array();
-
-        if (!$data instanceof VObject\Component\VCalendar) {
-            throw new VObject\ParseException('Supplied input could not be parsed as VCALENDAR.');
-        }
-
-        foreach($data->children() as $component) {
-            if (!$component instanceof VObject\Component) {
-                continue;
-            }
-
-            // Get all timezones
-            if ($component->name === 'VTIMEZONE') {
-                $this->vtimezones[(string)$component->TZID] = $component;
-                continue;
-            }
-
-            // Get component UID for recurring Events search
-            if(!$component->UID) {
-                $component->UID = sha1(microtime()) . '-vobjectimport';
-            }
-            $uid = (string)$component->UID;
-
-            // Take care of recurring events
-            if (!array_key_exists($uid, $this->objects)) {
-                $this->objects[$uid] = new VCalendar();
-            }
-
-            $this->objects[$uid]->add(clone $component);
-        }
-
-    }
-
-    /**
-     * Every time getNext() is called, a new object will be parsed, until we
-     * hit the end of the stream.
-     *
-     * When the end is reached, null will be returned.
-     *
-     * @return Sabre\VObject\Component|null
-     */
-    public function getNext() {
-
-        if($object=array_shift($this->objects)) {
-
-            // create our baseobject
-            $object->version = '2.0';
-            $object->prodid = '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN';
-            $object->calscale = 'GREGORIAN';
-
-            // add vtimezone information to obj (if we have it)
-            foreach ($this->vtimezones as $vtimezone) {
-                $object->add($vtimezone);
-            }
-
-            return $object;
-
-        } else {
-
-            return null;
-
-        }
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/Splitter/SplitterInterface.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-/**
- * VObject splitter
- *
- * The splitter is responsible for reading a large vCard or iCalendar object,
- * and splitting it into multiple objects.
- *
- * This is for example for Card and CalDAV, which require every event and vcard
- * to exist in their own objects, instead of one large one.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Dominik Tobschall
- * @license http://sabre.io/license/ Modified BSD License
- */
-interface SplitterInterface {
-
-    /**
-     * Constructor
-     *
-     * The splitter should receive an readable file stream as it's input.
-     *
-     * @param resource $input
-     */
-    public function __construct($input);
-
-    /**
-     * Every time getNext() is called, a new object will be parsed, until we
-     * hit the end of the stream.
-     *
-     * When the end is reached, null will be returned.
-     *
-     * @return Sabre\VObject\Component|null
-     */
-    public function getNext();
-
-}
--- a/vendor/sabre/vobject/lib/Splitter/VCard.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-use
-    Sabre\VObject,
-    Sabre\VObject\Parser\MimeDir;
-
-/**
- * Splitter
- *
- * This class is responsible for splitting up VCard objects.
- *
- * It is assumed that the input stream contains 1 or more VCARD objects. This
- * class checks for BEGIN:VCARD and END:VCARD and parses each encountered
- * component individually.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Dominik Tobschall
- * @author Armin Hackmann
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VCard implements SplitterInterface {
-
-    /**
-     * File handle
-     *
-     * @var resource
-     */
-    protected $input;
-
-    /**
-     * Persistent parser
-     *
-     * @var MimeDir
-     */
-    protected $parser;
-
-    /**
-     * Constructor
-     *
-     * The splitter should receive an readable file stream as it's input.
-     *
-     * @param resource $input
-     * @param int $options Parser options, see the OPTIONS constants.
-     */
-    public function __construct($input, $options = 0) {
-
-        $this->input = $input;
-        $this->parser = new MimeDir($input, $options);
-
-    }
-
-    /**
-     * Every time getNext() is called, a new object will be parsed, until we
-     * hit the end of the stream.
-     *
-     * When the end is reached, null will be returned.
-     *
-     * @return Sabre\VObject\Component|null
-     */
-    public function getNext() {
-
-        try {
-            $object = $this->parser->parse();
-
-            if (!$object instanceof VObject\Component\VCard) {
-                throw new VObject\ParseException('The supplied input contained non-VCARD data.');
-            }
-
-        } catch (VObject\EofException $e) {
-            return null;
-        }
-
-        return $object;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/StringUtil.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Useful utilities for working with various strings.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class StringUtil {
-
-    /**
-     * Returns true or false depending on if a string is valid UTF-8
-     *
-     * @param string $str
-     * @return bool
-     */
-    static public function isUTF8($str) {
-
-        // Control characters
-        if (preg_match('%[\x00-\x08\x0B-\x0C\x0E\x0F]%', $str)) {
-            return false;
-        }
-
-        return (bool)preg_match('%%u', $str);
-
-    }
-
-    /**
-     * This method tries its best to convert the input string to UTF-8.
-     *
-     * Currently only ISO-5991-1 input and UTF-8 input is supported, but this
-     * may be expanded upon if we receive other examples.
-     *
-     * @param string $str
-     * @return string
-     */
-    static public function convertToUTF8($str) {
-
-        $encoding = mb_detect_encoding($str , array('UTF-8','ISO-8859-1', 'WINDOWS-1252'), true);
-
-        switch($encoding) {
-            case 'ISO-8859-1' :
-                $newStr = utf8_encode($str);
-                break;
-            /* Unreachable code. Not sure yet how we can improve this
-             * situation.
-            case 'WINDOWS-1252' :
-                $newStr = iconv('cp1252', 'UTF-8', $str);
-                break;
-             */
-            default :
-                 $newStr = $str;
-
-        }
-
-        // Removing any control characters
-        return (preg_replace('%(?:[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', '', $newStr));
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/lib/TimeZoneUtil.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,265 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Time zone name translation
- *
- * This file translates well-known time zone names into "Olson database" time zone names.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Frank Edelhaeuser (fedel@users.sourceforge.net)
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class TimeZoneUtil {
-
-    public static $map = null;
-
-    /**
-     * List of microsoft exchange timezone ids.
-     *
-     * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx
-     */
-    public static $microsoftExchangeMap = array(
-        0  => 'UTC',
-        31 => 'Africa/Casablanca',
-
-        // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo.
-        // I'm not even kidding.. We handle this special case in the
-        // getTimeZone method.
-        2  => 'Europe/Lisbon',
-        1  => 'Europe/London',
-        4  => 'Europe/Berlin',
-        6  => 'Europe/Prague',
-        3  => 'Europe/Paris',
-        69 => 'Africa/Luanda', // This was a best guess
-        7  => 'Europe/Athens',
-        5  => 'Europe/Bucharest',
-        49 => 'Africa/Cairo',
-        50 => 'Africa/Harare',
-        59 => 'Europe/Helsinki',
-        27 => 'Asia/Jerusalem',
-        26 => 'Asia/Baghdad',
-        74 => 'Asia/Kuwait',
-        51 => 'Europe/Moscow',
-        56 => 'Africa/Nairobi',
-        25 => 'Asia/Tehran',
-        24 => 'Asia/Muscat', // Best guess
-        54 => 'Asia/Baku',
-        48 => 'Asia/Kabul',
-        58 => 'Asia/Yekaterinburg',
-        47 => 'Asia/Karachi',
-        23 => 'Asia/Calcutta',
-        62 => 'Asia/Kathmandu',
-        46 => 'Asia/Almaty',
-        71 => 'Asia/Dhaka',
-        66 => 'Asia/Colombo',
-        61 => 'Asia/Rangoon',
-        22 => 'Asia/Bangkok',
-        64 => 'Asia/Krasnoyarsk',
-        45 => 'Asia/Shanghai',
-        63 => 'Asia/Irkutsk',
-        21 => 'Asia/Singapore',
-        73 => 'Australia/Perth',
-        75 => 'Asia/Taipei',
-        20 => 'Asia/Tokyo',
-        72 => 'Asia/Seoul',
-        70 => 'Asia/Yakutsk',
-        19 => 'Australia/Adelaide',
-        44 => 'Australia/Darwin',
-        18 => 'Australia/Brisbane',
-        76 => 'Australia/Sydney',
-        43 => 'Pacific/Guam',
-        42 => 'Australia/Hobart',
-        68 => 'Asia/Vladivostok',
-        41 => 'Asia/Magadan',
-        17 => 'Pacific/Auckland',
-        40 => 'Pacific/Fiji',
-        67 => 'Pacific/Tongatapu',
-        29 => 'Atlantic/Azores',
-        53 => 'Atlantic/Cape_Verde',
-        30 => 'America/Noronha',
-         8 => 'America/Sao_Paulo', // Best guess
-        32 => 'America/Argentina/Buenos_Aires',
-        60 => 'America/Godthab',
-        28 => 'America/St_Johns',
-         9 => 'America/Halifax',
-        33 => 'America/Caracas',
-        65 => 'America/Santiago',
-        35 => 'America/Bogota',
-        10 => 'America/New_York',
-        34 => 'America/Indiana/Indianapolis',
-        55 => 'America/Guatemala',
-        11 => 'America/Chicago',
-        37 => 'America/Mexico_City',
-        36 => 'America/Edmonton',
-        38 => 'America/Phoenix',
-        12 => 'America/Denver', // Best guess
-        13 => 'America/Los_Angeles', // Best guess
-        14 => 'America/Anchorage',
-        15 => 'Pacific/Honolulu',
-        16 => 'Pacific/Midway',
-        39 => 'Pacific/Kwajalein',
-    );
-
-    /**
-     * This method will try to find out the correct timezone for an iCalendar
-     * date-time value.
-     *
-     * You must pass the contents of the TZID parameter, as well as the full
-     * calendar.
-     *
-     * If the lookup fails, this method will return the default PHP timezone
-     * (as configured using date_default_timezone_set, or the date.timezone ini
-     * setting).
-     *
-     * Alternatively, if $failIfUncertain is set to true, it will throw an
-     * exception if we cannot accurately determine the timezone.
-     *
-     * @param string $tzid
-     * @param Sabre\VObject\Component $vcalendar
-     * @return DateTimeZone
-     */
-    static public function getTimeZone($tzid, Component $vcalendar = null, $failIfUncertain = false) {
-
-        // First we will just see if the tzid is a support timezone identifier.
-        //
-        // The only exception is if the timezone starts with (. This is to
-        // handle cases where certain microsoft products generate timezone
-        // identifiers that for instance look like:
-        //
-        // (GMT+01.00) Sarajevo/Warsaw/Zagreb
-        //
-        // Since PHP 5.5.10, the first bit will be used as the timezone and
-        // this method will return just GMT+01:00. This is wrong, because it
-        // doesn't take DST into account.
-        if ($tzid[0]!=='(') {
-
-            // PHP has a bug that logs PHP warnings even it shouldn't:
-            // https://bugs.php.net/bug.php?id=67881
-            //
-            // That's why we're checking if we'll be able to successfull instantiate
-            // \DateTimeZone() before doing so. Otherwise we could simply instantiate
-            // and catch the exception.
-            $tzIdentifiers = \DateTimeZone::listIdentifiers();
-
-            try {
-                if (
-                    (in_array($tzid, $tzIdentifiers)) ||
-                    (preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches)) ||
-                    (in_array($tzid, self::getIdentifiersBC()))
-                ) {
-                    return new \DateTimeZone($tzid);
-                }
-            } catch(\Exception $e) {
-            }
-
-        }
-
-        self::loadTzMaps();
-
-        // Next, we check if the tzid is somewhere in our tzid map.
-        if (isset(self::$map[$tzid])) {
-            return new \DateTimeZone(self::$map[$tzid]);
-        }
-
-        // Maybe the author was hyper-lazy and just included an offset. We
-        // support it, but we aren't happy about it.
-        if (preg_match('/^GMT(\+|-)([0-9]{4})$/', $tzid, $matches)) {
-
-            // Note that the path in the source will never be taken from PHP 5.5.10
-            // onwards. PHP 5.5.10 supports the "GMT+0100" style of format, so it
-            // already gets returned early in this function. Once we drop support
-            // for versions under PHP 5.5.10, this bit can be taken out of the
-            // source.
-            // @codeCoverageIgnoreStart
-            return new \DateTimeZone('Etc/GMT' . $matches[1] . ltrim(substr($matches[2],0,2),'0'));
-            // @codeCoverageIgnoreEnd
-        }
-
-        if ($vcalendar) {
-
-            // If that didn't work, we will scan VTIMEZONE objects
-            foreach($vcalendar->select('VTIMEZONE') as $vtimezone) {
-
-                if ((string)$vtimezone->TZID === $tzid) {
-
-                    // Some clients add 'X-LIC-LOCATION' with the olson name.
-                    if (isset($vtimezone->{'X-LIC-LOCATION'})) {
-
-                        $lic = (string)$vtimezone->{'X-LIC-LOCATION'};
-
-                        // Libical generators may specify strings like
-                        // "SystemV/EST5EDT". For those we must remove the
-                        // SystemV part.
-                        if (substr($lic,0,8)==='SystemV/') {
-                            $lic = substr($lic,8);
-                        }
-
-                        return self::getTimeZone($lic, null, $failIfUncertain);
-
-                    }
-                    // Microsoft may add a magic number, which we also have an
-                    // answer for.
-                    if (isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) {
-                        $cdoId = (int)$vtimezone->{'X-MICROSOFT-CDO-TZID'}->getValue();
-
-                        // 2 can mean both Europe/Lisbon and Europe/Sarajevo.
-                        if ($cdoId===2 && strpos((string)$vtimezone->TZID, 'Sarajevo')!==false) {
-                            return new \DateTimeZone('Europe/Sarajevo');
-                        }
-
-                        if (isset(self::$microsoftExchangeMap[$cdoId])) {
-                            return new \DateTimeZone(self::$microsoftExchangeMap[$cdoId]);
-                        }
-                    }
-
-                }
-
-            }
-
-        }
-
-        if ($failIfUncertain) {
-            throw new \InvalidArgumentException('We were unable to determine the correct PHP timezone for tzid: ' . $tzid);
-        }
-
-        // If we got all the way here, we default to UTC.
-        return new \DateTimeZone(date_default_timezone_get());
-
-    }
-
-    /**
-     * This method will load in all the tz mapping information, if it's not yet
-     * done.
-     */
-    static public function loadTzMaps() {
-
-        if (!is_null(self::$map)) return;
-
-        self::$map = array_merge(
-            include __DIR__ .  '/timezonedata/windowszones.php',
-            include __DIR__ .  '/timezonedata/lotuszones.php',
-            include __DIR__ .  '/timezonedata/exchangezones.php',
-            include __DIR__ .  '/timezonedata/php-workaround.php'
-        );
-
-    }
-
-    /**
-     * This method returns an array of timezone identifiers, that are supported
-     * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers()
-     *
-     * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because:
-     * - It's not supported by some PHP versions as well as HHVM.
-     * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions.
-     * (See timezonedata/php-bc.php and timezonedata php-workaround.php)
-     *
-     * @return array
-     */
-    static public function getIdentifiersBC() {
-        return include __DIR__ .  '/timezonedata/php-bc.php';
-    }
-
-}
--- a/vendor/sabre/vobject/lib/UUIDUtil.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * UUID Utility
- *
- * This class has static methods to generate and validate UUID's.
- * UUIDs are used a decent amount within various *DAV standards, so it made
- * sense to include it.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class UUIDUtil {
-
-    /**
-     * Returns a pseudo-random v4 UUID
-     *
-     * This function is based on a comment by Andrew Moore on php.net
-     *
-     * @see http://www.php.net/manual/en/function.uniqid.php#94959
-     * @return string
-     */
-    static public function getUUID() {
-
-        return sprintf(
-
-            '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
-
-            // 32 bits for "time_low"
-            mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
-
-            // 16 bits for "time_mid"
-            mt_rand( 0, 0xffff ),
-
-            // 16 bits for "time_hi_and_version",
-            // four most significant bits holds version number 4
-            mt_rand( 0, 0x0fff ) | 0x4000,
-
-            // 16 bits, 8 bits for "clk_seq_hi_res",
-            // 8 bits for "clk_seq_low",
-            // two most significant bits holds zero and one for variant DCE1.1
-            mt_rand( 0, 0x3fff ) | 0x8000,
-
-            // 48 bits for "node"
-            mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
-        );
-    }
-
-    /**
-     * Checks if a string is a valid UUID.
-     *
-     * @param string $uuid
-     * @return bool
-     */
-    static public function validateUUID($uuid) {
-
-        return preg_match(
-            '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i',
-            $uuid
-        ) == true;
-
-    }
-
-}
--- a/vendor/sabre/vobject/lib/VCardConverter.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,459 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This utility converts vcards from one version to another.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class VCardConverter {
-
-    /**
-     * Converts a vCard object to a new version.
-     *
-     * targetVersion must be one of:
-     *   Document::VCARD21
-     *   Document::VCARD30
-     *   Document::VCARD40
-     *
-     * Currently only 3.0 and 4.0 as input and output versions.
-     *
-     * 2.1 has some minor support for the input version, it's incomplete at the
-     * moment though.
-     *
-     * If input and output version are identical, a clone is returned.
-     *
-     * @param Component\VCard $input
-     * @param int $targetVersion
-     */
-    public function convert(Component\VCard $input, $targetVersion) {
-
-        $inputVersion = $input->getDocumentType();
-        if ($inputVersion===$targetVersion) {
-            return clone $input;
-        }
-
-        if (!in_array($inputVersion, array(Document::VCARD21, Document::VCARD30, Document::VCARD40))) {
-            throw new \InvalidArgumentException('Only vCard 2.1, 3.0 and 4.0 are supported for the input data');
-        }
-        if (!in_array($targetVersion, array(Document::VCARD30, Document::VCARD40))) {
-            throw new \InvalidArgumentException('You can only use vCard 3.0 or 4.0 for the target version');
-        }
-
-        $newVersion = $targetVersion===Document::VCARD40?'4.0':'3.0';
-
-        $output = new Component\VCard(array(
-            'VERSION' => $newVersion,
-        ));
-
-        foreach($input->children as $property) {
-
-            $this->convertProperty($input, $output, $property, $targetVersion);
-
-        }
-
-        return $output;
-
-    }
-
-    /**
-     * Handles conversion of a single property.
-     *
-     * @param Component\VCard $input
-     * @param Component\VCard $output
-     * @param Property $property
-     * @param int $targetVersion
-     * @return void
-     */
-    protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) {
-
-        // Skipping these, those are automatically added.
-        if (in_array($property->name, array('VERSION', 'PRODID'))) {
-            return;
-        }
-
-        $parameters = $property->parameters();
-        $valueType = null;
-        if (isset($parameters['VALUE'])) {
-            $valueType = $parameters['VALUE']->getValue();
-            unset($parameters['VALUE']);
-        }
-        if (!$valueType) {
-            $valueType = $property->getValueType();
-        }
-        $newProperty = $output->createProperty(
-            $property->name,
-            $property->getParts(),
-            array(), // parameters will get added a bit later.
-            $valueType
-        );
-
-
-        if ($targetVersion===Document::VCARD30) {
-
-            if ($property instanceof Property\Uri && in_array($property->name, array('PHOTO','LOGO','SOUND'))) {
-
-                $newProperty = $this->convertUriToBinary($output, $newProperty);
-
-            } elseif ($property instanceof Property\VCard\DateAndOrTime) {
-
-                // In vCard 4, the birth year may be optional. This is not the
-                // case for vCard 3. Apple has a workaround for this that
-                // allows applications that support Apple's extension still
-                // omit birthyears in vCard 3, but applications that do not
-                // support this, will just use a random birthyear. We're
-                // choosing 1604 for the birthyear, because that's what apple
-                // uses.
-                $parts = DateTimeParser::parseVCardDateTime($property->getValue());
-                if (is_null($parts['year'])) {
-                    $newValue = '1604-' . $parts['month'] . '-' . $parts['date'];
-                    $newProperty->setValue($newValue);
-                    $newProperty['X-APPLE-OMIT-YEAR'] = '1604';
-                }
-
-                if ($newProperty->name == 'ANNIVERSARY') {
-                    // Microsoft non-standard anniversary
-                    $newProperty->name = 'X-ANNIVERSARY';
-
-                    // We also need to add a new apple property for the same
-                    // purpose. This apple property needs a 'label' in the same
-                    // group, so we first need to find a groupname that doesn't
-                    // exist yet.
-                    $x = 1;
-                    while($output->select('ITEM' . $x . '.')) {
-                        $x++;
-                    }
-                    $output->add('ITEM' . $x . '.X-ABDATE', $newProperty->getValue(), array('VALUE' => 'DATE-AND-OR-TIME'));
-                    $output->add('ITEM' . $x . '.X-ABLABEL', '_$!<Anniversary>!$_');
-                }
-
-            } elseif ($property->name === 'KIND') {
-
-                switch(strtolower($property->getValue())) {
-                    case 'org' :
-                        // vCard 3.0 does not have an equivalent to KIND:ORG,
-                        // but apple has an extension that means the same
-                        // thing.
-                        $newProperty = $output->createProperty('X-ABSHOWAS','COMPANY');
-                        break;
-
-                    case 'individual' :
-                        // Individual is implicit, so we skip it.
-                        return;
-
-                    case 'group' :
-                        // OS X addressbook property
-                        $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND','GROUP');
-                        break;
-                }
-
-
-            }
-
-        } elseif ($targetVersion===Document::VCARD40) {
-
-            // These properties were removed in vCard 4.0
-            if (in_array($property->name, array('NAME', 'MAILER', 'LABEL', 'CLASS'))) {
-                return;
-            }
-
-            if ($property instanceof Property\Binary) {
-
-                $newProperty = $this->convertBinaryToUri($output, $newProperty, $parameters);
-
-            } elseif ($property instanceof Property\VCard\DateAndOrTime && isset($parameters['X-APPLE-OMIT-YEAR'])) {
-
-                // If a property such as BDAY contained 'X-APPLE-OMIT-YEAR',
-                // then we're stripping the year from the vcard 4 value.
-                $parts = DateTimeParser::parseVCardDateTime($property->getValue());
-                if ($parts['year']===$property['X-APPLE-OMIT-YEAR']->getValue()) {
-                    $newValue = '--' . $parts['month'] . '-' . $parts['date'];
-                    $newProperty->setValue($newValue);
-                }
-
-                // Regardless if the year matched or not, we do need to strip
-                // X-APPLE-OMIT-YEAR.
-                unset($parameters['X-APPLE-OMIT-YEAR']);
-
-            }
-            switch($property->name) {
-                case 'X-ABSHOWAS' :
-                    if (strtoupper($property->getValue()) === 'COMPANY') {
-                        $newProperty = $output->createProperty('KIND','ORG');
-                    }
-                    break;
-                case 'X-ADDRESSBOOKSERVER-KIND' :
-                    if (strtoupper($property->getValue()) === 'GROUP') {
-                        $newProperty = $output->createProperty('KIND','GROUP');
-                    }
-                    break;
-                case 'X-ANNIVERSARY' :
-                    $newProperty->name = 'ANNIVERSARY';
-                    // If we already have an anniversary property with the same
-                    // value, ignore.
-                    foreach ($output->select('ANNIVERSARY') as $anniversary) {
-                        if ($anniversary->getValue() === $newProperty->getValue()) {
-                            return;
-                        }
-                    }
-                    break;
-                case 'X-ABDATE' :
-                    // Find out what the label was, if it exists.
-                    if (!$property->group) {
-                        break;
-                    }
-                    $label = $input->{$property->group . '.X-ABLABEL'};
-
-                    // We only support converting anniversaries.
-                    if (!$label || $label->getValue()!=='_$!<Anniversary>!$_') {
-                        break;
-                    }
-
-                    // If we already have an anniversary property with the same
-                    // value, ignore.
-                    foreach ($output->select('ANNIVERSARY') as $anniversary) {
-                        if ($anniversary->getValue() === $newProperty->getValue()) {
-                            return;
-                        }
-                    }
-                    $newProperty->name = 'ANNIVERSARY';
-                    break;
-                // Apple's per-property label system.
-                case 'X-ABLABEL' :
-                    if($newProperty->getValue() === '_$!<Anniversary>!$_') {
-                        // We can safely remove these, as they are converted to
-                        // ANNIVERSARY properties.
-                        return;
-                    }
-                    break;
-
-            }
-
-        }
-
-        // set property group
-        $newProperty->group = $property->group;
-
-        if ($targetVersion===Document::VCARD40) {
-            $this->convertParameters40($newProperty, $parameters);
-        } else {
-            $this->convertParameters30($newProperty, $parameters);
-        }
-
-        // Lastly, we need to see if there's a need for a VALUE parameter.
-        //
-        // We can do that by instantating a empty property with that name, and
-        // seeing if the default valueType is identical to the current one.
-        $tempProperty = $output->createProperty($newProperty->name);
-        if ($tempProperty->getValueType() !== $newProperty->getValueType()) {
-            $newProperty['VALUE'] = $newProperty->getValueType();
-        }
-
-        $output->add($newProperty);
-
-
-    }
-
-    /**
-     * Converts a BINARY property to a URI property.
-     *
-     * vCard 4.0 no longer supports BINARY properties.
-     *
-     * @param Component\VCard $output
-     * @param Property\Uri $property The input property.
-     * @param $parameters List of parameters that will eventually be added to
-     *                    the new property.
-     * @return Property\Uri
-     */
-    protected function convertBinaryToUri(Component\VCard $output, Property\Binary $newProperty, array &$parameters) {
-
-        $value = $newProperty->getValue();
-        $newProperty = $output->createProperty(
-            $newProperty->name,
-            null, // no value
-            array(), // no parameters yet
-            'URI' // Forcing the BINARY type
-        );
-
-        $mimeType = 'application/octet-stream';
-
-        // See if we can find a better mimetype.
-        if (isset($parameters['TYPE'])) {
-
-            $newTypes = array();
-            foreach($parameters['TYPE']->getParts() as $typePart) {
-                if (in_array(
-                    strtoupper($typePart),
-                    array('JPEG','PNG','GIF')
-                )) {
-                    $mimeType = 'image/' . strtolower($typePart);
-                } else {
-                    $newTypes[] = $typePart;
-                }
-            }
-
-            // If there were any parameters we're not converting to a
-            // mime-type, we need to keep them.
-            if ($newTypes) {
-                $parameters['TYPE']->setParts($newTypes);
-            } else {
-                unset($parameters['TYPE']);
-            }
-
-        }
-
-        $newProperty->setValue('data:' . $mimeType . ';base64,' . base64_encode($value));
-        return $newProperty;
-
-    }
-
-    /**
-     * Converts a URI property to a BINARY property.
-     *
-     * In vCard 4.0 attachments are encoded as data: uri. Even though these may
-     * be valid in vCard 3.0 as well, we should convert those to BINARY if
-     * possible, to improve compatibility.
-     *
-     * @param Component\VCard $output
-     * @param Property\Uri $property The input property.
-     * @return Property\Binary|null
-     */
-    protected function convertUriToBinary(Component\VCard $output, Property\Uri $newProperty) {
-
-        $value = $newProperty->getValue();
-
-        // Only converting data: uris
-        if (substr($value, 0, 5)!=='data:') {
-            return $newProperty;
-        }
-
-        $newProperty = $output->createProperty(
-            $newProperty->name,
-            null, // no value
-            array(), // no parameters yet
-            'BINARY'
-        );
-
-        $mimeType = substr($value, 5, strpos($value, ',')-5);
-        if (strpos($mimeType, ';')) {
-            $mimeType = substr($mimeType,0,strpos($mimeType, ';'));
-            $newProperty->setValue(base64_decode(substr($value, strpos($value,',')+1)));
-        } else {
-            $newProperty->setValue(substr($value, strpos($value,',')+1));
-        }
-        unset($value);
-
-        $newProperty['ENCODING'] = 'b';
-        switch($mimeType) {
-
-            case 'image/jpeg' :
-                $newProperty['TYPE'] = 'JPEG';
-                break;
-            case 'image/png' :
-                $newProperty['TYPE'] = 'PNG';
-                break;
-            case 'image/gif' :
-                $newProperty['TYPE'] = 'GIF';
-                break;
-
-        }
-
-
-        return $newProperty;
-
-    }
-
-    /**
-     * Adds parameters to a new property for vCard 4.0
-     *
-     * @param Property $newProperty
-     * @param array $parameters
-     * @return void
-     */
-    protected function convertParameters40(Property $newProperty, array $parameters) {
-
-        // Adding all parameters.
-        foreach($parameters as $param) {
-
-            // vCard 2.1 allowed parameters with no name
-            if ($param->noName) $param->noName = false;
-
-            switch($param->name) {
-
-                // We need to see if there's any TYPE=PREF, because in vCard 4
-                // that's now PREF=1.
-                case 'TYPE' :
-                    foreach($param->getParts() as $paramPart) {
-
-                        if (strtoupper($paramPart)==='PREF') {
-                            $newProperty->add('PREF','1');
-                        } else {
-                            $newProperty->add($param->name, $paramPart);
-                        }
-
-                    }
-                    break;
-                // These no longer exist in vCard 4
-                case 'ENCODING' :
-                case 'CHARSET' :
-                    break;
-
-                default :
-                    $newProperty->add($param->name, $param->getParts());
-                    break;
-
-            }
-
-        }
-
-    }
-
-    /**
-     * Adds parameters to a new property for vCard 3.0
-     *
-     * @param Property $newProperty
-     * @param array $parameters
-     * @return void
-     */
-    protected function convertParameters30(Property $newProperty, array $parameters) {
-
-        // Adding all parameters.
-        foreach($parameters as $param) {
-
-            // vCard 2.1 allowed parameters with no name
-            if ($param->noName) $param->noName = false;
-
-            switch($param->name) {
-
-                case 'ENCODING' :
-                    // This value only existed in vCard 2.1, and should be
-                    // removed for anything else.
-                    if (strtoupper($param->getValue())!=='QUOTED-PRINTABLE') {
-                        $newProperty->add($param->name, $param->getParts());
-                    }
-                    break;
-
-                /*
-                 * Converting PREF=1 to TYPE=PREF.
-                 *
-                 * Any other PREF numbers we'll drop.
-                 */
-                case 'PREF' :
-                    if ($param->getValue()=='1') {
-                        $newProperty->add('TYPE','PREF');
-                    }
-                    break;
-
-                default :
-                    $newProperty->add($param->name, $param->getParts());
-                    break;
-
-            }
-
-        }
-
-    }
-}
--- a/vendor/sabre/vobject/lib/Version.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This class contains the version number for the VObject package
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class Version {
-
-    /**
-     * Full version number
-     */
-    const VERSION = '3.3.5';
-
-}
--- a/vendor/sabre/vobject/lib/timezonedata/exchangezones.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-<?php
-
-/**
- * Microsoft exchange timezones
- * Source:
- * http://msdn.microsoft.com/en-us/library/ms988620%28v=exchg.65%29.aspx
- *
- * Correct timezones deduced with help from:
- * http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @license http://sabre.io/license/ Modified BSD License
- */
-return array(
-    'Universal Coordinated Time' => 'UTC',
-    'Casablanca, Monrovia' => 'Africa/Casablanca',
-    'Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London' => 'Europe/Lisbon',
-    'Greenwich Mean Time; Dublin, Edinburgh, London' =>  'Europe/London',
-    'Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
-    'Belgrade, Pozsony, Budapest, Ljubljana, Prague' => 'Europe/Prague',
-    'Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
-    'Paris, Madrid, Brussels, Copenhagen' => 'Europe/Paris',
-    'Prague, Central Europe' => 'Europe/Prague',
-    'Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb' => 'Europe/Sarajevo',
-    'West Central Africa' => 'Africa/Luanda', // This was a best guess
-    'Athens, Istanbul, Minsk' => 'Europe/Athens',
-    'Bucharest' => 'Europe/Bucharest',
-    'Cairo' => 'Africa/Cairo',
-    'Harare, Pretoria' => 'Africa/Harare',
-    'Helsinki, Riga, Tallinn' => 'Europe/Helsinki',
-    'Israel, Jerusalem Standard Time' => 'Asia/Jerusalem',
-    'Baghdad' => 'Asia/Baghdad',
-    'Arab, Kuwait, Riyadh' => 'Asia/Kuwait',
-    'Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
-    'East Africa, Nairobi' => 'Africa/Nairobi',
-    'Tehran' => 'Asia/Tehran',
-    'Abu Dhabi, Muscat' => 'Asia/Muscat', // Best guess
-    'Baku, Tbilisi, Yerevan' => 'Asia/Baku',
-    'Kabul' => 'Asia/Kabul',
-    'Ekaterinburg' => 'Asia/Yekaterinburg',
-    'Islamabad, Karachi, Tashkent' => 'Asia/Karachi',
-    'Kolkata, Chennai, Mumbai, New Delhi, India Standard Time' => 'Asia/Calcutta',
-    'Kathmandu, Nepal' => 'Asia/Kathmandu',
-    'Almaty, Novosibirsk, North Central Asia' => 'Asia/Almaty',
-    'Astana, Dhaka' => 'Asia/Dhaka',
-    'Sri Jayawardenepura, Sri Lanka' => 'Asia/Colombo',
-    'Rangoon' => 'Asia/Rangoon',
-    'Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
-    'Krasnoyarsk' => 'Asia/Krasnoyarsk',
-    'Beijing, Chongqing, Hong Kong SAR, Urumqi' => 'Asia/Shanghai',
-    'Irkutsk, Ulaan Bataar' => 'Asia/Irkutsk',
-    'Kuala Lumpur, Singapore' => 'Asia/Singapore',
-    'Perth, Western Australia' => 'Australia/Perth',
-    'Taipei' => 'Asia/Taipei',
-    'Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
-    'Seoul, Korea Standard time' => 'Asia/Seoul',
-    'Yakutsk' => 'Asia/Yakutsk',
-    'Adelaide, Central Australia' => 'Australia/Adelaide',
-    'Darwin' => 'Australia/Darwin',
-    'Brisbane, East Australia' => 'Australia/Brisbane',
-    'Canberra, Melbourne, Sydney, Hobart (year 2000 only)' => 'Australia/Sydney',
-    'Guam, Port Moresby' => 'Pacific/Guam',
-    'Hobart, Tasmania' => 'Australia/Hobart',
-    'Vladivostok' => 'Asia/Vladivostok',
-    'Magadan, Solomon Is., New Caledonia' => 'Asia/Magadan',
-    'Auckland, Wellington' => 'Pacific/Auckland',
-    'Fiji Islands, Kamchatka, Marshall Is.' => 'Pacific/Fiji',
-    'Nuku\'alofa, Tonga' => 'Pacific/Tongatapu',
-    'Azores' => 'Atlantic/Azores',
-    'Cape Verde Is.' => 'Atlantic/Cape_Verde',
-    'Mid-Atlantic' => 'America/Noronha',
-    'Brasilia' => 'America/Sao_Paulo', // Best guess
-    'Buenos Aires' => 'America/Argentina/Buenos_Aires',
-    'Greenland' => 'America/Godthab',
-    'Newfoundland' => 'America/St_Johns',
-    'Atlantic Time (Canada)' => 'America/Halifax',
-    'Caracas, La Paz' => 'America/Caracas',
-    'Santiago' => 'America/Santiago',
-    'Bogota, Lima, Quito' => 'America/Bogota',
-    'Eastern Time (US & Canada)' => 'America/New_York',
-    'Indiana (East)' => 'America/Indiana/Indianapolis',
-    'Central America' => 'America/Guatemala',
-    'Central Time (US & Canada)' => 'America/Chicago',
-    'Mexico City, Tegucigalpa' => 'America/Mexico_City',
-    'Saskatchewan' => 'America/Edmonton',
-    'Arizona' => 'America/Phoenix',
-    'Mountain Time (US & Canada)' => 'America/Denver', // Best guess
-    'Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles', // Best guess
-    'Alaska' => 'America/Anchorage',
-    'Hawaii' => 'Pacific/Honolulu',
-    'Midway Island, Samoa' => 'Pacific/Midway',
-    'Eniwetok, Kwajalein, Dateline Time' => 'Pacific/Kwajalein',
-);
--- a/vendor/sabre/vobject/lib/timezonedata/lotuszones.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-<?php
-
-/**
- * The following list are timezone names that could be generated by
- * Lotus / Domino
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @license http://sabre.io/license/ Modified BSD License
- */
-return array(
-    'Dateline'               => 'Etc/GMT-12',
-    'Samoa'                  => 'Pacific/Apia',
-    'Hawaiian'               => 'Pacific/Honolulu',
-    'Alaskan'                => 'America/Anchorage',
-    'Pacific'                => 'America/Los_Angeles',
-    'Pacific Standard Time'  => 'America/Los_Angeles',
-    'Mexico Standard Time 2' => 'America/Chihuahua',
-    'Mountain'               => 'America/Denver',
-    // 'Mountain Standard Time' => 'America/Chihuahua', // conflict with windows timezones.
-    'US Mountain'            => 'America/Phoenix',
-    'Canada Central'         => 'America/Edmonton',
-    'Central America'        => 'America/Guatemala',
-    'Central'                => 'America/Chicago',
-    // 'Central Standard Time'  => 'America/Mexico_City', // conflict with windows timezones.
-    'Mexico'                 => 'America/Mexico_City',
-    'Eastern'                => 'America/New_York',
-    'SA Pacific'             => 'America/Bogota',
-    'US Eastern'             => 'America/Indiana/Indianapolis',
-    'Venezuela'              => 'America/Caracas',
-    'Atlantic'               => 'America/Halifax',
-    'Central Brazilian'      => 'America/Manaus',
-    'Pacific SA'             => 'America/Santiago',
-    'SA Western'             => 'America/La_Paz',
-    'Newfoundland'           => 'America/St_Johns',
-    'Argentina'              => 'America/Argentina/Buenos_Aires',
-    'E. South America'       => 'America/Belem',
-    'Greenland'              => 'America/Godthab',
-    'Montevideo'             => 'America/Montevideo',
-    'SA Eastern'             => 'America/Belem',
-    // 'Mid-Atlantic'           => 'Etc/GMT-2', // conflict with windows timezones.
-    'Azores'                 => 'Atlantic/Azores',
-    'Cape Verde'             => 'Atlantic/Cape_Verde',
-    'Greenwich'              => 'Atlantic/Reykjavik', // No I'm serious.. Greenwich is not GMT.
-    'Morocco'                => 'Africa/Casablanca',
-    'Central Europe'         => 'Europe/Prague',
-    'Central European'       => 'Europe/Sarajevo',
-    'Romance'                => 'Europe/Paris',
-    'W. Central Africa'      => 'Africa/Lagos', // Best guess
-    'W. Europe'              => 'Europe/Amsterdam',
-    'E. Europe'              => 'Europe/Minsk',
-    'Egypt'                  => 'Africa/Cairo',
-    'FLE'                    => 'Europe/Helsinki',
-    'GTB'                    => 'Europe/Athens',
-    'Israel'                 => 'Asia/Jerusalem',
-    'Jordan'                 => 'Asia/Amman',
-    'Middle East'            => 'Asia/Beirut',
-    'Namibia'                => 'Africa/Windhoek',
-    'South Africa'           => 'Africa/Harare',
-    'Arab'                   => 'Asia/Kuwait',
-    'Arabic'                 => 'Asia/Baghdad',
-    'E. Africa'              => 'Africa/Nairobi',
-    'Georgian'               => 'Asia/Tbilisi',
-    'Russian'                => 'Europe/Moscow',
-    'Iran'                   => 'Asia/Tehran',
-    'Arabian'                => 'Asia/Muscat',
-    'Armenian'               => 'Asia/Yerevan',
-    'Azerbijan'              => 'Asia/Baku',
-    'Caucasus'               => 'Asia/Yerevan',
-    'Mauritius'              => 'Indian/Mauritius',
-    'Afghanistan'            => 'Asia/Kabul',
-    'Ekaterinburg'           => 'Asia/Yekaterinburg',
-    'Pakistan'               => 'Asia/Karachi',
-    'West Asia'              => 'Asia/Tashkent',
-    'India'                  => 'Asia/Calcutta',
-    'Sri Lanka'              => 'Asia/Colombo',
-    'Nepal'                  => 'Asia/Kathmandu',
-    'Central Asia'           => 'Asia/Dhaka',
-    'N. Central Asia'        => 'Asia/Almaty',
-    'Myanmar'                => 'Asia/Rangoon',
-    'North Asia'             => 'Asia/Krasnoyarsk',
-    'SE Asia'                => 'Asia/Bangkok',
-    'China'                  => 'Asia/Shanghai',
-    'North Asia East'        => 'Asia/Irkutsk',
-    'Singapore'              => 'Asia/Singapore',
-    'Taipei'                 => 'Asia/Taipei',
-    'W. Australia'           => 'Australia/Perth',
-    'Korea'                  => 'Asia/Seoul',
-    'Tokyo'                  => 'Asia/Tokyo',
-    'Yakutsk'                => 'Asia/Yakutsk',
-    'AUS Central'            => 'Australia/Darwin',
-    'Cen. Australia'         => 'Australia/Adelaide',
-    'AUS Eastern'            => 'Australia/Sydney',
-    'E. Australia'           => 'Australia/Brisbane',
-    'Tasmania'               => 'Australia/Hobart',
-    'Vladivostok'            => 'Asia/Vladivostok',
-    'West Pacific'           => 'Pacific/Guam',
-    'Central Pacific'        => 'Asia/Magadan',
-    'Fiji'                   => 'Pacific/Fiji',
-    'New Zealand'            => 'Pacific/Auckland',
-    'Tonga'                  => 'Pacific/Tongatapu',
-);
--- a/vendor/sabre/vobject/lib/timezonedata/php-bc.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-<?php
-/**
- * A list of additional PHP timezones that are returned by
- * DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC)
- * valid for new DateTimeZone()
- *
- * This list does not include those timezone identifiers that we have to map to
- * a different identifier for some PHP versions (see php-workaround.php).
- *
- * Instead of using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC)
- * directly, we use this file because DateTimeZone::ALL_WITH_BC is not properly
- * supported by all PHP version and HHVM.
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @license http://sabre.io/license/ Modified BSD License
- */
-return array(
-    'Africa/Asmera',
-    'Africa/Timbuktu',
-    'America/Argentina/ComodRivadavia',
-    'America/Atka',
-    'America/Buenos_Aires',
-    'America/Catamarca',
-    'America/Coral_Harbour',
-    'America/Cordoba',
-    'America/Ensenada',
-    'America/Fort_Wayne',
-    'America/Indianapolis',
-    'America/Jujuy',
-    'America/Knox_IN',
-    'America/Louisville',
-    'America/Mendoza',
-    'America/Montreal',
-    'America/Porto_Acre',
-    'America/Rosario',
-    'America/Shiprock',
-    'America/Virgin',
-    'Antarctica/South_Pole',
-    'Asia/Ashkhabad',
-    'Asia/Calcutta',
-    'Asia/Chungking',
-    'Asia/Dacca',
-    'Asia/Istanbul',
-    'Asia/Katmandu',
-    'Asia/Macao',
-    'Asia/Saigon',
-    'Asia/Tel_Aviv',
-    'Asia/Thimbu',
-    'Asia/Ujung_Pandang',
-    'Asia/Ulan_Bator',
-    'Atlantic/Faeroe',
-    'Atlantic/Jan_Mayen',
-    'Australia/ACT',
-    'Australia/Canberra',
-    'Australia/LHI',
-    'Australia/North',
-    'Australia/NSW',
-    'Australia/Queensland',
-    'Australia/South',
-    'Australia/Tasmania',
-    'Australia/Victoria',
-    'Australia/West',
-    'Australia/Yancowinna',
-    'Brazil/Acre',
-    'Brazil/DeNoronha',
-    'Brazil/East',
-    'Brazil/West',
-    'Canada/Atlantic',
-    'Canada/Central',
-    'Canada/East-Saskatchewan',
-    'Canada/Eastern',
-    'Canada/Mountain',
-    'Canada/Newfoundland',
-    'Canada/Pacific',
-    'Canada/Saskatchewan',
-    'Canada/Yukon',
-    'CET',
-    'Chile/Continental',
-    'Chile/EasterIsland',
-    'EET',
-    'EST',
-    'Etc/GMT',
-    'Etc/GMT+0',
-    'Etc/GMT+1',
-    'Etc/GMT+10',
-    'Etc/GMT+11',
-    'Etc/GMT+12',
-    'Etc/GMT+2',
-    'Etc/GMT+3',
-    'Etc/GMT+4',
-    'Etc/GMT+5',
-    'Etc/GMT+6',
-    'Etc/GMT+7',
-    'Etc/GMT+8',
-    'Etc/GMT+9',
-    'Etc/GMT-0',
-    'Etc/GMT-1',
-    'Etc/GMT-10',
-    'Etc/GMT-11',
-    'Etc/GMT-12',
-    'Etc/GMT-13',
-    'Etc/GMT-14',
-    'Etc/GMT-2',
-    'Etc/GMT-3',
-    'Etc/GMT-4',
-    'Etc/GMT-5',
-    'Etc/GMT-6',
-    'Etc/GMT-7',
-    'Etc/GMT-8',
-    'Etc/GMT-9',
-    'Etc/GMT0',
-    'Etc/Greenwich',
-    'Etc/UCT',
-    'Etc/Universal',
-    'Etc/UTC',
-    'Etc/Zulu',
-    'Europe/Belfast',
-    'Europe/Nicosia',
-    'Europe/Tiraspol',
-    'GB',
-    'GMT',
-    'GMT+0',
-    'GMT-0',
-    'HST',
-    'MET',
-    'Mexico/BajaNorte',
-    'Mexico/BajaSur',
-    'Mexico/General',
-    'MST',
-    'NZ',
-    'Pacific/Ponape',
-    'Pacific/Samoa',
-    'Pacific/Truk',
-    'Pacific/Yap',
-    'PRC',
-    'ROC',
-    'ROK',
-    'UCT',
-    'US/Alaska',
-    'US/Aleutian',
-    'US/Arizona',
-    'US/Central',
-    'US/East-Indiana',
-    'US/Eastern',
-    'US/Hawaii',
-    'US/Indiana-Starke',
-    'US/Michigan',
-    'US/Mountain',
-    'US/Pacific',
-    'US/Pacific-New',
-    'US/Samoa',
-    'WET',
-);
--- a/vendor/sabre/vobject/lib/timezonedata/php-workaround.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-<?php
-/**
- * A list of PHP timezones that were supported until 5.5.9, removed in
- * PHP 5.5.10 and re-introduced in PHP 5.5.17
- *
- * DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) returns them,
- * but they are invalid for new DateTimeZone(). Fixed in PHP 5.5.17.
- * https://bugs.php.net/bug.php?id=66985
- *
- * Some more info here:
- * http://evertpot.com/php-5-5-10-timezone-changes/
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @license http://sabre.io/license/ Modified BSD License
- */
-return array(
-    'CST6CDT'   => 'America/Chicago',
-    'Cuba'      => 'America/Havana',
-    'Egypt'     => 'Africa/Cairo',
-    'Eire'      => 'Europe/Dublin',
-    'EST5EDT'   => 'America/New_York',
-    'Factory'   => 'UTC',
-    'GB-Eire'   => 'Europe/London',
-    'GMT0'      => 'UTC',
-    'Greenwich' => 'UTC',
-    'Hongkong'  => 'Asia/Hong_Kong',
-    'Iceland'   => 'Atlantic/Reykjavik',
-    'Iran'      => 'Asia/Tehran',
-    'Israel'    => 'Asia/Jerusalem',
-    'Jamaica'   => 'America/Jamaica',
-    'Japan'     => 'Asia/Tokyo',
-    'Kwajalein' => 'Pacific/Kwajalein',
-    'Libya'     => 'Africa/Tripoli',
-    'MST7MDT'   => 'America/Denver',
-    'Navajo'    => 'America/Denver',
-    'NZ-CHAT'   => 'Pacific/Chatham',
-    'Poland'    => 'Europe/Warsaw',
-    'Portugal'  => 'Europe/Lisbon',
-    'PST8PDT'   => 'America/Los_Angeles',
-    'Singapore' => 'Asia/Singapore',
-    'Turkey'    => 'Europe/Istanbul',
-    'Universal' => 'UTC',
-    'W-SU'      => 'Europe/Moscow',
-    'Zulu'      => 'UTC',
-);
--- a/vendor/sabre/vobject/lib/timezonedata/windowszones.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-<?php
-
-/**
- * Automatically generated timezone file
- *
- * Last update: 2014-10-03T07:58:31-04:00
- * Source: http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml
- *
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @license http://sabre.io/license/ Modified BSD License
- */
-
-return array (
-  'AUS Central Standard Time' => 'Australia/Darwin',
-  'AUS Eastern Standard Time' => 'Australia/Sydney',
-  'Afghanistan Standard Time' => 'Asia/Kabul',
-  'Alaskan Standard Time' => 'America/Anchorage',
-  'Arab Standard Time' => 'Asia/Riyadh',
-  'Arabian Standard Time' => 'Asia/Dubai',
-  'Arabic Standard Time' => 'Asia/Baghdad',
-  'Argentina Standard Time' => 'America/Buenos_Aires',
-  'Atlantic Standard Time' => 'America/Halifax',
-  'Azerbaijan Standard Time' => 'Asia/Baku',
-  'Azores Standard Time' => 'Atlantic/Azores',
-  'Bahia Standard Time' => 'America/Bahia',
-  'Bangladesh Standard Time' => 'Asia/Dhaka',
-  'Canada Central Standard Time' => 'America/Regina',
-  'Cape Verde Standard Time' => 'Atlantic/Cape_Verde',
-  'Caucasus Standard Time' => 'Asia/Yerevan',
-  'Cen. Australia Standard Time' => 'Australia/Adelaide',
-  'Central America Standard Time' => 'America/Guatemala',
-  'Central Asia Standard Time' => 'Asia/Almaty',
-  'Central Brazilian Standard Time' => 'America/Cuiaba',
-  'Central Europe Standard Time' => 'Europe/Budapest',
-  'Central European Standard Time' => 'Europe/Warsaw',
-  'Central Pacific Standard Time' => 'Pacific/Guadalcanal',
-  'Central Standard Time' => 'America/Chicago',
-  'Central Standard Time (Mexico)' => 'America/Mexico_City',
-  'China Standard Time' => 'Asia/Shanghai',
-  'Dateline Standard Time' => 'Etc/GMT+12',
-  'E. Africa Standard Time' => 'Africa/Nairobi',
-  'E. Australia Standard Time' => 'Australia/Brisbane',
-  'E. South America Standard Time' => 'America/Sao_Paulo',
-  'Eastern Standard Time' => 'America/New_York',
-  'Egypt Standard Time' => 'Africa/Cairo',
-  'Ekaterinburg Standard Time' => 'Asia/Yekaterinburg',
-  'FLE Standard Time' => 'Europe/Kiev',
-  'Fiji Standard Time' => 'Pacific/Fiji',
-  'GMT Standard Time' => 'Europe/London',
-  'GTB Standard Time' => 'Europe/Bucharest',
-  'Georgian Standard Time' => 'Asia/Tbilisi',
-  'Greenland Standard Time' => 'America/Godthab',
-  'Greenwich Standard Time' => 'Atlantic/Reykjavik',
-  'Hawaiian Standard Time' => 'Pacific/Honolulu',
-  'India Standard Time' => 'Asia/Calcutta',
-  'Iran Standard Time' => 'Asia/Tehran',
-  'Israel Standard Time' => 'Asia/Jerusalem',
-  'Jordan Standard Time' => 'Asia/Amman',
-  'Kaliningrad Standard Time' => 'Europe/Kaliningrad',
-  'Korea Standard Time' => 'Asia/Seoul',
-  'Libya Standard Time' => 'Africa/Tripoli',
-  'Line Islands Standard Time' => 'Pacific/Kiritimati',
-  'Magadan Standard Time' => 'Asia/Magadan',
-  'Mauritius Standard Time' => 'Indian/Mauritius',
-  'Middle East Standard Time' => 'Asia/Beirut',
-  'Montevideo Standard Time' => 'America/Montevideo',
-  'Morocco Standard Time' => 'Africa/Casablanca',
-  'Mountain Standard Time' => 'America/Denver',
-  'Mountain Standard Time (Mexico)' => 'America/Chihuahua',
-  'Myanmar Standard Time' => 'Asia/Rangoon',
-  'N. Central Asia Standard Time' => 'Asia/Novosibirsk',
-  'Namibia Standard Time' => 'Africa/Windhoek',
-  'Nepal Standard Time' => 'Asia/Katmandu',
-  'New Zealand Standard Time' => 'Pacific/Auckland',
-  'Newfoundland Standard Time' => 'America/St_Johns',
-  'North Asia East Standard Time' => 'Asia/Irkutsk',
-  'North Asia Standard Time' => 'Asia/Krasnoyarsk',
-  'Pacific SA Standard Time' => 'America/Santiago',
-  'Pacific Standard Time' => 'America/Los_Angeles',
-  'Pacific Standard Time (Mexico)' => 'America/Santa_Isabel',
-  'Pakistan Standard Time' => 'Asia/Karachi',
-  'Paraguay Standard Time' => 'America/Asuncion',
-  'Romance Standard Time' => 'Europe/Paris',
-  'Russian Standard Time' => 'Europe/Moscow',
-  'SA Eastern Standard Time' => 'America/Cayenne',
-  'SA Pacific Standard Time' => 'America/Bogota',
-  'SA Western Standard Time' => 'America/La_Paz',
-  'SE Asia Standard Time' => 'Asia/Bangkok',
-  'Samoa Standard Time' => 'Pacific/Apia',
-  'Singapore Standard Time' => 'Asia/Singapore',
-  'South Africa Standard Time' => 'Africa/Johannesburg',
-  'Sri Lanka Standard Time' => 'Asia/Colombo',
-  'Syria Standard Time' => 'Asia/Damascus',
-  'Taipei Standard Time' => 'Asia/Taipei',
-  'Tasmania Standard Time' => 'Australia/Hobart',
-  'Tokyo Standard Time' => 'Asia/Tokyo',
-  'Tonga Standard Time' => 'Pacific/Tongatapu',
-  'Turkey Standard Time' => 'Europe/Istanbul',
-  'US Eastern Standard Time' => 'America/Indianapolis',
-  'US Mountain Standard Time' => 'America/Phoenix',
-  'UTC' => 'Etc/GMT',
-  'UTC+12' => 'Etc/GMT-12',
-  'UTC-02' => 'Etc/GMT+2',
-  'UTC-11' => 'Etc/GMT+11',
-  'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar',
-  'Venezuela Standard Time' => 'America/Caracas',
-  'Vladivostok Standard Time' => 'Asia/Vladivostok',
-  'W. Australia Standard Time' => 'Australia/Perth',
-  'W. Central Africa Standard Time' => 'Africa/Lagos',
-  'W. Europe Standard Time' => 'Europe/Berlin',
-  'West Asia Standard Time' => 'Asia/Tashkent',
-  'West Pacific Standard Time' => 'Pacific/Port_Moresby',
-  'Yakutsk Standard Time' => 'Asia/Yakutsk',
-);
--- a/vendor/sabre/vobject/tests/VObject/AttachIssueTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class AttachIssueTest extends \PHPUnit_Framework_TestCase {
-
-    function testRead() {
-
-        $event = <<<ICS
-BEGIN:VCALENDAR\r
-BEGIN:VEVENT\r
-ATTACH;FMTTYPE=;ENCODING=:Zm9v\r
-END:VEVENT\r
-END:VCALENDAR\r
-
-ICS;
-        $obj = Reader::read($event);
-        $this->assertEquals($event, $obj->serialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/CliTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,650 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Tests the cli.
- *
- * Warning: these tests are very rudimentary.
- */
-class CliTest extends \PHPUnit_Framework_TestCase {
-
-    public function setUp() {
-
-        $this->cli = new CliMock();
-        $this->cli->stderr = fopen('php://memory','r+');
-        $this->cli->stdout = fopen('php://memory','r+');
-
-    }
-
-    public function testInvalidArg() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', '--hi'))
-        );
-        rewind($this->cli->stderr);
-        $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100);
-
-    }
-
-    public function testQuiet() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', '-q'))
-        );
-        $this->assertTrue($this->cli->quiet);
-
-        rewind($this->cli->stderr);
-        $this->assertEquals(0, strlen(stream_get_contents($this->cli->stderr)));
-
-    }
-
-    public function testHelp() {
-
-        $this->assertEquals(
-            0,
-            $this->cli->main(array('vobject', '-h'))
-        );
-        rewind($this->cli->stderr);
-        $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100);
-
-    }
-
-    public function testFormat() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', '--format=jcard'))
-        );
-
-        rewind($this->cli->stderr);
-        $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100);
-
-        $this->assertEquals('jcard', $this->cli->format);
-
-    }
-
-    public function testFormatInvalid() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', '--format=foo'))
-        );
-
-        rewind($this->cli->stderr);
-        $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100);
-
-        $this->assertNull($this->cli->format);
-
-    }
-
-    public function testInputFormatInvalid() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', '--inputformat=foo'))
-        );
-
-        rewind($this->cli->stderr);
-        $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100);
-
-        $this->assertNull($this->cli->format);
-
-    }
-
-
-    public function testNoInputFile() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', 'color'))
-        );
-
-        rewind($this->cli->stderr);
-        $this->assertTrue(strlen(stream_get_contents($this->cli->stderr)) > 100);
-
-    }
-
-    public function testTooManyArgs() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', 'color', 'a', 'b', 'c'))
-        );
-
-    }
-
-    public function testUnknownCommand() {
-
-        $this->assertEquals(
-            1,
-            $this->cli->main(array('vobject', 'foo', '-'))
-        );
-
-    }
-
-    public function testConvertJson() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<ICS
-BEGIN:VCARD
-VERSION:3.0
-FN:Cowboy Henk
-END:VCARD
-ICS
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        $this->assertEquals(
-            0,
-            $this->cli->main(array('vobject', 'convert','--format=json', '-'))
-        );
-
-        rewind($this->cli->stdout);
-        $version = Version::VERSION;
-        $this->assertEquals(
-            '["vcard",[["version",{},"text","4.0"],["prodid",{},"text","-\/\/Sabre\/\/Sabre VObject '. $version .'\/\/EN"],["fn",{},"text","Cowboy Henk"]]]',
-            stream_get_contents($this->cli->stdout)
-        );
-
-    }
-
-    public function testConvertJCardPretty() {
-
-        if (version_compare(PHP_VERSION, '5.4.0') < 0) {
-            $this->markTestSkipped('This test required PHP 5.4.0');
-        }
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<ICS
-BEGIN:VCARD
-VERSION:3.0
-FN:Cowboy Henk
-END:VCARD
-ICS
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        $this->assertEquals(
-            0,
-            $this->cli->main(array('vobject', 'convert','--format=jcard', '--pretty', '-'))
-        );
-
-        rewind($this->cli->stdout);
-        $version = Version::VERSION;
-
-        // PHP 5.5.12 changed the output
-
-        $expected = <<<JCARD
-[
-    "vcard",
-    [
-        [
-            "versi
-JCARD;
-
-          $this->assertStringStartsWith(
-            $expected,
-            stream_get_contents($this->cli->stdout)
-        );
-
-    }
-
-    public function testConvertJCalFail() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<ICS
-BEGIN:VCARD
-VERSION:3.0
-FN:Cowboy Henk
-END:VCARD
-ICS
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'convert','--format=jcal', '--inputformat=mimedir', '-'))
-        );
-
-    }
-
-    public function testConvertMimeDir() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<JCARD
-[
-    "vcard",
-    [
-        [
-            "version",
-            {
-
-            },
-            "text",
-            "4.0"
-        ],
-        [
-            "prodid",
-            {
-
-            },
-            "text",
-            "-\/\/Sabre\/\/Sabre VObject 3.1.0\/\/EN"
-        ],
-        [
-            "fn",
-            {
-
-            },
-            "text",
-            "Cowboy Henk"
-        ]
-    ]
-]
-JCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        $this->assertEquals(
-            0,
-            $this->cli->main(array('vobject', 'convert','--format=mimedir', '--inputformat=json', '--pretty', '-'))
-        );
-
-        rewind($this->cli->stdout);
-        $expected = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject 3.1.0//EN
-FN:Cowboy Henk
-END:VCARD
-
-VCF;
-
-          $this->assertEquals(
-            strtr($expected, array("\n"=>"\r\n")),
-            stream_get_contents($this->cli->stdout)
-        );
-
-    }
-
-    public function testConvertDefaultFormats() {
-
-        $inputStream = fopen('php://memory','r+');
-        $outputFile = SABRE_TEMPDIR . 'bar.json';
-
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'convert','foo.json',$outputFile))
-        );
-
-        $this->assertEquals('json', $this->cli->inputFormat);
-        $this->assertEquals('json', $this->cli->format);
-
-    }
-
-    public function testConvertDefaultFormats2() {
-
-        $outputFile = SABRE_TEMPDIR . 'bar.ics';
-
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'convert','foo.ics',$outputFile))
-        );
-
-        $this->assertEquals('mimedir', $this->cli->inputFormat);
-        $this->assertEquals('mimedir', $this->cli->format);
-
-    }
-
-    public function testVCard3040() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCARD
-VERSION:3.0
-PRODID:-//Sabre//Sabre VObject 3.1.0//EN
-FN:Cowboy Henk
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        $this->assertEquals(
-            0,
-            $this->cli->main(array('vobject', 'convert','--format=vcard40', '--pretty', '-'))
-        );
-
-        rewind($this->cli->stdout);
-
-        $version = Version::VERSION;
-        $expected = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-FN:Cowboy Henk
-END:VCARD
-
-VCF;
-
-          $this->assertEquals(
-            strtr($expected, array("\n"=>"\r\n")),
-            stream_get_contents($this->cli->stdout)
-        );
-
-    }
-
-    public function testVCard4030() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject 3.1.0//EN
-FN:Cowboy Henk
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        $this->assertEquals(
-            0,
-            $this->cli->main(array('vobject', 'convert','--format=vcard30', '--pretty', '-'))
-        );
-
-        $version = Version::VERSION;
-
-        rewind($this->cli->stdout);
-        $expected = <<<VCF
-BEGIN:VCARD
-VERSION:3.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-FN:Cowboy Henk
-END:VCARD
-
-VCF;
-
-          $this->assertEquals(
-            strtr($expected, array("\n"=>"\r\n")),
-            stream_get_contents($this->cli->stdout)
-        );
-
-    }
-
-    public function testVCard4021() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject 3.1.0//EN
-FN:Cowboy Henk
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-
-        // vCard 2.1 is not supported yet, so this returns a failure.
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'convert','--format=vcard21', '--pretty', '-'))
-        );
-
-    }
-
-    function testValidate() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject 3.1.0//EN
-UID:foo
-FN:Cowboy Henk
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        $result = $this->cli->main(array('vobject', 'validate', '-'));
-
-        $this->assertEquals(
-            0,
-            $result
-        );
-
-    }
-
-    function testValidateFail() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCALENDAR
-VERSION:2.0
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        // vCard 2.1 is not supported yet, so this returns a failure.
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'validate', '-'))
-        );
-
-    }
-
-    function testValidateFail2() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCALENDAR
-VERSION:5.0
-END:VCALENDAR
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        // vCard 2.1 is not supported yet, so this returns a failure.
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'validate', '-'))
-        );
-
-    }
-
-    function testRepair() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCARD
-VERSION:5.0
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        // vCard 2.1 is not supported yet, so this returns a failure.
-        $this->assertEquals(
-            2,
-            $this->cli->main(array('vobject', 'repair', '-'))
-        );
-
-        rewind($this->cli->stdout);
-        $this->assertRegExp("/^BEGIN:VCARD\r\nVERSION:2.1\r\nUID:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\r\nEND:VCARD\r\n$/", stream_get_contents($this->cli->stdout));
-    }
-
-    function testRepairNothing() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject 3.1.0//EN
-BEGIN:VEVENT
-UID:foo
-DTSTAMP:20140122T233226Z
-DTSTART:20140101T120000Z
-END:VEVENT
-END:VCALENDAR
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        // vCard 2.1 is not supported yet, so this returns a failure.
-
-        $result = $this->cli->main(array('vobject', 'repair', '-'));
-
-        rewind($this->cli->stderr);
-        $error = stream_get_contents($this->cli->stderr);
-
-        $this->assertEquals(
-            0,
-            $result,
-            "This should have been error free. stderr output:\n" . $error
-        );
-
-    }
-
-    /**
-     * Note: this is a very shallow test, doesn't dig into the actual output,
-     * but just makes sure there's no errors thrown.
-     *
-     * The colorizer is not a critical component, it's mostly a debugging tool.
-     */
-    function testColorCalendar() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        $version = Version::VERSION;
-
-        /**
-         * This object is not valid, but it's designed to hit every part of the
-         * colorizer source.
-         */
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject {$version}//EN
-BEGIN:VTIMEZONE
-END:VTIMEZONE
-BEGIN:VEVENT
-ATTENDEE;RSVP=TRUE:mailto:foo@example.org
-REQUEST-STATUS:5;foo
-ATTACH:blabla
-END:VEVENT
-END:VCALENDAR
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        // vCard 2.1 is not supported yet, so this returns a failure.
-
-        $result = $this->cli->main(array('vobject', 'color', '-'));
-
-        rewind($this->cli->stderr);
-        $error = stream_get_contents($this->cli->stderr);
-
-        $this->assertEquals(
-            0,
-            $result,
-            "This should have been error free. stderr output:\n" . $error
-        );
-
-    }
-
-    /**
-     * Note: this is a very shallow test, doesn't dig into the actual output,
-     * but just makes sure there's no errors thrown.
-     *
-     * The colorizer is not a critical component, it's mostly a debugging tool.
-     */
-    function testColorVCard() {
-
-        $inputStream = fopen('php://memory','r+');
-
-        $version = Version::VERSION;
-
-        /**
-         * This object is not valid, but it's designed to hit every part of the
-         * colorizer source.
-         */
-        fwrite($inputStream, <<<VCARD
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject {$version}//EN
-ADR:1;2;3;4a,4b;5;6
-group.TEL:123454768
-END:VCARD
-
-VCARD
-    );
-        rewind($inputStream);
-        $this->cli->stdin = $inputStream;
-        // vCard 2.1 is not supported yet, so this returns a failure.
-
-        $result = $this->cli->main(array('vobject', 'color', '-'));
-
-        rewind($this->cli->stderr);
-        $error = stream_get_contents($this->cli->stderr);
-
-        $this->assertEquals(
-            0,
-            $result,
-            "This should have been error free. stderr output:\n" . $error
-        );
-
-    }
-}
-
-class CliMock extends Cli {
-
-    public $log = array();
-
-    public $quiet = false;
-
-    public $format;
-
-    public $pretty;
-
-    public $stdin;
-
-    public $stdout;
-
-    public $stderr;
-
-    public $inputFormat;
-
-    public $outputFormat;
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Component/VAlarmTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject\Component;
-use DateTime;
-use Sabre\VObject\Reader;
-
-class VAlarmTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider timeRangeTestData
-     */
-    public function testInTimeRange(VAlarm $valarm,$start,$end,$outcome) {
-
-        $this->assertEquals($outcome, $valarm->isInTimeRange($start, $end));
-
-    }
-
-    public function timeRangeTestData() {
-
-        $tests = array();
-
-        $calendar = new VCalendar();
-
-        // Hard date and time        
-        $valarm1 = $calendar->createComponent('VALARM');
-        $valarm1->add(
-            $calendar->createProperty('TRIGGER', '20120312T130000Z', array('VALUE' => 'DATE-TIME'))
-        );
-
-        $tests[] = array($valarm1, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
-        $tests[] = array($valarm1, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
-
-        // Relation to start time of event
-        $valarm2 = $calendar->createComponent('VALARM');
-        $valarm2->add(
-            $calendar->createProperty('TRIGGER', '-P1D', array('VALUE' => 'DURATION'))
-        );
-
-        $vevent2 = $calendar->createComponent('VEVENT');
-        $vevent2->DTSTART = '20120313T130000Z';
-        $vevent2->add($valarm2);
-
-        $tests[] = array($valarm2, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
-        $tests[] = array($valarm2, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
-
-        // Relation to end time of event
-        $valarm3 = $calendar->createComponent('VALARM');
-        $valarm3->add( $calendar->createProperty('TRIGGER', '-P1D', array('VALUE'=>'DURATION', 'RELATED' => 'END')) );
-
-        $vevent3 = $calendar->createComponent('VEVENT');
-        $vevent3->DTSTART = '20120301T130000Z';
-        $vevent3->DTEND = '20120401T130000Z';
-        $vevent3->add($valarm3);
-
-        $tests[] = array($valarm3, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
-        $tests[] = array($valarm3, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
-
-        // Relation to end time of todo 
-        $valarm4 = $calendar->createComponent('VALARM');
-        $valarm4->TRIGGER = '-P1D';
-        $valarm4->TRIGGER['VALUE'] = 'DURATION';
-        $valarm4->TRIGGER['RELATED']= 'END';
-
-        $vtodo4 = $calendar->createComponent('VTODO');
-        $vtodo4->DTSTART = '20120301T130000Z';
-        $vtodo4->DUE = '20120401T130000Z';
-        $vtodo4->add($valarm4);
-
-        $tests[] = array($valarm4, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
-        $tests[] = array($valarm4, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
-
-        // Relation to start time of event + repeat
-        $valarm5 = $calendar->createComponent('VALARM');
-        $valarm5->TRIGGER = '-P1D';
-        $valarm5->TRIGGER['VALUE'] = 'DURATION';
-        $valarm5->REPEAT = 10;
-        $valarm5->DURATION = 'P1D';
-
-        $vevent5 = $calendar->createComponent('VEVENT');
-        $vevent5->DTSTART = '20120301T130000Z';
-        $vevent5->add($valarm5);
-
-        $tests[] = array($valarm5, new DateTime('2012-03-09 01:00:00'), new DateTime('2012-03-10 01:00:00'), true);
-
-        // Relation to start time of event + duration, but no repeat
-        $valarm6 = $calendar->createComponent('VALARM');
-        $valarm6->TRIGGER = '-P1D';
-        $valarm6->TRIGGER['VALUE'] = 'DURATION';
-        $valarm6->DURATION = 'P1D';
-
-        $vevent6 = $calendar->createComponent('VEVENT');
-        $vevent6->DTSTART = '20120313T130000Z';
-        $vevent6->add($valarm6);
-
-        $tests[] = array($valarm6, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
-        $tests[] = array($valarm6, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
-
-
-        // Relation to end time of event (DURATION instead of DTEND)
-        $valarm7 = $calendar->createComponent('VALARM');
-        $valarm7->TRIGGER = '-P1D';
-        $valarm7->TRIGGER['VALUE'] = 'DURATION';
-        $valarm7->TRIGGER['RELATED']= 'END';
-
-        $vevent7 = $calendar->createComponent('VEVENT');
-        $vevent7->DTSTART = '20120301T130000Z';
-        $vevent7->DURATION = 'P30D';
-        $vevent7->add($valarm7);
-
-        $tests[] = array($valarm7, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
-        $tests[] = array($valarm7, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
-
-        // Relation to end time of event (No DTEND or DURATION)
-        $valarm7 = $calendar->createComponent('VALARM');
-        $valarm7->TRIGGER = '-P1D';
-        $valarm7->TRIGGER['VALUE'] = 'DURATION';
-        $valarm7->TRIGGER['RELATED']= 'END';
-
-        $vevent7 = $calendar->createComponent('VEVENT');
-        $vevent7->DTSTART = '20120301T130000Z';
-        $vevent7->add($valarm7);
-
-        $tests[] = array($valarm7, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), true);
-        $tests[] = array($valarm7, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), false);
-
-
-        return $tests;
-    }
-
-    /**
-     * @expectedException LogicException
-     */
-    public function testInTimeRangeInvalidComponent() {
-
-        $calendar = new VCalendar();
-        $valarm = $calendar->createComponent('VALARM');
-        $valarm->TRIGGER = '-P1D';
-        $valarm->TRIGGER['RELATED'] = 'END';
-
-        $vjournal = $calendar->createComponent('VJOURNAL');
-        $vjournal->add($valarm);
-
-        $valarm->isInTimeRange(new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'));
-
-    }
-
-    /**
-     * This bug was found and reported on the mailing list.
-     */
-    public function testInTimeRangeBuggy() {
-
-$input = <<<BLA
-BEGIN:VCALENDAR
-BEGIN:VTODO
-DTSTAMP:20121003T064931Z
-UID:b848cb9a7bb16e464a06c222ca1f8102@examle.com
-STATUS:NEEDS-ACTION
-DUE:20121005T000000Z
-SUMMARY:Task 1
-CATEGORIES:AlarmCategory
-BEGIN:VALARM
-TRIGGER:-PT10M
-ACTION:DISPLAY
-DESCRIPTION:Task 1
-END:VALARM
-END:VTODO
-END:VCALENDAR
-BLA;
-
-        $vobj = Reader::read($input);
-
-        $this->assertTrue($vobj->VTODO->VALARM->isInTimeRange(new \DateTime('2012-10-01 00:00:00'), new \DateTime('2012-11-01 00:00:00')));
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/Component/VCalendarTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,696 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use DateTimeZone;
-use Sabre\VObject;
-
-class VCalendarTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider expandData
-     */
-    public function testExpand($input, $output, $timeZone = 'UTC', $start = '2011-12-01', $end = '2011-12-31') {
-
-        $vcal = VObject\Reader::read($input);
-
-        $timeZone = new DateTimeZone($timeZone);
-
-        $vcal->expand(
-            new \DateTime($start),
-            new \DateTime($end),
-            $timeZone
-        );
-
-        // This will normalize the output
-        $output = VObject\Reader::read($output)->serialize();
-
-        $this->assertEquals($output, $vcal->serialize());
-
-    }
-
-    public function expandData() {
-
-        $tests = array();
-
-        // No data
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-END:VCALENDAR
-';
-
-        $output = $input;
-        $tests[] = array($input,$output);
-
-
-        // Simple events
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla
-SUMMARY:InExpand
-DTSTART;VALUE=DATE:20111202
-END:VEVENT
-BEGIN:VEVENT
-UID:bla2
-SUMMARY:NotInExpand
-DTSTART;VALUE=DATE:20120101
-END:VEVENT
-END:VCALENDAR
-';
-
-        $output = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla
-SUMMARY:InExpand
-DTSTART;VALUE=DATE:20111202
-END:VEVENT
-END:VCALENDAR
-';
-
-        $tests[] = array($input, $output);
-
-        // Removing timezone info
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:Europe/Paris
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:bla4
-SUMMARY:RemoveTZ info
-DTSTART;TZID=Europe/Paris:20111203T130102
-END:VEVENT
-END:VCALENDAR
-';
-
-        $output = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla4
-SUMMARY:RemoveTZ info
-DTSTART:20111203T120102Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $tests[] = array($input, $output);
-
-        // Recurrence rule
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule
-DTSTART:20111125T120000Z
-DTEND:20111125T130000Z
-RRULE:FREQ=WEEKLY
-END:VEVENT
-END:VCALENDAR
-';
-
-        $output = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule
-DTSTART:20111202T120000Z
-DTEND:20111202T130000Z
-RECURRENCE-ID:20111202T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule
-DTSTART:20111209T120000Z
-DTEND:20111209T130000Z
-RECURRENCE-ID:20111209T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule
-DTSTART:20111216T120000Z
-DTEND:20111216T130000Z
-RECURRENCE-ID:20111216T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule
-DTSTART:20111223T120000Z
-DTEND:20111223T130000Z
-RECURRENCE-ID:20111223T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule
-DTSTART:20111230T120000Z
-DTEND:20111230T130000Z
-RECURRENCE-ID:20111230T120000Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $tests[] = array($input, $output);
-
-        // Recurrence rule + override
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule2
-DTSTART:20111125T120000Z
-DTEND:20111125T130000Z
-RRULE:FREQ=WEEKLY
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-RECURRENCE-ID:20111209T120000Z
-DTSTART:20111209T140000Z
-DTEND:20111209T150000Z
-SUMMARY:Override!
-END:VEVENT
-END:VCALENDAR
-';
-
-        $output = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule2
-DTSTART:20111202T120000Z
-DTEND:20111202T130000Z
-RECURRENCE-ID:20111202T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-RECURRENCE-ID:20111209T120000Z
-DTSTART:20111209T140000Z
-DTEND:20111209T150000Z
-SUMMARY:Override!
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule2
-DTSTART:20111216T120000Z
-DTEND:20111216T130000Z
-RECURRENCE-ID:20111216T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule2
-DTSTART:20111223T120000Z
-DTEND:20111223T130000Z
-RECURRENCE-ID:20111223T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule2
-DTSTART:20111230T120000Z
-DTEND:20111230T130000Z
-RECURRENCE-ID:20111230T120000Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $tests[] = array($input, $output);
-
-        // Floating dates and times.
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla1
-DTSTART:20141112T195000
-END:VEVENT
-BEGIN:VEVENT
-UID:bla2
-DTSTART;VALUE=DATE:20141112
-END:VEVENT
-BEGIN:VEVENT
-UID:bla3
-DTSTART;VALUE=DATE:20141112
-RRULE:FREQ=DAILY;COUNT=2
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $output = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla1
-DTSTART:20141112T225000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bla2
-DTSTART;VALUE=DATE:20141112
-END:VEVENT
-BEGIN:VEVENT
-UID:bla3
-DTSTART;VALUE=DATE:20141112
-END:VEVENT
-BEGIN:VEVENT
-UID:bla3
-DTSTART;VALUE=DATE:20141113
-RECURRENCE-ID;VALUE=DATE:20141113
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array($input, $output, 'America/Argentina/Buenos_Aires', '2014-01-01', '2015-01-01');
-
-        // Recurrence rule with no valid instances
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-UID:bla6
-SUMMARY:Testing RRule3
-DTSTART:20111125T120000Z
-DTEND:20111125T130000Z
-RRULE:FREQ=WEEKLY;COUNT=1
-EXDATE:20111125T120000Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $output = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-END:VCALENDAR
-';
-
-        $tests[] = array($input, $output);
-        return $tests;
-
-    }
-
-    /**
-     * @expectedException LogicException
-     */
-    public function testBrokenEventExpand() {
-
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-RRULE:FREQ=WEEKLY
-DTSTART;VALUE=DATE:20111202
-END:VEVENT
-END:VCALENDAR
-';
-        $vcal = VObject\Reader::read($input);
-        $vcal->expand(
-            new \DateTime('2011-12-01'),
-            new \DateTime('2011-12-31')
-        );
-
-    }
-
-    function testGetDocumentType() {
-
-        $vcard = new VCalendar();
-        $vcard->VERSION = '2.0';
-        $this->assertEquals(VCalendar::ICALENDAR20, $vcard->getDocumentType());
-
-    }
-
-    function testValidateCorrect() {
-
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-PRODID:foo
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-DTSTAMP:20140122T233226Z
-UID:foo
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(array(), $vcal->validate(), 'Got an error');
-
-    }
-
-    function testValidateNoVersion() {
-
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:foo
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(1, count($vcal->validate()));
-
-    }
-
-    function testValidateWrongVersion() {
-
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:3.0
-PRODID:foo
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(1, count($vcal->validate()));
-
-    }
-
-    function testValidateNoProdId() {
-
-        $input = 'BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(1, count($vcal->validate()));
-
-    }
-
-    function testValidateDoubleCalScale() {
-
-        $input = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:foo
-CALSCALE:GREGORIAN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(1, count($vcal->validate()));
-
-    }
-
-    function testValidateDoubleMethod() {
-
-        $input = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:foo
-METHOD:REQUEST
-METHOD:REQUEST
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(1, count($vcal->validate()));
-
-    }
-
-    function testValidateTwoMasterEvents() {
-
-        $input = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:foo
-METHOD:REQUEST
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(1, count($vcal->validate()));
-
-    }
-
-    function testValidateOneMasterEvent() {
-
-        $input = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:foo
-METHOD:REQUEST
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-RECURRENCE-ID;VALUE=DATE:20111202
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-        $this->assertEquals(0, count($vcal->validate()));
-
-    }
-
-    function testGetBaseComponent() {
-
-        $input = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:foo
-METHOD:REQUEST
-BEGIN:VEVENT
-SUMMARY:test
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-RECURRENCE-ID;VALUE=DATE:20111202
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-
-        $result = $vcal->getBaseComponent();
-        $this->assertEquals('test', $result->SUMMARY->getValue());
-
-    }
-
-    function testGetBaseComponentNoResult() {
-
-        $input = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:foo
-METHOD:REQUEST
-BEGIN:VEVENT
-SUMMARY:test
-RECURRENCE-ID;VALUE=DATE:20111202
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20111202
-UID:foo
-DTSTAMP:20140122T234434Z
-RECURRENCE-ID;VALUE=DATE:20111202
-END:VEVENT
-END:VCALENDAR
-';
-
-        $vcal = VObject\Reader::read($input);
-
-        $result = $vcal->getBaseComponent();
-        $this->assertNull($result);
-
-    }
-
-    function testNoComponents() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:vobject
-END:VCALENDAR
-ICS;
-
-        $this->assertValidate(
-            $input,
-            0,
-            3,
-           "An iCalendar object must have at least 1 component."
-        );
-
-    }
-
-    function testCalDAVNoComponents() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:vobject
-BEGIN:VTIMEZONE
-TZID:America/Toronto
-END:VTIMEZONE
-END:VCALENDAR
-ICS;
-
-        $this->assertValidate(
-            $input,
-            VCalendar::PROFILE_CALDAV,
-            3,
-           "A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL)."
-        );
-
-    }
-
-    function testCalDAVMultiUID() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:vobject
-BEGIN:VEVENT
-UID:foo
-DTSTAMP:20150109T184500Z
-DTSTART:20150109T184500Z
-END:VEVENT
-BEGIN:VEVENT
-UID:bar
-DTSTAMP:20150109T184500Z
-DTSTART:20150109T184500Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $this->assertValidate(
-            $input,
-            VCalendar::PROFILE_CALDAV,
-            3,
-           "A calendar object on a CalDAV server may only have components with the same UID."
-        );
-
-    }
-
-    function testCalDAVMultiComponent() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:vobject
-BEGIN:VEVENT
-UID:foo
-RECURRENCE-ID:20150109T185200Z
-DTSTAMP:20150109T184500Z
-DTSTART:20150109T184500Z
-END:VEVENT
-BEGIN:VTODO
-UID:foo
-DTSTAMP:20150109T184500Z
-DTSTART:20150109T184500Z
-END:VTODO
-END:VCALENDAR
-ICS;
-
-        $this->assertValidate(
-            $input,
-            VCalendar::PROFILE_CALDAV,
-            3,
-           "A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL)."
-        );
-
-    }
-
-    function testCalDAVMETHOD() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:PUBLISH
-PRODID:vobject
-BEGIN:VEVENT
-UID:foo
-RECURRENCE-ID:20150109T185200Z
-DTSTAMP:20150109T184500Z
-DTSTART:20150109T184500Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $this->assertValidate(
-            $input,
-            VCalendar::PROFILE_CALDAV,
-            3,
-           "A calendar object on a CalDAV server MUST NOT have a METHOD property."
-        );
-
-    }
-
-    function assertValidate($ics, $options, $expectedLevel, $expectedMessage = null) {
-
-        $vcal = VObject\Reader::read($ics);
-        $result = $vcal->validate($options);
-
-        $this->assertValidateResult($result, $expectedLevel, $expectedMessage);
-
-    }
-
-    function assertValidateResult($input, $expectedLevel, $expectedMessage = null) {
-
-        $messages = array();
-        foreach($input as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        if ($expectedLevel === 0) {
-            $this->assertEquals(0, count($input), 'No validation messages were expected. We got: ' . implode(', ', $messages));
-        } else {
-            $this->assertEquals(1, count($input), 'We expected exactly 1 validation message, We got: ' . implode(', ', $messages));
-
-            $this->assertEquals($expectedMessage, $input[0]['message']);
-            $this->assertEquals($expectedLevel, $input[0]['level']);
-        }
-
-    }
-
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Component/VCardTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-class VCardTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider validateData
-     */
-    function testValidate($input, $expectedWarnings, $expectedRepairedOutput) {
-
-        $vcard = VObject\Reader::read($input);
-
-        $warnings = $vcard->validate();
-
-        $warnMsg = array();
-        foreach($warnings as $warning) {
-            $warnMsg[] = $warning['message'];
-        }
-
-        $this->assertEquals($expectedWarnings, $warnMsg);
-
-        $vcard->validate(VObject\Component::REPAIR);
-
-        $this->assertEquals(
-            $expectedRepairedOutput,
-            $vcard->serialize()
-        );
-
-    }
-
-    public function validateData() {
-
-        $tests = array();
-
-        // Correct
-        $tests[] = array(
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
-            array(),
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
-        );
-
-        // No VERSION
-        $tests[] = array(
-            "BEGIN:VCARD\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
-            array(
-                'VERSION MUST appear exactly once in a VCARD component',
-            ),
-            "BEGIN:VCARD\r\nVERSION:3.0\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
-        );
-
-        // Unknown version
-        $tests[] = array(
-            "BEGIN:VCARD\r\nVERSION:2.2\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
-            array(
-                'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
-            ),
-            "BEGIN:VCARD\r\nVERSION:2.1\r\nFN:John Doe\r\nUID:foo\r\nEND:VCARD\r\n",
-        );
-
-        // No FN
-        $tests[] = array(
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nEND:VCARD\r\n",
-            array(
-                'The FN property must appear in the VCARD component exactly 1 time',
-            ),
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nEND:VCARD\r\n",
-        );
-        // No FN, N fallback
-        $tests[] = array(
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;John;;;;;\r\nEND:VCARD\r\n",
-            array(
-                'The FN property must appear in the VCARD component exactly 1 time',
-            ),
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;John;;;;;\r\nFN:John Doe\r\nEND:VCARD\r\n",
-        );
-        // No FN, N fallback, no first name
-        $tests[] = array(
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;;;;;;\r\nEND:VCARD\r\n",
-            array(
-                'The FN property must appear in the VCARD component exactly 1 time',
-            ),
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nN:Doe;;;;;;\r\nFN:Doe\r\nEND:VCARD\r\n",
-        );
-
-        // No FN, ORG fallback
-        $tests[] = array(
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nORG:Acme Co.\r\nEND:VCARD\r\n",
-            array(
-                'The FN property must appear in the VCARD component exactly 1 time',
-            ),
-            "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nORG:Acme Co.\r\nFN:Acme Co.\r\nEND:VCARD\r\n",
-        );
-        return $tests;
-
-    }
-
-    function testGetDocumentType() {
-
-        $vcard = new VCard(array(), false);
-        $vcard->VERSION = '2.1';
-        $this->assertEquals(VCard::VCARD21, $vcard->getDocumentType());
-
-        $vcard = new VCard(array(), false);
-        $vcard->VERSION = '3.0';
-        $this->assertEquals(VCard::VCARD30, $vcard->getDocumentType());
-
-        $vcard = new VCard(array(), false);
-        $vcard->VERSION = '4.0';
-        $this->assertEquals(VCard::VCARD40, $vcard->getDocumentType());
-
-        $vcard = new VCard(array(), false);
-        $this->assertEquals(VCard::UNKNOWN, $vcard->getDocumentType());
-    }
-
-    function testPreferredNoPref() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:3.0
-EMAIL:1@example.org
-EMAIL:2@example.org
-END:VCARD
-VCF;
-
-        $vcard = VObject\Reader::read($vcard);
-        $this->assertEquals('1@example.org', $vcard->preferred('EMAIL')->getValue());
-
-    }
-
-    function testPreferredWithPref() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:3.0
-EMAIL:1@example.org
-EMAIL;TYPE=PREF:2@example.org
-END:VCARD
-VCF;
-
-        $vcard = VObject\Reader::read($vcard);
-        $this->assertEquals('2@example.org', $vcard->preferred('EMAIL')->getValue());
-
-    }
-
-    function testPreferredWith40Pref() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-EMAIL:1@example.org
-EMAIL;PREF=3:2@example.org
-EMAIL;PREF=2:3@example.org
-END:VCARD
-VCF;
-
-        $vcard = VObject\Reader::read($vcard);
-        $this->assertEquals('3@example.org', $vcard->preferred('EMAIL')->getValue());
-
-    }
-
-    function testPreferredNotFound() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-END:VCARD
-VCF;
-
-        $vcard = VObject\Reader::read($vcard);
-        $this->assertNull($vcard->preferred('EMAIL'));
-
-    }
-
-    function testNoUIDCardDAV() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-FN:John Doe
-END:VCARD
-VCF;
-        $this->assertValidate(
-            $vcard,
-            VCARD::PROFILE_CARDDAV,
-            3,
-            'vCards on CardDAV servers MUST have a UID property.'
-        );
-
-    }
-
-    function testNoUIDNoCardDAV() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-FN:John Doe
-END:VCARD
-VCF;
-        $this->assertValidate(
-            $vcard,
-            0,
-            2,
-            'Adding a UID to a vCard property is recommended.'
-        );
-
-    }
-    function testNoUIDNoCardDAVRepair() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-FN:John Doe
-END:VCARD
-VCF;
-        $this->assertValidate(
-            $vcard,
-            VCARD::REPAIR,
-            1,
-            'Adding a UID to a vCard property is recommended.'
-        );
-
-    }
-
-    function testVCard21CardDAV() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:2.1
-FN:John Doe
-UID:foo
-END:VCARD
-VCF;
-        $this->assertValidate(
-            $vcard,
-            VCARD::PROFILE_CARDDAV,
-            3,
-            'CardDAV servers are not allowed to accept vCard 2.1.'
-        );
-
-    }
-
-    function testVCard21NoCardDAV() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:2.1
-FN:John Doe
-UID:foo
-END:VCARD
-VCF;
-        $this->assertValidate(
-            $vcard,
-            0,
-            0
-        );
-
-    }
-
-    function assertValidate($vcf, $options, $expectedLevel, $expectedMessage = null) {
-
-        $vcal = VObject\Reader::read($vcf);
-        $result = $vcal->validate($options);
-
-        $this->assertValidateResult($result, $expectedLevel, $expectedMessage);
-
-    }
-
-    function assertValidateResult($input, $expectedLevel, $expectedMessage = null) {
-
-        $messages = array();
-        foreach($input as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        if ($expectedLevel === 0) {
-            $this->assertEquals(0, count($input), 'No validation messages were expected. We got: ' . implode(', ', $messages));
-        } else {
-            $this->assertEquals(1, count($input), 'We expected exactly 1 validation message, We got: ' . implode(', ', $messages));
-
-            $this->assertEquals($expectedMessage, $input[0]['message']);
-            $this->assertEquals($expectedLevel, $input[0]['level']);
-        }
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/Component/VEventTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-
-class VEventTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider timeRangeTestData
-     */
-    public function testInTimeRange(VEvent $vevent,$start,$end,$outcome) {
-
-        $this->assertEquals($outcome, $vevent->isInTimeRange($start, $end));
-
-    }
-
-    public function timeRangeTestData() {
-
-        $tests = array();
-
-        $calendar = new VCalendar();
-
-        $vevent = $calendar->createComponent('VEVENT');
-        $vevent->DTSTART = '20111223T120000Z';
-        $tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vevent2 = clone $vevent;
-        $vevent2->DTEND = '20111225T120000Z';
-        $tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vevent3 = clone $vevent;
-        $vevent3->DURATION = 'P1D';
-        $tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vevent4 = clone $vevent;
-        $vevent4->DTSTART = '20111225';
-        $vevent4->DTSTART['VALUE'] = 'DATE';
-        $tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-        // Event with no end date should be treated as lasting the entire day.
-        $tests[] = array($vevent4, new \DateTime('2011-12-25 16:00:00'), new \DateTime('2011-12-25 17:00:00'), true);
-
-
-        $vevent5 = clone $vevent;
-        $vevent5->DURATION = 'P1D';
-        $vevent5->RRULE = 'FREQ=YEARLY';
-        $tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-        $tests[] = array($vevent5, new \DateTime('2013-12-01'), new \DateTime('2013-12-31'), true);
-
-        $vevent6 = clone $vevent;
-        $vevent6->DTSTART = '20111225';
-        $vevent6->DTSTART['VALUE'] = 'DATE';
-        $vevent6->DTEND   = '20111225';
-        $vevent6->DTEND['VALUE'] = 'DATE';
-
-        $tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        // Added this test to ensure that recurrence rules with no DTEND also 
-        // get checked for the entire day.
-        $vevent7 = clone $vevent;
-        $vevent7->DTSTART = '20120101';
-        $vevent7->DTSTART['VALUE'] = 'DATE';
-        $vevent7->RRULE = 'FREQ=MONTHLY';
-        $tests[] = array($vevent7, new \DateTime('2012-02-01 15:00:00'), new \DateTime('2012-02-02'), true);
-        return $tests;
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/Component/VFreeBusyTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-use Sabre\VObject\Reader;
-
-class VFreeBusyTest extends \PHPUnit_Framework_TestCase {
-
-    function testIsFree() {
-
-        $input = <<<BLA
-BEGIN:VCALENDAR
-BEGIN:VFREEBUSY
-FREEBUSY;FBTYPE=FREE:20120912T000500Z/PT1H
-FREEBUSY;FBTYPE=BUSY:20120912T010000Z/20120912T020000Z
-FREEBUSY;FBTYPE=BUSY-TENTATIVE:20120912T020000Z/20120912T030000Z
-FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20120912T030000Z/20120912T040000Z
-FREEBUSY;FBTYPE=BUSY:20120912T050000Z/20120912T060000Z,20120912T080000Z/20120912T090000Z
-FREEBUSY;FBTYPE=BUSY:20120912T100000Z/PT1H
-END:VFREEBUSY
-END:VCALENDAR
-BLA;
-
-        $obj = VObject\Reader::read($input);
-        $vfb = $obj->VFREEBUSY;
-
-        $tz = new \DateTimeZone('UTC');
-
-        $this->assertFalse($vfb->isFree(new \DateTime('2012-09-12 01:15:00', $tz), new \DateTime('2012-09-12 01:45:00', $tz)));
-        $this->assertFalse($vfb->isFree(new \DateTime('2012-09-12 08:05:00', $tz), new \DateTime('2012-09-12 08:10:00', $tz)));
-        $this->assertFalse($vfb->isFree(new \DateTime('2012-09-12 10:15:00', $tz), new \DateTime('2012-09-12 10:45:00', $tz)));
-
-        // Checking whether the end time is treated as non-inclusive
-        $this->assertTrue($vfb->isFree(new \DateTime('2012-09-12 09:00:00', $tz), new \DateTime('2012-09-12 09:15:00', $tz)));
-        $this->assertTrue($vfb->isFree(new \DateTime('2012-09-12 09:45:00', $tz), new \DateTime('2012-09-12 10:00:00', $tz)));
-        $this->assertTrue($vfb->isFree(new \DateTime('2012-09-12 11:00:00', $tz), new \DateTime('2012-09-12 12:00:00', $tz)));
-
-    }
-
-    public function testValidate() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VFREEBUSY
-UID:some-random-id
-DTSTAMP:20140402T180200Z
-END:VFREEBUSY
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(), $messages);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Component/VJournalTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject\Component;
-use Sabre\VObject\Reader;
-
-class VJournalTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider timeRangeTestData
-     */
-    public function testInTimeRange(VJournal $vtodo,$start,$end,$outcome) {
-
-        $this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
-
-    }
-
-    public function testValidate() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VJOURNAL
-UID:12345678
-DTSTAMP:20140402T174100Z
-END:VJOURNAL
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(), $messages);
-
-    }
-
-    public function testValidateBroken() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VJOURNAL
-UID:12345678
-DTSTAMP:20140402T174100Z
-URL:http://example.org/
-URL:http://example.com/
-END:VJOURNAL
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(
-            array("URL MUST NOT appear more than once in a VJOURNAL component"),
-            $messages
-        );
-
-    }
-
-    public function timeRangeTestData() {
-
-        $calendar = new VCalendar();
-
-        $tests = array();
-
-        $vjournal = $calendar->createComponent('VJOURNAL');
-        $vjournal->DTSTART = '20111223T120000Z';
-        $tests[] = array($vjournal, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vjournal, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vjournal2 = $calendar->createComponent('VJOURNAL');
-        $vjournal2->DTSTART = '20111223';
-        $vjournal2->DTSTART['VALUE'] = 'DATE';
-        $tests[] = array($vjournal2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vjournal2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vjournal3 = $calendar->createComponent('VJOURNAL');
-        $tests[] = array($vjournal3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), false);
-        $tests[] = array($vjournal3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        return $tests;
-    }
-
-
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/Component/VTimeZoneTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use Sabre\VObject;
-use Sabre\VObject\Reader;
-
-class VTimeZoneTest extends \PHPUnit_Framework_TestCase {
-
-    function testValidate() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VTIMEZONE
-TZID:America/Toronto
-END:VTIMEZONE
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(), $messages);
-
-    }
-
-    function testGetTimeZone() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VTIMEZONE
-TZID:America/Toronto
-END:VTIMEZONE
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $tz = new \DateTimeZone('America/Toronto');
-
-        $this->assertEquals(
-            $tz,
-            $obj->VTIMEZONE->getTimeZone()
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Component/VTodoTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Component;
-
-use
-    Sabre\VObject\Component,
-    Sabre\VObject\Reader;
-
-class VTodoTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider timeRangeTestData
-     */
-    public function testInTimeRange(VTodo $vtodo,$start,$end,$outcome) {
-
-        $this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
-
-    }
-
-    public function timeRangeTestData() {
-
-        $tests = array();
-
-        $calendar = new VCalendar();
-
-        $vtodo = $calendar->createComponent('VTODO');
-        $vtodo->DTSTART = '20111223T120000Z';
-        $tests[] = array($vtodo, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo2 = clone $vtodo;
-        $vtodo2->DURATION = 'P1D';
-        $tests[] = array($vtodo2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo3 = clone $vtodo;
-        $vtodo3->DUE = '20111225';
-        $tests[] = array($vtodo3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo4 = $calendar->createComponent('VTODO');
-        $vtodo4->DUE = '20111225';
-        $tests[] = array($vtodo4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo5 = $calendar->createComponent('VTODO');
-        $vtodo5->COMPLETED = '20111225';
-        $tests[] = array($vtodo5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo6 = $calendar->createComponent('VTODO');
-        $vtodo6->CREATED = '20111225';
-        $tests[] = array($vtodo6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo7 = $calendar->createComponent('VTODO');
-        $vtodo7->CREATED = '20111225';
-        $vtodo7->COMPLETED = '20111226';
-        $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false);
-
-        $vtodo7 = $calendar->createComponent('VTODO');
-        $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true);
-        $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), true);
-
-        return $tests;
-
-    }
-
-    public function testValidate() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VTODO
-UID:1234-21355-123156
-DTSTAMP:20140402T183400Z
-END:VTODO
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(), $messages);
-
-    }
-
-    public function testValidateInvalid() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VTODO
-END:VTODO
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(
-            "UID MUST appear exactly once in a VTODO component",
-            "DTSTAMP MUST appear exactly once in a VTODO component",
-        ), $messages);
-
-    }
-
-    public function testValidateDUEDTSTARTMisMatch() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VTODO
-UID:FOO
-DTSTART;VALUE=DATE-TIME:20140520T131600Z
-DUE;VALUE=DATE:20140520
-DTSTAMP;VALUE=DATE-TIME:20140520T131600Z
-END:VTODO
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(
-            "The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART",
-        ), $messages);
-
-    }
-
-    public function testValidateDUEbeforeDTSTART() {
-
-        $input = <<<HI
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:YoYo
-BEGIN:VTODO
-UID:FOO
-DTSTART;VALUE=DATE:20140520
-DUE;VALUE=DATE:20140518
-DTSTAMP;VALUE=DATE-TIME:20140520T131600Z
-END:VTODO
-END:VCALENDAR
-HI;
-
-        $obj = Reader::read($input);
-
-        $warnings = $obj->validate();
-        $messages = array();
-        foreach($warnings as $warning) {
-            $messages[] = $warning['message'];
-        }
-
-        $this->assertEquals(array(
-            "DUE must occur after DTSTART",
-        ), $messages);
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/ComponentTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,528 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    Sabre\VObject\Component\VCalendar,
-    Sabre\VObject\Component\VCard;
-
-class ComponentTest extends \PHPUnit_Framework_TestCase {
-
-    function testIterate() {
-
-        $comp = new VCalendar(array(), false);
-
-        $sub = $comp->createComponent('VEVENT');
-        $comp->add($sub);
-
-        $sub = $comp->createComponent('VTODO');
-        $comp->add($sub);
-
-        $count = 0;
-        foreach($comp->children() as $key=>$subcomponent) {
-
-           $count++;
-           $this->assertInstanceOf('Sabre\\VObject\\Component',$subcomponent);
-
-        }
-        $this->assertEquals(2,$count);
-        $this->assertEquals(1,$key);
-
-    }
-
-    function testMagicGet() {
-
-        $comp = new VCalendar(array(), false);
-
-        $sub = $comp->createComponent('VEVENT');
-        $comp->add($sub);
-
-        $sub = $comp->createComponent('VTODO');
-        $comp->add($sub);
-
-        $event = $comp->vevent;
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $event);
-        $this->assertEquals('VEVENT', $event->name);
-
-        $this->assertInternalType('null', $comp->vjournal);
-
-    }
-
-    function testMagicGetGroups() {
-
-        $comp = new VCard();
-
-        $sub = $comp->createProperty('GROUP1.EMAIL','1@1.com');
-        $comp->add($sub);
-
-        $sub = $comp->createProperty('GROUP2.EMAIL','2@2.com');
-        $comp->add($sub);
-
-        $sub = $comp->createProperty('EMAIL','3@3.com');
-        $comp->add($sub);
-
-        $emails = $comp->email;
-        $this->assertEquals(3, count($emails));
-
-        $email1 = $comp->{"group1.email"};
-        $this->assertEquals('EMAIL', $email1[0]->name);
-        $this->assertEquals('GROUP1', $email1[0]->group);
-
-        $email3 = $comp->{".email"};
-        $this->assertEquals('EMAIL', $email3[0]->name);
-        $this->assertEquals(null, $email3[0]->group);
-
-    }
-
-    function testMagicIsset() {
-
-        $comp = new VCalendar();
-
-        $sub = $comp->createComponent('VEVENT');
-        $comp->add($sub);
-
-        $sub = $comp->createComponent('VTODO');
-        $comp->add($sub);
-
-        $this->assertTrue(isset($comp->vevent));
-        $this->assertTrue(isset($comp->vtodo));
-        $this->assertFalse(isset($comp->vjournal));
-
-    }
-
-    function testMagicSetScalar() {
-
-        $comp = new VCalendar();
-        $comp->myProp = 'myValue';
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->MYPROP);
-        $this->assertEquals('myValue',(string)$comp->MYPROP);
-
-
-    }
-
-    function testMagicSetScalarTwice() {
-
-        $comp = new VCalendar(array(), false);
-        $comp->myProp = 'myValue';
-        $comp->myProp = 'myValue';
-
-        $this->assertEquals(1,count($comp->children()));
-        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->MYPROP);
-        $this->assertEquals('myValue',(string)$comp->MYPROP);
-
-    }
-
-    function testMagicSetArray() {
-
-        $comp = new VCalendar();
-        $comp->ORG = array('Acme Inc', 'Section 9');
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->ORG);
-        $this->assertEquals(array('Acme Inc', 'Section 9'),$comp->ORG->getParts());
-
-    }
-
-    function testMagicSetComponent() {
-
-        $comp = new VCalendar();
-
-        // Note that 'myProp' is ignored here.
-        $comp->myProp = $comp->createComponent('VEVENT');
-
-        $this->assertEquals(1, count($comp));
-
-        $this->assertEquals('VEVENT',$comp->VEVENT->name);
-
-    }
-
-    function testMagicSetTwice() {
-
-        $comp = new VCalendar(array(), false);
-
-        $comp->VEVENT = $comp->createComponent('VEVENT');
-        $comp->VEVENT = $comp->createComponent('VEVENT');
-
-        $this->assertEquals(1, count($comp->children()));
-
-        $this->assertEquals('VEVENT',$comp->VEVENT->name);
-
-    }
-
-    function testArrayAccessGet() {
-
-        $comp = new VCalendar(array(), false);
-
-        $event = $comp->createComponent('VEVENT');
-        $event->summary = 'Event 1';
-
-        $comp->add($event);
-
-        $event2 = clone $event;
-        $event2->summary = 'Event 2';
-
-        $comp->add($event2);
-
-        $this->assertEquals(2,count($comp->children()));
-        $this->assertTrue($comp->vevent[1] instanceof Component);
-        $this->assertEquals('Event 2', (string)$comp->vevent[1]->summary);
-
-    }
-
-    function testArrayAccessExists() {
-
-        $comp = new VCalendar();
-
-        $event = $comp->createComponent('VEVENT');
-        $event->summary = 'Event 1';
-
-        $comp->add($event);
-
-        $event2 = clone $event;
-        $event2->summary = 'Event 2';
-
-        $comp->add($event2);
-
-        $this->assertTrue(isset($comp->vevent[0]));
-        $this->assertTrue(isset($comp->vevent[1]));
-
-    }
-
-    /**
-     * @expectedException LogicException
-     */
-    function testArrayAccessSet() {
-
-        $comp = new VCalendar();
-        $comp['hey'] = 'hi there';
-
-    }
-    /**
-     * @expectedException LogicException
-     */
-    function testArrayAccessUnset() {
-
-        $comp = new VCalendar();
-        unset($comp[0]);
-
-    }
-
-    function testAddScalar() {
-
-        $comp = new VCalendar(array(), false);
-
-        $comp->add('myprop','value');
-
-        $this->assertEquals(1, count($comp->children()));
-
-        $bla = $comp->children[0];
-
-        $this->assertTrue($bla instanceof Property);
-        $this->assertEquals('MYPROP',$bla->name);
-        $this->assertEquals('value',(string)$bla);
-
-    }
-
-    function testAddScalarParams() {
-
-        $comp = new VCalendar(array(), false);
-
-        $comp->add('myprop','value',array('param1'=>'value1'));
-
-        $this->assertEquals(1, count($comp->children()));
-
-        $bla = $comp->children[0];
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $bla);
-        $this->assertEquals('MYPROP',$bla->name);
-        $this->assertEquals('value', (string)$bla);
-
-        $this->assertEquals(1, count($bla->parameters()));
-
-        $this->assertEquals('PARAM1',$bla->parameters['PARAM1']->name);
-        $this->assertEquals('value1',$bla->parameters['PARAM1']->getValue());
-
-    }
-
-
-    function testAddComponent() {
-
-        $comp = new VCalendar(array(), false);
-
-        $comp->add($comp->createComponent('VEVENT'));
-
-        $this->assertEquals(1, count($comp->children()));
-
-        $this->assertEquals('VEVENT',$comp->VEVENT->name);
-
-    }
-
-    function testAddComponentTwice() {
-
-        $comp = new VCalendar(array(), false);
-
-        $comp->add($comp->createComponent('VEVENT'));
-        $comp->add($comp->createComponent('VEVENT'));
-
-        $this->assertEquals(2, count($comp->children()));
-
-        $this->assertEquals('VEVENT',$comp->VEVENT->name);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testAddArgFail() {
-
-        $comp = new VCalendar();
-        $comp->add($comp->createComponent('VEVENT'),'hello');
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testAddArgFail2() {
-
-        $comp = new VCalendar();
-        $comp->add(array());
-
-    }
-
-    function testMagicUnset() {
-
-        $comp = new VCalendar(array(), false);
-        $comp->add($comp->createComponent('VEVENT'));
-
-        unset($comp->vevent);
-
-        $this->assertEquals(0, count($comp->children()));
-
-    }
-
-
-    function testCount() {
-
-        $comp = new VCalendar();
-        $this->assertEquals(1,$comp->count());
-
-    }
-
-    function testChildren() {
-
-        $comp = new VCalendar(array(), false);
-
-        // Note that 'myProp' is ignored here.
-        $comp->add($comp->createComponent('VEVENT'));
-        $comp->add($comp->createComponent('VTODO'));
-
-        $r = $comp->children();
-        $this->assertInternalType('array', $r);
-        $this->assertEquals(2,count($r));
-    }
-
-    function testGetComponents() {
-
-        $comp = new VCalendar();
-
-        $comp->add($comp->createProperty('FOO','BAR'));
-        $comp->add($comp->createComponent('VTODO'));
-
-        $r = $comp->getComponents();
-        $this->assertInternalType('array', $r);
-        $this->assertEquals(1, count($r));
-        $this->assertEquals('VTODO', $r[0]->name);
-    }
-
-    function testSerialize() {
-
-        $comp = new VCalendar(array(), false);
-        $this->assertEquals("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n", $comp->serialize());
-
-    }
-
-    function testSerializeChildren() {
-
-        $comp = new VCalendar(array(), false);
-        $event = $comp->add($comp->createComponent('VEVENT'));
-        unset($event->DTSTAMP, $event->UID);
-        $comp->add($comp->createComponent('VTODO'));
-
-        $str = $comp->serialize();
-
-        $this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", $str);
-
-    }
-
-    function testSerializeOrderCompAndProp() {
-
-        $comp = new VCalendar(array(), false);
-        $comp->add($event = $comp->createComponent('VEVENT'));
-        $comp->add('PROP1','BLABLA');
-        $comp->add('VERSION','2.0');
-        $comp->add($comp->createComponent('VTIMEZONE'));
-
-        unset($event->DTSTAMP, $event->UID);
-        $str = $comp->serialize();
-
-        $this->assertEquals("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPROP1:BLABLA\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $str);
-
-    }
-
-    function testAnotherSerializeOrderProp() {
-
-        $prop4s=array('1', '2', '3', '4', '5', '6', '7', '8', '9', '10');
-
-        $comp = new VCard(array(), false);
-
-        $comp->__set('SOMEPROP','FOO');
-        $comp->__set('ANOTHERPROP','FOO');
-        $comp->__set('THIRDPROP','FOO');
-        foreach ($prop4s as $prop4) {
-            $comp->add('PROP4', 'FOO '.$prop4);
-        }
-        $comp->__set('PROPNUMBERFIVE', 'FOO');
-        $comp->__set('PROPNUMBERSIX', 'FOO');
-        $comp->__set('PROPNUMBERSEVEN', 'FOO');
-        $comp->__set('PROPNUMBEREIGHT', 'FOO');
-        $comp->__set('PROPNUMBERNINE', 'FOO');
-        $comp->__set('PROPNUMBERTEN', 'FOO');
-        $comp->__set('VERSION','2.0');
-        $comp->__set('UID', 'FOO');
-
-        $str = $comp->serialize();
-
-        $this->assertEquals("BEGIN:VCARD\r\nVERSION:2.0\r\nSOMEPROP:FOO\r\nANOTHERPROP:FOO\r\nTHIRDPROP:FOO\r\nPROP4:FOO 1\r\nPROP4:FOO 2\r\nPROP4:FOO 3\r\nPROP4:FOO 4\r\nPROP4:FOO 5\r\nPROP4:FOO 6\r\nPROP4:FOO 7\r\nPROP4:FOO 8\r\nPROP4:FOO 9\r\nPROP4:FOO 10\r\nPROPNUMBERFIVE:FOO\r\nPROPNUMBERSIX:FOO\r\nPROPNUMBERSEVEN:FOO\r\nPROPNUMBEREIGHT:FOO\r\nPROPNUMBERNINE:FOO\r\nPROPNUMBERTEN:FOO\r\nUID:FOO\r\nEND:VCARD\r\n", $str);
-
-    }
-
-    function testInstantiateWithChildren() {
-
-        $comp = new VCard(array(
-            'ORG' => array('Acme Inc.', 'Section 9'),
-            'FN' => 'Finn The Human',
-        ));
-
-        $this->assertEquals(array('Acme Inc.', 'Section 9'), $comp->ORG->getParts());
-        $this->assertEquals('Finn The Human', $comp->FN->getValue());
-
-    }
-
-    function testInstantiateSubComponent() {
-
-        $comp = new VCalendar();
-        $event = $comp->createComponent('VEVENT', array(
-            $comp->createProperty('UID', '12345'),
-        ));
-        $comp->add($event);
-
-        $this->assertEquals('12345', $comp->VEVENT->UID->getValue());
-
-    }
-
-    function testRemoveByName() {
-
-        $comp = new VCalendar(array(), false);
-        $comp->add('prop1','val1');
-        $comp->add('prop2','val2');
-        $comp->add('prop2','val2');
-
-        $comp->remove('prop2');
-        $this->assertFalse(isset($comp->prop2));
-        $this->assertTrue(isset($comp->prop1));
-
-    }
-
-    function testRemoveByObj() {
-
-        $comp = new VCalendar(array(), false);
-        $comp->add('prop1','val1');
-        $prop = $comp->add('prop2','val2');
-
-        $comp->remove($prop);
-        $this->assertFalse(isset($comp->prop2));
-        $this->assertTrue(isset($comp->prop1));
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testRemoveNotFound() {
-
-        $comp = new VCalendar(array(), false);
-        $prop = $comp->createProperty('A','B');
-        $comp->remove($prop);
-
-    }
-
-    /**
-     * @dataProvider ruleData
-     */
-    function testValidateRules($componentList, $errorCount) {
-
-        $vcard = new Component\VCard();
-
-        $component = new FakeComponent($vcard,'Hi', array(), $defaults = false );
-        foreach($componentList as $v) {
-            $component->add($v,'Hello.');
-        }
-
-        $this->assertEquals($errorCount, count($component->validate()));
-
-    }
-
-    function testValidateRepair() {
-
-        $vcard = new Component\VCard();
-
-        $component = new FakeComponent($vcard,'Hi', array(), $defaults = false );
-        $component->validate(Component::REPAIR);
-        $this->assertEquals('yow', $component->BAR->getValue());
-
-    }
-
-    function ruleData() {
-
-        return array(
-
-            array(array(), 2),
-            array(array('FOO'), 3),
-            array(array('BAR'), 1),
-            array(array('BAZ'), 1),
-            array(array('BAR','BAZ'), 0),
-            array(array('BAR','BAZ','ZIM',), 0),
-            array(array('BAR','BAZ','ZIM','GIR'), 0),
-            array(array('BAR','BAZ','ZIM','GIR','GIR'), 1),
-
-        );
-
-    }
-
-}
-
-class FakeComponent extends Component {
-
-    public function getValidationRules() {
-
-        return array(
-            'FOO' => '0',
-            'BAR' => '1',
-            'BAZ' => '+',
-            'ZIM' => '*',
-            'GIR' => '?',
-        );
-
-    }
-
-    public function getDefaults() {
-
-        return array(
-            'BAR' => 'yow',
-        );
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/DateTimeParserTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,389 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use DateTime;
-use DateTimeZone;
-use DateInterval;
-
-class DateTimeParserTest extends \PHPUnit_Framework_TestCase {
-
-    function testParseICalendarDuration() {
-
-        $this->assertEquals('+1 weeks', DateTimeParser::parseDuration('P1W',true));
-        $this->assertEquals('+5 days',  DateTimeParser::parseDuration('P5D',true));
-        $this->assertEquals('+5 days 3 hours 50 minutes 12 seconds', DateTimeParser::parseDuration('P5DT3H50M12S',true));
-        $this->assertEquals('-1 weeks 50 minutes', DateTimeParser::parseDuration('-P1WT50M',true));
-        $this->assertEquals('+50 days 3 hours 2 seconds', DateTimeParser::parseDuration('+P50DT3H2S',true));
-        $this->assertEquals('+0 seconds', DateTimeParser::parseDuration('+PT0S',true));
-        $this->assertEquals(new DateInterval('PT0S'), DateTimeParser::parseDuration('PT0S'));
-
-    }
-
-    function testParseICalendarDurationDateInterval() {
-
-        $expected = new DateInterval('P7D');
-        $this->assertEquals($expected, DateTimeParser::parseDuration('P1W'));
-        $this->assertEquals($expected, DateTimeParser::parse('P1W'));
-
-        $expected = new DateInterval('PT3M');
-        $expected->invert = true;
-        $this->assertEquals($expected, DateTimeParser::parseDuration('-PT3M'));
-
-    }
-
-    /**
-     * @expectedException LogicException
-     */
-    function testParseICalendarDurationFail() {
-
-        DateTimeParser::parseDuration('P1X',true);
-
-    }
-
-    function testParseICalendarDateTime() {
-
-        $dateTime = DateTimeParser::parseDateTime('20100316T141405');
-
-        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
-
-        $this->assertEquals($compare, $dateTime);
-
-    }
-
-    /**
-     * @depends testParseICalendarDateTime
-     * @expectedException LogicException
-     */
-    function testParseICalendarDateTimeBadFormat() {
-
-        $dateTime = DateTimeParser::parseDateTime('20100316T141405 ');
-
-    }
-
-    /**
-     * @depends testParseICalendarDateTime
-     */
-    function testParseICalendarDateTimeUTC() {
-
-        $dateTime = DateTimeParser::parseDateTime('20100316T141405Z');
-
-        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
-        $this->assertEquals($compare, $dateTime);
-
-    }
-
-    /**
-     * @depends testParseICalendarDateTime
-     */
-    function testParseICalendarDateTimeUTC2() {
-
-        $dateTime = DateTimeParser::parseDateTime('20101211T160000Z');
-
-        $compare = new DateTime('2010-12-11 16:00:00',new DateTimeZone('UTC'));
-        $this->assertEquals($compare, $dateTime);
-
-    }
-
-    /**
-     * @depends testParseICalendarDateTime
-     */
-    function testParseICalendarDateTimeCustomTimeZone() {
-
-        $dateTime = DateTimeParser::parseDateTime('20100316T141405', new DateTimeZone('Europe/Amsterdam'));
-
-        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('Europe/Amsterdam'));
-        $this->assertEquals($compare, $dateTime);
-
-    }
-
-    function testParseICalendarDate() {
-
-        $dateTime = DateTimeParser::parseDate('20100316');
-
-        $expected = new DateTime('2010-03-16 00:00:00',new DateTimeZone('UTC'));
-
-        $this->assertEquals($expected, $dateTime);
-
-        $dateTime = DateTimeParser::parse('20100316');
-        $this->assertEquals($expected, $dateTime);
-
-    }
-
-    /**
-     * TCheck if a date with year > 4000 will not throw an exception. iOS seems to use 45001231 in yearly recurring events
-     */
-    function testParseICalendarDateGreaterThan4000() {
-
-        $dateTime = DateTimeParser::parseDate('45001231');
-
-        $expected = new DateTime('4500-12-31 00:00:00',new DateTimeZone('UTC'));
-
-        $this->assertEquals($expected, $dateTime);
-
-        $dateTime = DateTimeParser::parse('45001231');
-        $this->assertEquals($expected, $dateTime);
-
-    }
-
-    /**
-     * Check if a datetime with year > 4000 will not throw an exception. iOS seems to use 45001231T235959 in yearly recurring events
-     */
-    function testParseICalendarDateTimeGreaterThan4000() {
-
-        $dateTime = DateTimeParser::parseDateTime('45001231T235959');
-
-        $expected = new DateTime('4500-12-31 23:59:59',new DateTimeZone('UTC'));
-
-        $this->assertEquals($expected, $dateTime);
-
-        $dateTime = DateTimeParser::parse('45001231T235959');
-        $this->assertEquals($expected, $dateTime);
-
-    }
-
-    /**
-     * @depends testParseICalendarDate
-     * @expectedException LogicException
-     */
-    function testParseICalendarDateBadFormat() {
-
-        $dateTime = DateTimeParser::parseDate('20100316T141405');
-
-    }
-
-    /**
-     * @dataProvider vcardDates
-     */
-    function testVCardDate($input, $output) {
-
-        $this->assertEquals(
-            $output,
-            DateTimeParser::parseVCardDateTime($input)
-        );
-
-    }
-
-    /**
-     * @dataProvider vcardDates
-     * @expectedException \InvalidArgumentException
-     */
-    function testBadVCardDate() {
-
-        DateTimeParser::parseVCardDateTime('1985---01');
-
-    }
-
-    /**
-     * @dataProvider vcardDates
-     * @expectedException \InvalidArgumentException
-     */
-    function testBadVCardTime() {
-
-        DateTimeParser::parseVCardTime('23:12:166');
-
-    }
-
-    function vcardDates() {
-
-        return array(
-            array(
-                "19961022T140000",
-                array(
-                    "year" => 1996,
-                    "month" => 10,
-                    "date" => 22,
-                    "hour" => 14,
-                    "minute" => 00,
-                    "second" => 00,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "--1022T1400",
-                array(
-                    "year" => null,
-                    "month" => 10,
-                    "date" => 22,
-                    "hour" => 14,
-                    "minute" => 00,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "---22T14",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => 22,
-                    "hour" => 14,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "19850412",
-                array(
-                    "year" => 1985,
-                    "month" => 4,
-                    "date" => 12,
-                    "hour" => null,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "1985-04",
-                array(
-                    "year" => 1985,
-                    "month" => 04,
-                    "date" => null,
-                    "hour" => null,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "1985",
-                array(
-                    "year" => 1985,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => null,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "--0412",
-                array(
-                    "year" => null,
-                    "month" => 4,
-                    "date" => 12,
-                    "hour" => null,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "---12",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => 12,
-                    "hour" => null,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "T102200",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => 10,
-                    "minute" => 22,
-                    "second" => 0,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "T1022",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => 10,
-                    "minute" => 22,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "T10",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => 10,
-                    "minute" => null,
-                    "second" => null,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "T-2200",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => null,
-                    "minute" => 22,
-                    "second" => 00,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "T--00",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => null,
-                    "minute" => null,
-                    "second" => 00,
-                    "timezone" => null
-                ),
-            ),
-            array(
-                "T102200Z",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => 10,
-                    "minute" => 22,
-                    "second" => 00,
-                    "timezone" => 'Z'
-                ),
-            ),
-            array(
-                "T102200-0800",
-                array(
-                    "year" => null,
-                    "month" => null,
-                    "date" => null,
-                    "hour" => 10,
-                    "minute" => 22,
-                    "second" => 00,
-                    "timezone" => '-0800'
-                ),
-            ),
-
-            // extended format
-            array(
-                "2012-11-29T15:10:53Z",
-                array(
-                    "year" => 2012,
-                    "month" => 11,
-                    "date" => 29,
-                    "hour" => 15,
-                    "minute" => 10,
-                    "second" => 53,
-                    "timezone" => 'Z'
-                ),
-            ),
-        );
-
-    }
-
-
-}
--- a/vendor/sabre/vobject/tests/VObject/DocumentTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class DocumentTest extends \PHPUnit_Framework_TestCase {
-
-    function testGetDocumentType() {
-
-        $doc = new MockDocument();
-        $this->assertEquals(Document::UNKNOWN, $doc->getDocumentType());
-
-    }
-
-    function testConstruct() {
-
-        $doc = new MockDocument('VLIST');
-        $this->assertEquals('VLIST', $doc->name);
-
-    }
-
-    function testCreateComponent() {
-
-        $vcal = new Component\VCalendar(array(), false);
-
-        $event = $vcal->createComponent('VEVENT');
-
-        $this->assertInstanceOf('Sabre\VObject\Component\VEvent', $event);
-        $vcal->add($event);
-
-        $prop = $vcal->createProperty('X-PROP','1234256',array('X-PARAM' => '3'));
-        $this->assertInstanceOf('Sabre\VObject\Property', $prop);
-
-        $event->add($prop);
-
-        unset(
-            $event->DTSTAMP,
-            $event->UID
-        );
-
-        $out = $vcal->serialize();
-        $this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nX-PROP;X-PARAM=3:1234256\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $out);
-
-    }
-
-    function testCreate() {
-
-        $vcal = new Component\VCalendar(array(), false);
-
-        $event = $vcal->create('VEVENT');
-        $this->assertInstanceOf('Sabre\VObject\Component\VEvent', $event);
-
-        $event = $vcal->create('CALSCALE');
-        $this->assertInstanceOf('Sabre\VObject\Property\Text', $event);
-
-    }
-
-    function testGetClassNameForPropertyValue() {
-
-        $vcal = new Component\VCalendar(array(), false);
-        $this->assertEquals('Sabre\\VObject\\Property\\Text', $vcal->getClassNameForPropertyValue('TEXT'));
-        $this->assertNull($vcal->getClassNameForPropertyValue('FOO'));
-
-    }
-
-}
-
-
-class MockDocument extends Document {
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ElementListTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class ElementListTest extends \PHPUnit_Framework_TestCase {
-
-    function testIterate() {
-
-        $cal = new Component\VCalendar();
-        $sub = $cal->createComponent('VEVENT');
-
-        $elems = array(
-            $sub,
-            clone $sub,
-            clone $sub
-        );
-
-        $elemList = new ElementList($elems);
-
-        $count = 0;
-        foreach($elemList as $key=>$subcomponent) {
-
-           $count++;
-           $this->assertInstanceOf('Sabre\\VObject\\Component',$subcomponent);
-
-        }
-        $this->assertEquals(3,$count);
-        $this->assertEquals(2,$key);
-
-    }
-
-
-}
--- a/vendor/sabre/vobject/tests/VObject/EmClientTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class EmClientTest extends \PHPUnit_Framework_TestCase {
-
-    function testParseTz() {
-
-        $str = 'BEGIN:VCALENDAR
-X-WR-CALNAME:Blackhawks Schedule 2011-12
-X-APPLE-CALENDAR-COLOR:#E51717
-X-WR-TIMEZONE:America/Chicago
-CALSCALE:GREGORIAN
-PRODID:-//eM Client/4.0.13961.0
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:America/Chicago
-BEGIN:DAYLIGHT
-TZOFFSETFROM:-0600
-RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
-DTSTART:20070311T020000
-TZNAME:CDT
-TZOFFSETTO:-0500
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:-0500
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
-DTSTART:20071104T020000
-TZNAME:CST
-TZOFFSETTO:-0600
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-CREATED:20110624T181236Z
-UID:be3bbfff-96e8-4c66-9908-ab791a62231d
-DTEND;TZID="America/Chicago":20111008T223000
-TRANSP:OPAQUE
-SUMMARY:Stars @ Blackhawks (Home Opener)
-DTSTART;TZID="America/Chicago":20111008T193000
-DTSTAMP:20120330T013232Z
-SEQUENCE:2
-X-MICROSOFT-CDO-BUSYSTATUS:BUSY
-LAST-MODIFIED:20120330T013237Z
-CLASS:PUBLIC
-END:VEVENT
-END:VCALENDAR';
-
-        $vObject = Reader::read($str);
-        $dt = $vObject->VEVENT->DTSTART->getDateTime();
-        $this->assertEquals(new \DateTime('2011-10-08 19:30:00', new \DateTimeZone('America/Chicago')), $dt);
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/EmptyParameterTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class IssueEmptyParameterTest extends \PHPUnit_Framework_TestCase {
-
-    function testRead() {
-
-        $input = <<<VCF
-BEGIN:VCARD
-VERSION:2.1
-N:Doe;Jon;;;
-FN:Jon Doe
-EMAIL;X-INTERN:foo@example.org
-UID:foo
-END:VCARD
-VCF;
-
-        $vcard = Reader::read($input);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard);
-        $vcard = $vcard->convert(\Sabre\VObject\Document::VCARD30);
-        $vcard = $vcard->serialize();
-
-        $converted = Reader::read($vcard);
-        $converted->validate();
-
-        $this->assertTrue(isset($converted->EMAIL['X-INTERN']));
-
-        $version = Version::VERSION;
-
-        $expected = <<<VCF
-BEGIN:VCARD
-VERSION:3.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-N:Doe;Jon;;;
-FN:Jon Doe
-EMAIL;X-INTERN=:foo@example.org
-UID:foo
-END:VCARD
-
-VCF;
-
-        $this->assertEquals($expected, str_replace("\r","", $vcard));
-
-    }
-
-    function testVCard21Parameter() {
-
-        $vcard = new Component\VCard(array(), false);
-        $vcard->VERSION = '2.1';
-        $vcard->PHOTO = 'random_stuff';
-        $vcard->PHOTO->add(null,'BASE64');
-        $vcard->UID = 'foo-bar';
-
-        $result = $vcard->serialize();
-        $expected = array(
-            "BEGIN:VCARD",
-            "VERSION:2.1",
-            "PHOTO;BASE64:" . base64_encode('random_stuff'),
-            "UID:foo-bar",
-            "END:VCARD",
-            "",
-        );
-
-        $this->assertEquals(implode("\r\n", $expected), $result);
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/EmptyValueIssueTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This test is written for Issue 68:
- *
- * https://github.com/fruux/sabre-vobject/issues/68 
- */
-class EmptyValueIssueTest extends \PHPUnit_Framework_TestCase {
-
-    function testDecodeValue() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-DESCRIPTION:This is a descpription\\nwith a linebreak and a \\; \\, and :
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vobj = Reader::read($input);
-
-        // Before this bug was fixed, getValue() would return nothing.
-        $this->assertEquals("This is a descpription\nwith a linebreak and a ; , and :", $vobj->VEVENT->DESCRIPTION->getValue());
-
-    }
-
-}
-
--- a/vendor/sabre/vobject/tests/VObject/FreeBusyGeneratorTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class FreeBusyGeneratorTest extends \PHPUnit_Framework_TestCase {
-
-    function getInput() {
-
-        $tests = array();
-
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20110101T120000Z
-DTEND:20110101T130000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            "20110101T120000Z/20110101T130000Z"
-        );
-
-        // opaque, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar2
-TRANSP:OPAQUE
-DTSTART:20110101T130000Z
-DTEND:20110101T140000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            "20110101T130000Z/20110101T140000Z"
-        );
-
-        // transparent, hidden
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar3
-TRANSP:TRANSPARENT
-DTSTART:20110101T140000Z
-DTEND:20110101T150000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            null,
-        );
-
-        // cancelled, hidden
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar4
-STATUS:CANCELLED
-DTSTART:20110101T160000Z
-DTEND:20110101T170000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            null,
-        );
-
-        // tentative, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar5
-STATUS:TENTATIVE
-DTSTART:20110101T180000Z
-DTEND:20110101T190000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            '20110101T180000Z/20110101T190000Z',
-        );
-
-        // outside of time-range, hidden
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar6
-DTSTART:20110101T090000Z
-DTEND:20110101T100000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            null,
-        );
-
-        // outside of time-range, hidden
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar7
-DTSTART:20110104T090000Z
-DTEND:20110104T100000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            null,
-        );
-
-        // using duration, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar8
-DTSTART:20110101T190000Z
-DURATION:PT1H
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            '20110101T190000Z/20110101T200000Z',
-        );
-
-        // Day-long event, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar9
-DTSTART;VALUE=DATE:20110102
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            '20110102T000000Z/20110103T000000Z',
-        );
-
-
-        // No duration, does not show up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar10
-DTSTART:20110101T200000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            null,
-        );
-
-        // encoded as object, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar11
-DTSTART:20110101T210000Z
-DURATION:PT1H
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            Reader::read($blob),
-            '20110101T210000Z/20110101T220000Z',
-        );
-
-        // Freebusy. Some parts show up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VFREEBUSY
-FREEBUSY:20110103T010000Z/20110103T020000Z
-FREEBUSY;FBTYPE=FREE:20110103T020000Z/20110103T030000Z
-FREEBUSY:20110103T030000Z/20110103T040000Z,20110103T040000Z/20110103T050000Z
-FREEBUSY:20120101T000000Z/20120101T010000Z
-FREEBUSY:20110103T050000Z/PT1H
-END:VFREEBUSY
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            Reader::read($blob),
-            array(
-                '20110103T010000Z/20110103T020000Z',
-                '20110103T030000Z/20110103T040000Z',
-                '20110103T040000Z/20110103T050000Z',
-                '20110103T050000Z/20110103T060000Z',
-            )
-        );
-
-
-        // Yearly recurrence rule, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar13
-DTSTART:20100101T220000Z
-DTEND:20100101T230000Z
-RRULE:FREQ=YEARLY
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            Reader::read($blob),
-            '20110101T220000Z/20110101T230000Z',
-        );
-
-
-        // Yearly recurrence rule + duration, shows up
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar14
-DTSTART:20100101T230000Z
-DURATION:PT1H
-RRULE:FREQ=YEARLY
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            Reader::read($blob),
-            '20110101T230000Z/20110102T000000Z',
-        );
-
-        // Floating time, no timezone
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20110101T120000
-DTEND:20110101T130000
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            "20110101T120000Z/20110101T130000Z"
-        );
-
-        // Floating time + reference timezone
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20110101T120000
-DTEND:20110101T130000
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            "20110101T170000Z/20110101T180000Z",
-            new \DateTimeZone('America/Toronto')
-        );
-
-        // All-day event
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART;VALUE=DATE:20110101
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            "20110101T000000Z/20110102T000000Z"
-        );
-
-        // All-day event + reference timezone
-        $blob = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART;VALUE=DATE:20110101
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $tests[] = array(
-            $blob,
-            "20110101T050000Z/20110102T050000Z",
-            new \DateTimeZone('America/Toronto')
-        );
-        return $tests;
-
-    }
-
-    /**
-     * @dataProvider getInput
-     */
-    function testGenerator($input, $expected, $timeZone = null) {
-
-        $gen = new FreeBusyGenerator(
-            new \DateTime('20110101T110000Z', new \DateTimeZone('UTC')),
-            new \DateTime('20110103T110000Z', new \DateTimeZone('UTC')),
-            $input,
-            $timeZone
-        );
-
-        $result = $gen->getResult();
-
-        $expected = (array)$expected;
-
-        $freebusy = $result->VFREEBUSY->select('FREEBUSY');
-
-        foreach($freebusy as $fb) {
-
-            $this->assertContains((string)$fb, $expected, "$fb did not appear in our list of expected freebusy strings. This is concerning!");
-
-            $k = array_search((string)$fb, $expected);
-            unset($expected[$k]);
-
-        }
-        $this->assertTrue(
-            count($expected) === 0,
-            'There were elements in the expected array that were not found in the output: ' . "\n"  . print_r($expected,true) . "\n" . $result->serialize()
-        );
-
-    }
-
-    function testGeneratorBaseObject() {
-
-        $obj = new Component\VCalendar();
-        $obj->METHOD = 'PUBLISH';
-
-        $gen = new FreeBusyGenerator();
-        $gen->setObjects(array());
-        $gen->setBaseObject($obj);
-
-        $result = $gen->getResult();
-
-        $this->assertEquals('PUBLISH', $result->METHOD->getValue());
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testInvalidArg() {
-
-        $gen = new FreeBusyGenerator(
-            new \DateTime('2012-01-01'),
-            new \DateTime('2012-12-31'),
-            new \StdClass()
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/GoogleColonEscapingTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Google produces vcards with a weird escaping of urls.
- *
- * VObject will provide a workaround for this, so end-user still get expected
- * values.
- */
-class GoogleColonEscaping extends \PHPUnit_Framework_TestCase {
-
-    function testDecode() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:3.0
-FN:Evert Pot
-N:Pot;Evert;;;
-EMAIL;TYPE=INTERNET;TYPE=WORK:evert@fruux.com
-BDAY:1985-04-07
-item7.URL:http\://www.rooftopsolutions.nl/
-END:VCARD
-VCF;
-
-        $vobj = Reader::read($vcard);
-        $this->assertEquals('http://www.rooftopsolutions.nl/', $vobj->URL->getValue());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ICalendar/AttachParseTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ICalendar;
-
-use Sabre\VObject\Reader;
-
-class AttachParseTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * See issue #128 for more info.
-     */
-    function testParseAttach() {
-
-        $vcal = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-ATTACH;FMTTYPE=application/postscript:ftp://example.com/pub/reports/r-960812.ps
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($vcal);
-        $prop = $vcal->VEVENT->ATTACH;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property\\URI', $prop);
-        $this->assertEquals('ftp://example.com/pub/reports/r-960812.ps', $prop->getValue());
-
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerAttendeeReplyTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,962 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class BrokerAttendeeReplyTest extends BrokerTester {
-
-    function testAccepted() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SUMMARY:B-day party
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SUMMARY:B-day party
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => 'One',
-                'recipient' => 'mailto:strunk@example.org',
-                'recipientName' => 'Strunk',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-SUMMARY:B-day party
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testRecurringReply() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140724T120000Z
-SUMMARY:Daily sprint
-RRULE;FREQ=DAILY
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
-DTSTART:20140724T120000Z
-SUMMARY:Daily sprint
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART:20140726T120000Z
-RECURRENCE-ID:20140726T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-DTSTART:20140724T120000Z
-RECURRENCE-ID:20140724T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
-DTSTART:20140728T120000Z
-RECURRENCE-ID:20140728T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART:20140729T120000Z
-RECURRENCE-ID:20140729T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-DTSTART:20140725T120000Z
-RECURRENCE-ID:20140725T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => 'One',
-                'recipient' => 'mailto:strunk@example.org',
-                'recipientName' => 'Strunk',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140726T120000Z
-SUMMARY:Daily sprint
-RECURRENCE-ID:20140726T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140724T120000Z
-SUMMARY:Daily sprint
-RECURRENCE-ID:20140724T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140728T120000Z
-SUMMARY:Daily sprint
-RECURRENCE-ID:20140728T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140729T120000Z
-SUMMARY:Daily sprint
-RECURRENCE-ID:20140729T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140725T120000Z
-SUMMARY:Daily sprint
-RECURRENCE-ID:20140725T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testRecurringAllDay() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140724
-RRULE;FREQ=DAILY
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-    $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140724
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140726
-RECURRENCE-ID;VALUE=DATE:20140726
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140724
-RECURRENCE-ID;VALUE=DATE:20140724
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140728
-RECURRENCE-ID;VALUE=DATE:20140728
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140729
-RECURRENCE-ID;VALUE=DATE:20140729
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140725
-RECURRENCE-ID;VALUE=DATE:20140725
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-    $version = \Sabre\VObject\Version::VERSION;
-
-    $expected = array(
-        array(
-            'uid' => 'foobar',
-            'method' => 'REPLY',
-            'component' => 'VEVENT',
-            'sender' => 'mailto:one@example.org',
-            'senderName' => 'One',
-            'recipient' => 'mailto:strunk@example.org',
-            'recipientName' => 'Strunk',
-            'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140726
-RECURRENCE-ID;VALUE=DATE:20140726
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140724
-RECURRENCE-ID;VALUE=DATE:20140724
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140728
-RECURRENCE-ID;VALUE=DATE:20140728
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140729
-RECURRENCE-ID;VALUE=DATE:20140729
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140725
-RECURRENCE-ID;VALUE=DATE:20140725
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testNoChange() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $expected = array();
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testNoChangeForceSend() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;SCHEDULE-FORCE-SEND=REPLY;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => 'One',
-                'recipient' => 'mailto:strunk@example.org',
-                'recipientName' => 'Strunk',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-            )
-
-        );
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testNoRelevantAttendee() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = array();
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    /**
-     * In this test, an event exists in an attendees calendar. The event
-     * is recurring, and the attendee deletes 1 instance of the event.
-     * This instance shows up in EXDATE
-     *
-     * This should automatically generate a DECLINED message for that
-     * specific instance.
-     */
-    function testCreateReplyByException() {
-
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140811T200000Z
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140811T200000Z
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-EXDATE:20140818T200000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => null,
-                'recipient' => 'mailto:organizer@example.org',
-                'recipientName' => null,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140818T200000Z
-RECURRENCE-ID:20140818T200000Z
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    /**
-     * This test is identical to the last, but now we're working with
-     * timezones.
-     *
-     * @depends testCreateReplyByException
-     */
-    function testCreateReplyByExceptionTz() {
-
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;TZID=America/Toronto:20140811T200000
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;TZID=America/Toronto:20140811T200000
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-EXDATE;TZID=America/Toronto:20140818T200000
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => null,
-                'recipient' => 'mailto:organizer@example.org',
-                'recipientName' => null,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;TZID=America/Toronto:20140818T200000
-RECURRENCE-ID;TZID=America/Toronto:20140818T200000
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    /**
-     * @depends testCreateReplyByException
-     */
-    function testCreateReplyByExceptionAllDay() {
-
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SUMMARY:Weekly meeting
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140811
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SUMMARY:Weekly meeting
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140811
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-EXDATE;VALUE=DATE:20140818
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => null,
-                'recipient' => 'mailto:organizer@example.org',
-                'recipientName' => null,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140818
-SUMMARY:Weekly meeting
-RECURRENCE-ID;VALUE=DATE:20140818
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testDeclined() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => 'One',
-                'recipient' => 'mailto:strunk@example.org',
-                'recipientName' => 'Strunk',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testDeclinedCancelledEvent() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-STATUS:CANCELLED
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-STATUS:CANCELLED
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array();
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    /**
-     * In this test, a new exception is created by an attendee as well.
-     *
-     * Except in this case, there was already an overridden event, and the
-     * overridden event was marked as cancelled by the attendee.
-     *
-     * For any other attendence status, the new status would have been
-     * declined, but for this, no message should we sent.
-     */
-    function testDontCreateReplyWhenEventWasDeclined() {
-
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140811T200000Z
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-END:VEVENT
-BEGIN:VEVENT
-RECURRENCE-ID:20140818T200000Z
-UID:foobar
-SEQUENCE:1
-DTSTART:20140818T200000Z
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140811T200000Z
-RRULE:FREQ=WEEKLY
-ORGANIZER:mailto:organizer@example.org
-ATTENDEE:mailto:one@example.org
-EXDATE:20140818T200000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $expected = array();
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testScheduleAgentOnOrganizer() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;SCHEDULE-AGENT=CLIENT;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array();
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-    function testAcceptedAllDay() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140716
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-DTSTART;VALUE=DATE:20140716
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => 'One',
-                'recipient' => 'mailto:strunk@example.org',
-                'recipientName' => 'Strunk',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART;VALUE=DATE:20140716
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerDeleteEventTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class BrokerDeleteEventTest extends BrokerTester {
-
-    function testOrganizerDelete() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = null;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-            ),
-
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:two@example.org',
-                'recipientName' => 'Two',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testAttendeeDelete() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = null;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REPLY',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:one@example.org',
-                'senderName' => 'One',
-                'recipient' => 'mailto:strunk@example.org',
-                'recipientName' => 'Strunk',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-            ),
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected, 'mailto:one@example.org');
-
-
-    }
-
-    function testAttendeeDeleteCancelledEvent() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-STATUS:CANCELLED
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = null;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array();
-
-        $result = $this->parse($oldMessage, $newMessage, $expected, 'mailto:one@example.org');
-
-
-    }
-
-    function testNoCalendar() {
-
-        $this->parse(null, null, array(), 'mailto:one@example.org');
-
-    }
-
-    function testVTodo() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VTODO
-UID:foobar
-SEQUENCE:1
-END:VTODO
-END:VCALENDAR
-ICS;
-        $this->parse($oldMessage, null, array(), 'mailto:one@example.org');
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerNewEventTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,507 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class BrokerNewEventTest extends \PHPUnit_Framework_TestCase {
-
-    function testNoAttendee() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140811T220000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->parse($message);
-
-    }
-
-    function testVTODO() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VTODO
-UID:foobar
-END:VTODO
-END:VCALENDAR
-ICS;
-
-        $result = $this->parse($message);
-
-    }
-
-    function testSimpleInvite() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140811T220000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=White:mailto:white@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $expectedMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140811T220000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=White;PARTSTAT=NEEDS-ACTION:mailto:white@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:white@example.org',
-                'recipientName' => 'White',
-                'message' => $expectedMessage,
-            ),
-        );
-
-        $result = $this->parse($message, $expected);
-
-    }
-
-    /**
-     * @expectedException \Sabre\VObject\ITip\ITipException
-     */
-    function testBrokenEventUIDMisMatch() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=White:mailto:white@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=White:mailto:white@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = array();
-        $this->parse($message, array());
-
-    }
-    /**
-     * @expectedException \Sabre\VObject\ITip\ITipException
-     */
-    function testBrokenEventOrganizerMisMatch() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=White:mailto:white@example.org
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER:mailto:foo@example.org
-ATTENDEE;CN=White:mailto:white@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = array();
-        $this->parse($message, array());
-
-    }
-
-    function testRecurrenceInvite() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-EXDATE:20140717T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-EXDATE:20140717T120000Z,20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:two@example.org',
-                'recipientName' => 'Two',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-EXDATE:20140717T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:three@example.org',
-                'recipientName' => 'Three',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $result = $this->parse($message, $expected);
-
-    }
-
-    function testRecurrenceInvite2() {
-
-        // This method tests a nearly identical path, but in this case the
-        // master event does not have an EXDATE.
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-EXDATE:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:two@example.org',
-                'recipientName' => 'Two',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:three@example.org',
-                'recipientName' => 'Three',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $result = $this->parse($message, $expected);
-
-    }
-
-    function testScheduleAgentClient() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140811T220000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=White;SCHEDULE-AGENT=CLIENT:mailto:white@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array();
-        $result = $this->parse($message, $expected);
-
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ITip\ITipException
-     */
-    function testMultipleUID() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar2
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $result = $this->parse($message, array());
-
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ITip\SameOrganizerForAllComponentsException
-     *
-     */
-    function testChangingOrganizers() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140718T120000Z
-ORGANIZER;CN=Strunk:mailto:ew@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140718T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-        $result = $this->parse($message, array());
-
-    }
-    function testNoOrganizerHasAttendee() {
-
-        $message = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140811T220000Z
-ATTENDEE;CN=Two:mailto:two@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $this->parse($message, array());
-
-    }
-
-    function parse($message, $expected = array()) {
-
-        $broker = new Broker();
-        $result = $broker->parseEvent($message, 'mailto:strunk@example.org');
-
-        $this->assertEquals(count($expected), count($result));
-
-        foreach($expected as $index=>$ex) {
-
-            $message = $result[$index];
-
-            foreach($ex as $key=>$val) {
-
-                if ($key==='message') {
-                    $this->assertEquals(
-                        str_replace("\n", "\r\n", $val),
-                        rtrim($message->message->serialize(), "\r\n")
-                    );
-                } else {
-                    $this->assertEquals($val, $message->$key);
-                }
-
-            }
-
-        }
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerProcessMessageTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class BrokerProcessMessageTest extends BrokerTester {
-
-    function testRequestNew() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REQUEST
-BEGIN:VEVENT
-SEQUENCE:1
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-%foo%
-BEGIN:VEVENT
-SEQUENCE:1
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, null, $expected);
-
-    }
-
-    function testRequestUpdate() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REQUEST
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-%foo%
-BEGIN:VEVENT
-SEQUENCE:1
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-%foo%
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testCancel() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:CANCEL
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-%foo%
-BEGIN:VEVENT
-SEQUENCE:1
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-%foo%
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-STATUS:CANCELLED
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testCancelNoExistingEvent() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:CANCEL
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = null;
-        $expected = null;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testUnsupportedComponent() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VTODO
-SEQUENCE:2
-UID:foobar
-END:VTODO
-END:VCALENDAR
-ICS;
-
-        $old = null;
-        $expected = null;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testUnsupportedMethod() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:PUBLISH
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = null;
-        $expected = null;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerProcessReplyTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class BrokerProcessReplyTest extends BrokerTester {
-
-    function testReplyNoOriginal() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = null;
-        $expected = null;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testReplyAccept() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testReplyRequestStatus() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-UID:foobar
-REQUEST-STATUS:2.3;foo-bar!
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.3:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-
-    function testReplyPartyCrasher() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:crasher@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:crasher@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testReplyNewException() {
-
-        // This is a reply to 1 instance of a recurring event. This should
-        // automatically create an exception.
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-RECURRENCE-ID:20140725T000000Z
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART:20140724T000000Z
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART:20140724T000000Z
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-DTSTART:20140725T000000Z
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-RECURRENCE-ID:20140725T000000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testReplyNewExceptionTz() {
-
-        // This is a reply to 1 instance of a recurring event. This should
-        // automatically create an exception.
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-RECURRENCE-ID;TZID=America/Toronto:20140725T000000
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART;TZID=America/Toronto:20140724T000000
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART;TZID=America/Toronto:20140724T000000
-ATTENDEE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-DTSTART;TZID=America/Toronto:20140725T000000
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-RECURRENCE-ID;TZID=America/Toronto:20140725T000000
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testReplyPartyCrashCreateExcepton() {
-
-        // IN this test there's a recurring event that has an exception. The
-        // exception is missing the attendee.
-        //
-        // The attendee party crashes the instance, so it should show up in the
-        // resulting object.
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED;CN=Crasher!:mailto:crasher@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-RECURRENCE-ID:20140725T000000Z
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART:20140724T000000Z
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART:20140724T000000Z
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-DTSTART:20140725T000000Z
-ORGANIZER:mailto:bar@example.org
-RECURRENCE-ID:20140725T000000Z
-ATTENDEE;PARTSTAT=ACCEPTED;CN=Crasher!:mailto:crasher@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    function testReplyNewExceptionNoMasterEvent() {
-
-        /**
-         * This iTip message would normally create a new exception, but the
-         * server is not able to create this new instance, because there's no
-         * master event to clone from.
-         *
-         * This test checks if the message is ignored.
-         */
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED;CN=Crasher!:mailto:crasher@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-RECURRENCE-ID:20140725T000000Z
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-RRULE:FREQ=DAILY
-DTSTART:20140724T000000Z
-RECURRENCE-ID:20140724T000000Z
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = null;
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-    /**
-     * @depends testReplyAccept
-     */
-    function testReplyAcceptUpdateRSVP() {
-
-        $itip = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-METHOD:REPLY
-BEGIN:VEVENT
-ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-SEQUENCE:2
-UID:foobar
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE;RSVP=TRUE:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SEQUENCE:2
-UID:foobar
-ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:foo@example.org
-ORGANIZER:mailto:bar@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $result = $this->process($itip, $old, $expected);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerTester.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-use Sabre\VObject\Reader;
-
-/**
- * Utilities for testing the broker
- * 
- * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
- * @author Evert Pot (http://evertpot.com/) 
- * @license http://sabre.io/license/ Modified BSD License
- */
-abstract class BrokerTester extends \PHPUnit_Framework_TestCase {
-
-    function parse($oldMessage, $newMessage, $expected = array(), $currentUser = 'mailto:one@example.org') {
-
-        $broker = new Broker();
-        $result = $broker->parseEvent($newMessage, $currentUser, $oldMessage);
-
-        $this->assertEquals(count($expected), count($result));
-
-        foreach($expected as $index=>$ex) {
-
-            $message = $result[$index];
-
-            foreach($ex as $key=>$val) {
-
-                if ($key==='message') {
-                    $this->assertEquals(
-                        str_replace("\n", "\r\n", $val),
-                        rtrim($message->message->serialize(), "\r\n")
-                    );
-                } else {
-                    $this->assertEquals($val, $message->$key);
-                }
-
-            }
-
-        }
-
-    }
-
-    function process($input, $existingObject = null, $expected = false) {
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $vcal = Reader::read($input);
-
-        foreach($vcal->getComponents() as $mainComponent) {
-            break;
-        }
-
-        $message = new Message();
-        $message->message = $vcal;
-        $message->method = isset($vcal->METHOD)?$vcal->METHOD->getValue():null;
-        $message->component = $mainComponent->name;
-        $message->uid = $mainComponent->uid->getValue();
-        $message->sequence = isset($vcal->VEVENT[0])?(string)$vcal->VEVENT[0]->SEQUENCE:null;
-
-        if ($message->method === 'REPLY') {
-
-            $message->sender = $mainComponent->ATTENDEE->getValue();
-            $message->senderName = isset($mainComponent->ATTENDEE['CN'])?$mainComponent->ATTENDEE['CN']->getValue():null;
-            $message->recipient = $mainComponent->ORGANIZER->getValue();
-            $message->recipientName = isset($mainComponent->ORGANIZER['CN'])?$mainComponent->ORGANIZER['CN']:null;
-
-        }
-
-        $broker = new Broker();
-
-        if (is_string($existingObject)) {
-            $existingObject = str_replace(
-                '%foo%',
-                "VERSION:2.0\nPRODID:-//Sabre//Sabre VObject $version//EN\nCALSCALE:GREGORIAN",
-                $existingObject
-            );
-            $existingObject = Reader::read($existingObject);
-        }
-
-        $result = $broker->processMessage($message, $existingObject);
-
-        if (is_string($expected)) {
-            $expected = str_replace(
-                '%foo%',
-                "VERSION:2.0\nPRODID:-//Sabre//Sabre VObject $version//EN\nCALSCALE:GREGORIAN",
-                $expected
-            );
-            $expected = str_replace("\n", "\r\n", $expected);
-
-        }
-        if ($result instanceof \Sabre\VObject\Component\VCalendar) {
-            $result = $result->serialize();
-            $result = rtrim($result,"\r\n");
-        }
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/BrokerUpdateEventTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,719 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class BrokerUpdateTest extends BrokerTester {
-
-    function testInviteChange() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:two@example.org',
-                'recipientName' => 'Two',
-                'significantChange' => false,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:three@example.org',
-                'recipientName' => 'Three',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testInviteChangeFromNonSchedulingToSchedulingObject() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testInviteChangeFromSchedulingToNonSchedulingObject() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testNoAttendees() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array();
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testRemoveInstance() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART;TZID=America/Toronto:20140716T120000
-RRULE:FREQ=WEEKLY
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART;TZID=America/Toronto:20140716T120000
-RRULE:FREQ=WEEKLY
-EXDATE;TZID=America/Toronto:20140724T120000
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-DTSTART;TZID=America/Toronto:20140716T120000
-RRULE:FREQ=WEEKLY
-EXDATE;TZID=America/Toronto:20140724T120000
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    /**
-     * This test is identical to the first test, except this time we change the
-     * DURATION property.
-     *
-     * This should ensure that the message is significant for every attendee,
-     */
-    function testInviteChangeSignificantChange() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-DURATION:PT1H
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-DURATION:PT2H
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-ATTENDEE;CN=Three:mailto:three@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:two@example.org',
-                'recipientName' => 'Two',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-DURATION:PT2H
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:three@example.org',
-                'recipientName' => 'Three',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-DURATION:PT2H
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
-ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testInviteNoChange() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'significantChange' => false,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testInviteNoChangeForceSend() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;SCHEDULE-FORCE-SEND=REQUEST;CN=One:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'REQUEST',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
-ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-
-        );
-
-        $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-
-    function testInviteRemoveAttendees() {
-
-        $oldMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:1
-SUMMARY:foo
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-
-        $newMessage = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-DTSTART:20140716T120000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION;
-
-        $expected = array(
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:one@example.org',
-                'recipientName' => 'One',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=One:mailto:one@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-            array(
-                'uid' => 'foobar',
-                'method' => 'CANCEL',
-                'component' => 'VEVENT',
-                'sender' => 'mailto:strunk@example.org',
-                'senderName' => 'Strunk',
-                'recipient' => 'mailto:two@example.org',
-                'recipientName' => 'Two',
-                'significantChange' => true,
-                'message' => <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:CANCEL
-BEGIN:VEVENT
-UID:foobar
-SEQUENCE:2
-SUMMARY:foo
-DTSTART:20140716T120000Z
-ORGANIZER;CN=Strunk:mailto:strunk@example.org
-ATTENDEE;CN=Two:mailto:two@example.org
-END:VEVENT
-END:VCALENDAR
-ICS
-
-            ),
-        );
-
-        $result = $this->parse($oldMessage, $newMessage, $expected, 'mailto:strunk@example.org');
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/EvolutionTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2653 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class EvolutionTest extends BrokerTester {
-
-    /**
-     * Evolution does things as usual a little bit differently.
-     *
-     * We're adding a seprate test just for it.
-     */
-    function testNewEvolutionEvent() {
-
-        $ics = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Ximian//NONSGML Evolution Calendar//EN
-BEGIN:VTIMEZONE
-TZID:/freeassociation.sourceforge.net/Tzfile/America/Toronto
-X-LIC-LOCATION:America/Toronto
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19691026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19700426T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19701025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19710425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19711031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19720430T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19721029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19730429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19731028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19740428T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19741027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19750427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19751026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19760425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19761031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19770424T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19771030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19780430T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19781029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19790429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19791028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19800427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19801026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19810426T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19811025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19820425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19821031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19830424T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19831030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19840429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19841028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19850428T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19851027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19860427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19861026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19870405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19871025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19880403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19881030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19890402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19891029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19900401T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19901028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19910407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19911027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19920405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19921025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19930404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19931031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19940403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19941030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19950402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19951029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19960407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19961027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19970406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19971026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19980405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19981025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19990404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19991031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20000402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20001029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20010401T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20011028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20020407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20021027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20030406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20031026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20040404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20041031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20050403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20051030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20060402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20061029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20070311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20071104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20080309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20081102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20090308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20091101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20100314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20101107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20110313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20111106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20120311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20121104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20130310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20131103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20140309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20141102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20150308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20151101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20160313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20161106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20170312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20171105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20180311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20181104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20190310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20191103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20200308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20201101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20210314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20211107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20220313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20221106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20230312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20231105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20240310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20241103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20250309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20251102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20260308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20261101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20270314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20271107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20280312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20281105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20290311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20291104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20300310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20301103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20310309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20311102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20320314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20321107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20330313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20331106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20340312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20341105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20350311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20351104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20360309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20361102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20370308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20371101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:20140813T153116Z-12176-1000-1065-6@johnny-lubuntu
-DTSTAMP:20140813T142829Z
-DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/America/Toronto:201408
- 15T110000
-DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/America/Toronto:20140815
- T113000
-TRANSP:OPAQUE
-SEQUENCE:2
-SUMMARY:Evo makes a Meeting (fruux HQ) (fruux HQ)
-LOCATION:fruux HQ
-CLASS:PUBLIC
-ORGANIZER;SENT-BY="MAILTO:martin+johnny@fruux.com":MAILTO:martin@fruux.com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
- ;SENT-BY="MAILTO:martin+johnny@fruux.com";LANGUAGE=en:MAILTO:martin@fruux.
- com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
- TRUE;LANGUAGE=en:MAILTO:dominik@fruux.com
-CREATED:20140813T153211Z
-LAST-MODIFIED:20140813T155353Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $version = \Sabre\VObject\Version::VERSION; 
-        $expectedICS = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-METHOD:REQUEST
-BEGIN:VTIMEZONE
-TZID:/freeassociation.sourceforge.net/Tzfile/America/Toronto
-X-LIC-LOCATION:America/Toronto
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19691026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19700426T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19701025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19710425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19711031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19720430T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19721029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19730429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19731028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19740428T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19741027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19750427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19751026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19760425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19761031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19770424T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19771030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19780430T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19781029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19790429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19791028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19800427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19801026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19810426T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19811025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19820425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19821031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19830424T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19831030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19840429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19841028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19850428T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19851027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19860427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19861026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19870405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19871025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19880403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19881030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19890402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19891029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19900401T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19901028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19910407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19911027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19920405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19921025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19930404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19931031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19940403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19941030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19950402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19951029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19960407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19961027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19970406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19971026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19980405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19981025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19990404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19991031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20000402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20001029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20010401T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20011028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20020407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20021027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20030406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20031026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20040404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20041031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20050403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20051030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20060402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20061029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20070311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20071104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20080309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20081102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20090308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20091101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20100314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20101107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20110313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20111106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20120311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20121104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20130310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20131103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20140309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20141102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20150308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20151101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20160313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20161106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20170312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20171105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20180311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20181104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20190310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20191103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20200308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20201101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20210314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20211107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20220313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20221106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20230312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20231105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20240310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20241103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20250309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20251102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20260308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20261101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20270314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20271107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20280312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20281105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20290311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20291104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20300310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20301103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20310309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20311102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20320314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20321107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20330313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20331106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20340312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20341105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20350311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20351104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20360309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20361102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20370308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20371101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:20140813T153116Z-12176-1000-1065-6@johnny-lubuntu
-DTSTAMP:20140813T142829Z
-DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/America/Toronto:201408
- 15T110000
-DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/America/Toronto:20140815
- T113000
-TRANSP:OPAQUE
-SEQUENCE:2
-SUMMARY:Evo makes a Meeting (fruux HQ) (fruux HQ)
-LOCATION:fruux HQ
-CLASS:PUBLIC
-ORGANIZER;SENT-BY="MAILTO:martin+johnny@fruux.com":MAILTO:martin@fruux.com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
- ;SENT-BY="MAILTO:martin+johnny@fruux.com";LANGUAGE=en:MAILTO:martin@fruux.
- com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
- TRUE;LANGUAGE=en:MAILTO:dominik@fruux.com
-CREATED:20140813T153211Z
-LAST-MODIFIED:20140813T155353Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $expected = array(
-            array(
-                'uid' => '20140813T153116Z-12176-1000-1065-6@johnny-lubuntu',
-                'method' => 'REQUEST',
-                'sender' => 'mailto:martin@fruux.com',
-                'senderName' => null,
-                'recipient' => 'mailto:dominik@fruux.com',
-                'recipientName' => null,
-                'message' => $expectedICS,
-            )
-        ); 
-        $this->parse(null, $ics, $expected, 'mailto:martin@fruux.com');
-
-    }
-
-    /**
-     * This is an event originally from evolution, then parsed by sabredav and
-     * again mangled by iCal. This triggered a few bugs related to email
-     * address scheme casing.
-     */
-    public function testAttendeeModify() {
-
-        $old = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject 3.3.1//EN
-CALSCALE:GREGORIAN
-BEGIN:VTIMEZONE
-TZID:/freeassociation.sourceforge.net/Tzfile/America/Toronto
-X-LIC-LOCATION:America/Toronto
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19691026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19700426T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19701025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19710425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19711031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19720430T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19721029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19730429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19731028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19740428T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19741027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19750427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19751026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19760425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19761031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19770424T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19771030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19780430T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19781029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19790429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19791028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19800427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19801026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19810426T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19811025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19820425T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19821031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19830424T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19831030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19840429T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19841028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19850428T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19851027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19860427T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19861026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19870405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19871025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19880403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19881030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19890402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19891029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19900401T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19901028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19910407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19911027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19920405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19921025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19930404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19931031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19940403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19941030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19950402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19951029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19960407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19961027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19970406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19971026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19980405T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19981025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19990404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19991031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20000402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20001029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20010401T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20011028T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20020407T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20021027T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20030406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20031026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20040404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20041031T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20050403T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20051030T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20060402T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20061029T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20070311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20071104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20080309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20081102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20090308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20091101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20100314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20101107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20110313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20111106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20120311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20121104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20130310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20131103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20140309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20141102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20150308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20151101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20160313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20161106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20170312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20171105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20180311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20181104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20190310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20191103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20200308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20201101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20210314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20211107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20220313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20221106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20230312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20231105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20240310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20241103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20250309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20251102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20260308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20261101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20270314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20271107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20280312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20281105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20290311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20291104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20300310T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20301103T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20310309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20311102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20320314T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20321107T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20330313T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20331106T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20340312T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20341105T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20350311T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20351104T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20360309T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20361102T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:20370308T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:20371101T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:20140813T212317Z-6646-1000-1221-23@evert-ubuntu
-DTSTAMP:20140813T212221Z
-DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/America/Toronto:201408
- 13T180000
-DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/America/Toronto:20140813
- T200000
-TRANSP:OPAQUE
-SEQUENCE:4
-SUMMARY:Testing evolution
-LOCATION:Online
-CLASS:PUBLIC
-ORGANIZER:MAILTO:o@example.org
-CREATED:20140813T212510Z
-LAST-MODIFIED:20140813T212541Z
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;LANGUAGE=en:MAILTO:o@example.org
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;LANGUAGE=en:MAILTO:a1@example.org
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;LANGUAGE=en:MAILTO:a2@example.org
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;LANGUAGE=en:MAILTO:a3@example.org
-STATUS:CANCELLED
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $new = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Apple Inc.//Mac OS X 10.9.4//EN
-CALSCALE:GREGORIAN
-BEGIN:VTIMEZONE
-TZID:America/Toronto
-BEGIN:DAYLIGHT
-TZOFFSETFROM:-0500
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-DTSTART:20070311T020000
-TZNAME:EDT
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:-0400
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-DTSTART:20071104T020000
-TZNAME:EST
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-TRANSP:OPAQUE
-DTEND;TZID=America/Toronto:20140813T200000
-ORGANIZER:MAILTO:o@example.org
-UID:20140813T212317Z-6646-1000-1221-23@evert-ubuntu
-DTSTAMP:20140813T212221Z
-LOCATION:Online
-STATUS:CANCELLED
-SEQUENCE:4
-CLASS:PUBLIC
-SUMMARY:Testing evolution
-LAST-MODIFIED:20140813T212541Z
-DTSTART;TZID=America/Toronto:20140813T180000
-CREATED:20140813T212510Z
-ATTENDEE;CUTYPE=INDIVIDUAL;LANGUAGE=en;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:a2@example.org
-ATTENDEE;CUTYPE=INDIVIDUAL;LANGUAGE=en;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:o@example.org
-ATTENDEE;CUTYPE=INDIVIDUAL;LANGUAGE=en;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:a1@example.org
-ATTENDEE;CUTYPE=INDIVIDUAL;LANGUAGE=en;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:a3@example.org
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $this->parse($old, $new, array(), 'mailto:a1@example.org');
-
-
-    }
-
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ITip/MessageTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-<?php
-
-namespace Sabre\VObject\ITip;
-
-class MessageTest extends \PHPUnit_Framework_TestCase {
-
-    public function testNoScheduleStatus() {
-
-        $message = new Message();
-        $this->assertFalse($message->getScheduleStatus());
-
-    }
-
-    public function testScheduleStatus() {
-
-        $message = new Message();
-        $message->scheduleStatus = '1.2;Delivered';
-
-        $this->assertEquals('1.2', $message->getScheduleStatus());
-
-    }
-
-    public function testUnexpectedScheduleStatus() {
-
-        $message = new Message();
-        $message->scheduleStatus = '9.9.9';
-
-        $this->assertEquals('9.9.9', $message->getScheduleStatus());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Issue153Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class Issue153Test extends \PHPUnit_Framework_TestCase {
-
-    function testRead() {
-
-        $obj = Reader::read(file_get_contents(dirname(__FILE__) . '/issue153.vcf'));
-        $this->assertEquals('Test Benutzer', (string)$obj->fn);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Issue26Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    DateTime,
-    DateTimeZone;
-
-class Issue26Test extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    function testExpand() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:bae5d57a98
-RRULE:FREQ=MONTHLY;BYDAY=0MO,0TU,0WE,0TH,0FR;INTERVAL=1
-DTSTART;VALUE=DATE:20130401
-DTEND;VALUE=DATE:20130402
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $it = new Recur\EventIterator($vcal, 'bae5d57a98');
-        iterator_to_array($it);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Issue36WorkAroundTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class Issue36WorkAroundTest extends \PHPUnit_Framework_TestCase {
-
-    function testWorkaround() {
-
-        // See https://github.com/fruux/sabre-vobject/issues/36
-        $event = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-SUMMARY:Titel
-SEQUENCE:1
-TRANSP:TRANSPARENT
-RRULE:FREQ=YEARLY
-LAST-MODIFIED:20130323T225737Z
-DTSTAMP:20130323T225737Z
-UID:1833bd44-188b-405c-9f85-1a12105318aa
-CATEGORIES:Jubiläum
-X-MOZ-GENERATION:3
-RECURRENCE-ID;RANGE=THISANDFUTURE;VALUE=DATE:20131013
-DTSTART;VALUE=DATE:20131013
-CREATED:20100721T121914Z
-DURATION:P1D
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $obj = Reader::read($event);
-
-        // If this does not throw an exception, it's all good.
-        $it = new Recur\EventIterator($obj,'1833bd44-188b-405c-9f85-1a12105318aa');
-        $this->assertInstanceOf('Sabre\\VObject\\Recur\EventIterator', $it);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Issue40Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This test is created to handle the issues brought forward by issue 40.
- *
- * https://github.com/fruux/sabre-vobject/issues/40
- */
-class Issue40Test extends \PHPUnit_Framework_TestCase {
-
-    function testEncode() {
-
-        $card = new Component\VCard();
-        $card->add('N', array('van der Harten', array('Rene','J.'), "", 'Sir','R.D.O.N.'), array('SORT-AS' => array('Harten','Rene')));
-
-        $expected = implode("\r\n", array(
-            "BEGIN:VCARD",
-            "VERSION:3.0",
-            "PRODID:-//Sabre//Sabre VObject " . Version::VERSION . '//EN',
-            "N;SORT-AS=Harten,Rene:van der Harten;Rene,J.;;Sir;R.D.O.N.",
-            "END:VCARD",
-            ""
-        ));
-
-        $this->assertEquals($expected, $card->serialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Issue64Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class Issue64Test extends \PHPUnit_Framework_TestCase {
-
-    function testRead() {
-
-        $vcard = Reader::read(file_get_contents(dirname(__FILE__) . '/issue64.vcf'));
-        $vcard = $vcard->convert(\Sabre\VObject\Document::VCARD30);
-        $vcard = $vcard->serialize();
-
-        $converted = Reader::read($vcard);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $converted);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Issue96Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class Issue96Test extends \PHPUnit_Framework_TestCase {
-
-    function testRead() {
-
-        $input = <<<VCF
-BEGIN:VCARD
-VERSION:2.1
-SOURCE:Yahoo Contacts (http://contacts.yahoo.com)
-URL;CHARSET=utf-8;ENCODING=QUOTED-PRINTABLE:=
-http://www.example.org
-END:VCARD
-VCF;
-
-        $vcard = Reader::read($input, Reader::OPTION_FORGIVING);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard);
-        $this->assertEquals("http://www.example.org", $vcard->url->getValue());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/JCalTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class JCalTest extends \PHPUnit_Framework_TestCase {
-
-    function testToJCal() {
-
-        $cal = new Component\VCalendar();
-
-        $event = $cal->add('VEVENT', array(
-            "UID" => "foo",
-            "DTSTART" => new \DateTime("2013-05-26 18:10:00Z"),
-            "DURATION" => "P1D",
-            "CATEGORIES" => array('home', 'testing'),
-            "CREATED" => new \DateTime("2013-05-26 18:10:00Z"),
-
-            "ATTENDEE" => "mailto:armin@example.org",
-            "GEO" => array(51.96668, 7.61876),
-            "SEQUENCE" => 5,
-            "FREEBUSY" => array("20130526T210213Z/PT1H", "20130626T120000Z/20130626T130000Z"),
-            "URL" => "http://example.org/",
-            "TZOFFSETFROM" => "+05:00",
-            "RRULE" => array('FREQ' => 'WEEKLY', 'BYDAY' => array('MO','TU')),
-        ));
-
-        // Modifying DTSTART to be a date-only.
-        $event->dtstart['VALUE'] = 'DATE';
-        $event->add("X-BOOL", true, array('VALUE' => 'BOOLEAN'));
-        $event->add("X-TIME", "08:00:00", array('VALUE' => 'TIME'));
-        $event->add("ATTACH", "attachment", array('VALUE' => 'BINARY'));
-        $event->add("ATTENDEE", "mailto:dominik@example.org", array("CN" => "Dominik", "PARTSTAT" => "DECLINED"));
-
-        $event->add('REQUEST-STATUS', array("2.0", "Success"));
-        $event->add('REQUEST-STATUS', array("3.7", "Invalid Calendar User", "ATTENDEE:mailto:jsmith@example.org"));
-
-        $event->add('DTEND', '20150108T133000');
-
-        $expected = array(
-            "vcalendar",
-            array(
-                array(
-                    "version",
-                    new \StdClass(),
-                    "text",
-                    "2.0"
-                ),
-                array(
-                    "prodid",
-                    new \StdClass(),
-                    "text",
-                    "-//Sabre//Sabre VObject " . Version::VERSION . "//EN",
-                ),
-                array(
-                    "calscale",
-                    new \StdClass(),
-                    "text",
-                    "GREGORIAN"
-                ),
-            ),
-            array(
-                array("vevent",
-                    array(
-                        array(
-                            "uid", new \StdClass(), "text", "foo",
-                        ),
-                        array(
-                            "dtstart", new \StdClass(), "date", "2013-05-26",
-                        ),
-                        array(
-                            "duration", new \StdClass(), "duration", "P1D",
-                        ),
-                        array(
-                            "categories", new \StdClass(), "text", "home", "testing",
-                        ),
-                        array(
-                            "created", new \StdClass(), "date-time", "2013-05-26T18:10:00Z",
-                        ),
-
-                        array(
-                            "attendee", new \StdClass(), "cal-address", "mailto:armin@example.org",
-                        ),
-                        array(
-                            "geo", new \StdClass(), "float", array(51.96668, 7.61876),
-                        ),
-                        array(
-                            "sequence", new \StdClass(), "integer", 5
-                        ),
-                        array(
-                            "freebusy", new \StdClass(), "period",  array("2013-05-26T21:02:13", "PT1H"), array("2013-06-26T12:00:00", "2013-06-26T13:00:00"),
-                        ),
-                        array(
-                            "url", new \StdClass(), "uri", "http://example.org/",
-                        ),
-                        array(
-                            "tzoffsetfrom", new \StdClass(), "utc-offset", "+05:00",
-                        ),
-                        array(
-                            "rrule", new \StdClass(), "recur", array(
-                                'freq' => 'WEEKLY',
-                                'byday' => array('MO', 'TU'),
-                            ),
-                        ),
-                        array(
-                            "x-bool", new \StdClass(), "boolean", true
-                        ),
-                        array(
-                            "x-time", new \StdClass(), "time", "08:00:00",
-                        ),
-                        array(
-                            "attach", new \StdClass(), "binary", base64_encode('attachment')
-                        ),
-                        array(
-                            "attendee",
-                            (object)array(
-                                "cn" => "Dominik",
-                                "partstat" => "DECLINED",
-                            ),
-                            "cal-address",
-                            "mailto:dominik@example.org"
-                        ),
-                        array(
-                            "request-status",
-                            new \StdClass(),
-                            "text",
-                            array("2.0", "Success"),
-                        ),
-                        array(
-                            "request-status",
-                            new \StdClass(),
-                            "text",
-                            array("3.7", "Invalid Calendar User", "ATTENDEE:mailto:jsmith@example.org"),
-                        ),
-                        array(
-                            'dtend',
-                            new \StdClass(),
-                            "date-time",
-                            "2015-01-08T13:30:00",
-                        ),
-                    ),
-                    array(),
-                )
-            ),
-        );
-
-        $this->assertEquals($expected, $cal->jsonSerialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/JCardTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class JCardTest extends \PHPUnit_Framework_TestCase {
-
-    function testToJCard() {
-
-        $card = new Component\VCard(array(
-            "VERSION" => "4.0",
-            "UID" => "foo",
-            "BDAY" => "19850407",
-            "REV"  => "19951031T222710Z",
-            "LANG" => "nl",
-            "N" => array("Last", "First", "Middle", "", ""),
-            "item1.TEL" => "+1 555 123456",
-            "item1.X-AB-LABEL" => "Walkie Talkie",
-            "ADR" => array(
-                "",
-                "",
-                array("My Street", "Left Side", "Second Shack"),
-                "Hometown",
-                "PA",
-                "18252",
-                "U.S.A",
-            ),
-        ));
-
-        $card->add('BDAY', '1979-12-25', array('VALUE' => 'DATE', 'X-PARAM' => array(1,2)));
-        $card->add('BDAY', '1979-12-25T02:00:00', array('VALUE' => 'DATE-TIME'));
-
-
-        $card->add('X-TRUNCATED', '--1225', array('VALUE' => 'DATE'));
-        $card->add('X-TIME-LOCAL', '123000', array('VALUE' => 'TIME'));
-        $card->add('X-TIME-UTC', '12:30:00Z', array('VALUE' => 'TIME'));
-        $card->add('X-TIME-OFFSET', '12:30:00-08:00', array('VALUE' => 'TIME'));
-        $card->add('X-TIME-REDUCED', '23', array('VALUE' => 'TIME'));
-        $card->add('X-TIME-TRUNCATED', '--30', array('VALUE' => 'TIME'));
-
-        $card->add('X-KARMA-POINTS', '42', array('VALUE' => 'INTEGER'));
-        $card->add('X-GRADE', '1.3', array('VALUE' => 'FLOAT'));
-
-        $card->add('TZ', '-05:00', array('VALUE' => 'UTC-OFFSET'));
-
-        $expected = array(
-            "vcard",
-            array(
-                array(
-                    "version",
-                    new \StdClass(),
-                    "text",
-                    "4.0"
-                ),
-                array(
-                    "prodid",
-                    new \StdClass(),
-                    "text",
-                    "-//Sabre//Sabre VObject " . Version::VERSION . "//EN",
-                ),
-                array(
-                    "uid",
-                    new \StdClass(),
-                    "text",
-                    "foo",
-                ),
-                array(
-                    "bday",
-                    new \StdClass(),
-                    "date-and-or-time",
-                    "1985-04-07",
-                ),
-                array(
-                    "rev",
-                    new \StdClass(),
-                    "timestamp",
-                    "1995-10-31T22:27:10Z",
-                ),
-                array(
-                    "lang",
-                    new \StdClass(),
-                    "language-tag",
-                    "nl",
-                ),
-                array(
-                    "n",
-                    new \StdClass(),
-                    "text",
-                    array("Last", "First", "Middle", "", ""),
-                ),
-                array(
-                    "tel",
-                    (object)array(
-                        "group" => "item1",
-                    ),
-                    "text",
-                    "+1 555 123456",
-                ),
-                array(
-                    "x-ab-label",
-                    (object)array(
-                        "group" => "item1",
-                    ),
-                    "unknown",
-                    "Walkie Talkie",
-                ),
-                array(
-                    "adr",
-                    new \StdClass(),
-                    "text",
-                        array(
-                            "",
-                            "",
-                            array("My Street", "Left Side", "Second Shack"),
-                            "Hometown",
-                            "PA",
-                            "18252",
-                            "U.S.A",
-                        ),
-                ),
-                array(
-                    "bday",
-                    (object)array(
-                        'x-param' => array(1,2),
-                    ),
-                    "date",
-                    "1979-12-25",
-                ),
-                array(
-                    "bday",
-                    new \StdClass(),
-                    "date-time",
-                    "1979-12-25T02:00:00",
-                ),
-                array(
-                    "x-truncated",
-                    new \StdClass(),
-                    "date",
-                    "--12-25",
-                ),
-                array(
-                    "x-time-local",
-                    new \StdClass(),
-                    "time",
-                    "12:30:00"
-                ),
-                array(
-                    "x-time-utc",
-                    new \StdClass(),
-                    "time",
-                    "12:30:00Z"
-                ),
-                array(
-                    "x-time-offset",
-                    new \StdClass(),
-                    "time",
-                    "12:30:00-08:00"
-                ),
-                array(
-                    "x-time-reduced",
-                    new \StdClass(),
-                    "time",
-                    "23"
-                ),
-                array(
-                    "x-time-truncated",
-                    new \StdClass(),
-                    "time",
-                    "--30"
-                ),
-                array(
-                    "x-karma-points",
-                    new \StdClass(),
-                    "integer",
-                    42
-                ),
-                array(
-                    "x-grade",
-                    new \StdClass(),
-                    "float",
-                    1.3
-                ),
-                array(
-                    "tz",
-                    new \StdClass(),
-                    "utc-offset",
-                    "-05:00",
-                ),
-            ),
-        );
-
-        $this->assertEquals($expected, $card->jsonSerialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/LineFoldingIssueTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class LineFoldingIssueTest extends \PHPUnit_Framework_TestCase {
-
-    function testRead() {
-
-        $event = <<<ICS
-BEGIN:VCALENDAR\r
-BEGIN:VEVENT\r
-DESCRIPTION:TEST\\n\\n \\n\\nTEST\\n\\n \\n\\nTEST\\n\\n \\n\\nTEST\\n\\nTEST\\nTEST, TEST\r
-END:VEVENT\r
-END:VCALENDAR\r
-
-ICS;
-
-        $obj = Reader::read($event);
-        $this->assertEquals($event, $obj->serialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ParameterTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class ParameterTest extends \PHPUnit_Framework_TestCase {
-
-    function testSetup() {
-
-        $cal = new Component\VCalendar();
-
-        $param = new Parameter($cal, 'name','value');
-        $this->assertEquals('NAME',$param->name);
-        $this->assertEquals('value',$param->getValue());
-
-    }
-
-    function testSetupNameLess() {
-
-        $card = new Component\VCard();
-
-        $param = new Parameter($card, null,'URL');
-        $this->assertEquals('VALUE',$param->name);
-        $this->assertEquals('URL',$param->getValue());
-        $this->assertTrue($param->noName);
-
-    }
-
-    function testModify() {
-
-        $cal = new Component\VCalendar();
-
-        $param = new Parameter($cal, 'name', null);
-        $param->addValue(1);
-        $this->assertEquals(array(1), $param->getParts());
-
-        $param->setParts(array(1,2));
-        $this->assertEquals(array(1,2), $param->getParts());
-
-        $param->addValue(3);
-        $this->assertEquals(array(1,2,3), $param->getParts());
-
-        $param->setValue(4);
-        $param->addValue(5);
-        $this->assertEquals(array(4,5), $param->getParts());
-
-    }
-
-    function testCastToString() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name', 'value');
-        $this->assertEquals('value',$param->__toString());
-        $this->assertEquals('value',(string)$param);
-
-    }
-
-    function testCastNullToString() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name', null);
-        $this->assertEquals('',$param->__toString());
-        $this->assertEquals('',(string)$param);
-
-    }
-
-    function testSerialize() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name', 'value');
-        $this->assertEquals('NAME=value',$param->serialize());
-
-    }
-
-    function testSerializeEmpty() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name', null);
-        $this->assertEquals('NAME=',$param->serialize());
-
-    }
-
-    function testSerializeComplex() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name',array("val1", "val2;", "val3^", "val4\n", "val5\""));
-        $this->assertEquals('NAME=val1,"val2;","val3^^","val4^n","val5^\'"',$param->serialize());
-
-    }
-
-    /**
-     * iCal 7.0 (OSX 10.9) has major issues with the EMAIL property, when the
-     * value contains a plus sign, and it's not quoted.
-     *
-     * So we specifically added support for that.
-     */
-    function testSerializePlusSign() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'EMAIL',"user+something@example.org");
-        $this->assertEquals('EMAIL="user+something@example.org"',$param->serialize());
-
-    }
-
-    function testIterate() {
-
-        $cal = new Component\VCalendar();
-
-        $param = new Parameter($cal, 'name', array(1,2,3,4));
-        $result = array();
-
-        foreach($param as $value) {
-            $result[] = $value;
-        }
-
-        $this->assertEquals(array(1,2,3,4), $result);
-
-    }
-
-    function testSerializeColon() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name','va:lue');
-        $this->assertEquals('NAME="va:lue"',$param->serialize());
-
-    }
-
-    function testSerializeSemiColon() {
-
-        $cal = new Component\VCalendar();
-        $param = new Parameter($cal, 'name','va;lue');
-        $this->assertEquals('NAME="va;lue"',$param->serialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Parser/JsonTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Parser;
-
-use
-    Sabre\VObject;
-
-class JsonTest extends \PHPUnit_Framework_TestCase {
-
-    function testRoundTripJCard() {
-
-        $input = array(
-            "vcard",
-            array(
-                array(
-                    "version",
-                    new \StdClass(),
-                    "text",
-                    "4.0"
-                ),
-                array(
-                    "prodid",
-                    new \StdClass(),
-                    "text",
-                    "-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN",
-                ),
-                array(
-                    "uid",
-                    new \StdClass(),
-                    "text",
-                    "foo",
-                ),
-                array(
-                    "bday",
-                    new \StdClass(),
-                    "date-and-or-time",
-                    "1985-04-07",
-                ),
-                array(
-                    "rev",
-                    new \StdClass(),
-                    "timestamp",
-                    "1995-10-31T22:27:10Z",
-                ),
-                array(
-                    "lang",
-                    new \StdClass(),
-                    "language-tag",
-                    "nl",
-                ),
-                array(
-                    "n",
-                    new \StdClass(),
-                    "text",
-                    array("Last", "First", "Middle", "", ""),
-                ),
-                array(
-                    "tel",
-                    (object)array(
-                        "group" => "item1",
-                    ),
-                    "text",
-                    "+1 555 123456",
-                ),
-                array(
-                    "x-ab-label",
-                    (object)array(
-                        "group" => "item1",
-                    ),
-                    "unknown",
-                    "Walkie Talkie",
-                ),
-                array(
-                    "adr",
-                    new \StdClass(),
-                    "text",
-                        array(
-                            "",
-                            "",
-                            array("My Street", "Left Side", "Second Shack"),
-                            "Hometown",
-                            "PA",
-                            "18252",
-                            "U.S.A",
-                        ),
-                ),
-                array(
-                    "bday",
-                    (object)array(
-                        'x-param' => array(1,2),
-                    ),
-                    "date",
-                    "1979-12-25",
-                ),
-                array(
-                    "bday",
-                    new \StdClass(),
-                    "date-time",
-                    "1979-12-25T02:00:00",
-                ),
-                array(
-                    "x-truncated",
-                    new \StdClass(),
-                    "date",
-                    "--12-25",
-                ),
-                array(
-                    "x-time-local",
-                    new \StdClass(),
-                    "time",
-                    "12:30:00"
-                ),
-                array(
-                    "x-time-utc",
-                    new \StdClass(),
-                    "time",
-                    "12:30:00Z"
-                ),
-                array(
-                    "x-time-offset",
-                    new \StdClass(),
-                    "time",
-                    "12:30:00-08:00"
-                ),
-                array(
-                    "x-time-reduced",
-                    new \StdClass(),
-                    "time",
-                    "23"
-                ),
-                array(
-                    "x-time-truncated",
-                    new \StdClass(),
-                    "time",
-                    "--30"
-                ),
-                array(
-                    "x-karma-points",
-                    new \StdClass(),
-                    "integer",
-                    42
-                ),
-                array(
-                    "x-grade",
-                    new \StdClass(),
-                    "float",
-                    1.3
-                ),
-                array(
-                    "tz",
-                    new \StdClass(),
-                    "utc-offset",
-                    "-05:00",
-                ),
-            ),
-        );
-
-        $parser = new Json(json_encode($input));
-        $vobj = $parser->parse();        
-
-        $version = VObject\Version::VERSION;
-
-
-        $result = $vobj->serialize();
-        $expected = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-UID:foo
-BDAY:1985-04-07
-REV:1995-10-31T22:27:10Z
-LANG:nl
-N:Last;First;Middle;;
-item1.TEL:+1 555 123456
-item1.X-AB-LABEL:Walkie Talkie
-ADR:;;My Street,Left Side,Second Shack;Hometown;PA;18252;U.S.A
-BDAY;X-PARAM=1,2;VALUE=DATE:1979-12-25
-BDAY;VALUE=DATE-TIME:1979-12-25T02:00:00
-X-TRUNCATED;VALUE=DATE:--12-25
-X-TIME-LOCAL;VALUE=TIME:12:30:00
-X-TIME-UTC;VALUE=TIME:12:30:00Z
-X-TIME-OFFSET;VALUE=TIME:12:30:00-08:00
-X-TIME-REDUCED;VALUE=TIME:23
-X-TIME-TRUNCATED;VALUE=TIME:--30
-X-KARMA-POINTS;VALUE=INTEGER:42
-X-GRADE;VALUE=FLOAT:1.3
-TZ;VALUE=UTC-OFFSET:-05:00
-END:VCARD
-
-VCF;
-        $this->assertEquals($expected, str_replace("\r", "", $result));
-
-        $this->assertEquals(
-            $input,
-            $vobj->jsonSerialize()
-        );
-
-    }
-
-    function testRoundTripJCal() {
-
-        $input = array(
-            "vcalendar",
-            array(
-                array(
-                    "version",
-                    new \StdClass(),
-                    "text",
-                    "2.0"
-                ),
-                array(
-                    "prodid",
-                    new \StdClass(),
-                    "text",
-                    "-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN",
-                ),
-                array(
-                    "calscale",
-                    new \StdClass(),
-                    "text",
-                    "GREGORIAN"
-                ),
-            ),
-            array(
-                array("vevent",
-                    array(
-                        array(
-                            "uid", new \StdClass(), "text", "foo",
-                        ),
-                        array(
-                            "dtstart", new \StdClass(), "date", "2013-05-26",
-                        ),
-                        array(
-                            "duration", new \StdClass(), "duration", "P1D",
-                        ),
-                        array(
-                            "categories", new \StdClass(), "text", "home", "testing",
-                        ),
-                        array(
-                            "created", new \StdClass(), "date-time", "2013-05-26T18:10:00Z",
-                        ),
-                        array(
-                            "attach", new \StdClass(), "binary", base64_encode('attachment')
-                        ),
-                        array(
-                            "attendee", new \StdClass(), "cal-address", "mailto:armin@example.org",
-                        ),
-                        array(
-                            "geo", new \StdClass(), "float", array(51.96668, 7.61876),
-                        ),
-                        array(
-                            "sequence", new \StdClass(), "integer", 5
-                        ),
-                        array(
-                            "freebusy", new \StdClass(), "period",  array("2013-05-26T21:02:13", "PT1H"), array("2013-06-26T12:00:00", "2013-06-26T13:00:00"),
-                        ),
-                        array(
-                            "url", new \StdClass(), "uri", "http://example.org/",
-                        ),
-                        array(
-                            "tzoffsetfrom", new \StdClass(), "utc-offset", "+05:00",
-                        ),
-                        array(
-                            "rrule", new \StdClass(), "recur", array(
-                                'freq' => 'WEEKLY',
-                                'byday' => array('MO', 'TU'),
-                            ),
-                        ),
-                        array(
-                            "x-bool", new \StdClass(), "boolean", true
-                        ),
-                        array(
-                            "x-time", new \StdClass(), "time", "08:00:00",
-                        ),
-                        array(
-                            "attendee",
-                            (object)array(
-                                "cn" => "Dominik",
-                                "partstat" => "DECLINED",
-                            ),
-                            "cal-address",
-                            "mailto:dominik@example.org"
-                        ),
-                        array(
-                            "request-status",
-                            new \StdClass(),
-                            "text",
-                            array("2.0", "Success"),
-                        ),
-                        array(
-                            "request-status",
-                            new \StdClass(),
-                            "text",
-                            array("3.7", "Invalid Calendar User", "ATTENDEE:mailto:jsmith@example.org"),
-                        ),
-                    ),
-                    array(
-                        array("valarm",
-                            array(
-                                array(
-                                    "action", new \StdClass(), "text", "DISPLAY",
-                                ),
-                            ),
-                            array(),
-                        ),
-                    ),
-                )
-            ),
-        );
-
-        $parser = new Json(json_encode($input));
-        $vobj = $parser->parse();        
-        $result = $vobj->serialize();
-
-        $version = VObject\Version::VERSION;
-
-        $expected = <<<VCF
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-UID:foo
-DTSTART;VALUE=DATE:20130526
-DURATION:P1D
-CATEGORIES:home,testing
-CREATED:20130526T181000Z
-ATTACH;VALUE=BINARY:YXR0YWNobWVudA==
-ATTENDEE:mailto:armin@example.org
-GEO:51.96668;7.61876
-SEQUENCE:5
-FREEBUSY:20130526T210213/PT1H,20130626T120000/20130626T130000
-URL:http://example.org/
-TZOFFSETFROM:+05:00
-RRULE:FREQ=WEEKLY;BYDAY=MO,TU
-X-BOOL;VALUE=BOOLEAN:TRUE
-X-TIME;VALUE=TIME:08:00:00
-ATTENDEE;CN=Dominik;PARTSTAT=DECLINED:mailto:dominik@example.org
-REQUEST-STATUS:2.0;Success
-REQUEST-STATUS:3.7;Invalid Calendar User;ATTENDEE:mailto:jsmith@example.org
-BEGIN:VALARM
-ACTION:DISPLAY
-END:VALARM
-END:VEVENT
-END:VCALENDAR
-
-VCF;
-        $this->assertEquals($expected, str_replace("\r", "", $result));
-
-        $this->assertEquals(
-            $input,
-            $vobj->jsonSerialize()
-        );
-
-    }
-
-    function testParseStreamArg() {
-
-        $input = array(
-            "vcard",
-            array(
-                array(
-                    "FN", new \StdClass(), 'text', "foo",
-                ),
-            ),
-        );
-
-        $stream = fopen('php://memory','r+');
-        fwrite($stream, json_encode($input));
-        rewind($stream);
-
-        $result = VObject\Reader::readJson($stream,0);
-        $this->assertEquals('foo', $result->FN->getValue());
-
-    }
-
-    /**
-     * @expectedException \Sabre\VObject\ParseException
-     */
-    function testParseInvalidData() {
-
-        $json = new Json();
-        $input = array(
-            "vlist",
-            array(
-                array(
-                    "FN", new \StdClass(), 'text', "foo",
-                ),
-            ),
-        );
-
-        $json->parse(json_encode($input), 0);
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/Parser/MimeDirTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Parser;
-
-/**
- * Note that most MimeDir related tests can actually be found in the ReaderTest
- * class one level up.
- */
-class MimeDirTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @expectedException \Sabre\VObject\ParseException
-     */
-    function testParseError() {
-
-        $mimeDir = new MimeDir();
-        $mimeDir->parse(fopen(__FILE__,'a'));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Parser/QuotedPrintableTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Parser;
-
-use
-    Sabre\VObject\Reader;
-
-class QuotedPrintableTest extends \PHPUnit_Framework_TestCase {
-
-    function testReadQuotedPrintableSimple() {
-
-        $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aach=65n\r\nEND:VCARD";
-
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCARD', $result->name);
-        $this->assertEquals(1, count($result->children()));
-        $this->assertEquals("Aachen", $this->getPropertyValue($result->label));
-
-    }
-
-    function testReadQuotedPrintableNewlineSoft() {
-
-        $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aa=\r\n ch=\r\n en\r\nEND:VCARD";
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCARD', $result->name);
-        $this->assertEquals(1, count($result->children()));
-        $this->assertEquals("Aachen", $this->getPropertyValue($result->label));
-
-    }
-
-    function testReadQuotedPrintableNewlineHard() {
-
-        $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aachen=0D=0A=\r\n Germany\r\nEND:VCARD";
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCARD', $result->name);
-        $this->assertEquals(1, count($result->children()));
-        $this->assertEquals("Aachen\r\nGermany", $this->getPropertyValue($result->label));
-
-
-    }
-
-    function testReadQuotedPrintableCompatibilityMS() {
-
-        $data = "BEGIN:VCARD\r\nLABEL;ENCODING=QUOTED-PRINTABLE:Aachen=0D=0A=\r\nDeutschland:okay\r\nEND:VCARD";
-        $result = Reader::read($data, Reader::OPTION_FORGIVING);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCARD', $result->name);
-        $this->assertEquals(1, count($result->children()));
-        $this->assertEquals("Aachen\r\nDeutschland:okay", $this->getPropertyValue($result->label));
-
-    }
-
-    function testReadQuotesPrintableCompoundValues() {
-
-        $data = <<<VCF
-BEGIN:VCARD
-VERSION:2.1
-N:Doe;John;;;
-FN:John Doe
-ADR;WORK;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;;M=C3=BCnster =
-Str. 1;M=C3=BCnster;;48143;Deutschland
-END:VCARD
-VCF;
-
-        $result = Reader::read($data, Reader::OPTION_FORGIVING);
-        $this->assertEquals(array(
-            '','','Münster Str. 1','Münster','','48143','Deutschland'
-        ), $result->ADR->getParts());
-
-
-    }
-
-    private function getPropertyValue(\Sabre\VObject\Property $property) {
-
-        return (string)$property;
-
-        /*
-        $param = $property['encoding'];
-        if ($param !== null) {
-            $encoding = strtoupper((string)$param);
-            if ($encoding === 'QUOTED-PRINTABLE') {
-                $value = quoted_printable_decode($value);
-            } else {
-                throw new Exception();
-            }
-        }
-
-        $param = $property['charset'];
-        if ($param !== null) {
-            $charset = strtoupper((string)$param);
-            if ($charset !== 'UTF-8') {
-                $value = mb_convert_encoding($value, 'UTF-8', $charset);
-            }
-        } else {
-            $value = StringUtil::convertToUTF8($value);
-        }
-
-        return $value;
-         */
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/BinaryTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject;
-
-class BinaryTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    function testMimeDir() {
-
-        $vcard = new VObject\Component\VCard();
-        $vcard->add('PHOTO', array('a','b'));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/BooleanTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject;
-
-class BooleanTest extends \PHPUnit_Framework_TestCase {
-
-    function testMimeDir() {
-
-        $input = "BEGIN:VCARD\r\nX-AWESOME;VALUE=BOOLEAN:TRUE\r\nX-SUCKS;VALUE=BOOLEAN:FALSE\r\nEND:VCARD\r\n";
-
-        $vcard = VObject\Reader::read($input);
-        $this->assertTrue($vcard->{'X-AWESOME'}->getValue());
-        $this->assertFalse($vcard->{'X-SUCKS'}->getValue());
-
-        $this->assertEquals('BOOLEAN', $vcard->{'X-AWESOME'}->getValueType());
-        $this->assertEquals($input, $vcard->serialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/CompoundTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject\Component\VCard;
-
-class CompoundTest extends \PHPUnit_Framework_TestCase {
-
-    function testSetParts() {
-
-        $arr = array(
-            'ABC, Inc.',
-            'North American Division',
-            'Marketing;Sales',
-        );
-
-        $vcard = new VCard();
-        $elem = $vcard->createProperty('ORG');
-        $elem->setParts($arr);
-
-        $this->assertEquals('ABC\, Inc.;North American Division;Marketing\;Sales', $elem->getValue());
-        $this->assertEquals(3, count($elem->getParts()));
-        $parts = $elem->getParts();
-        $this->assertEquals('Marketing;Sales', $parts[2]);
-
-    }
-
-    function testGetParts() {
-
-        $str = 'ABC\, Inc.;North American Division;Marketing\;Sales';
-
-        $vcard = new VCard();
-        $elem = $vcard->createProperty('ORG');
-        $elem->setRawMimeDirValue($str);
-
-        $this->assertEquals(3, count($elem->getParts()));
-        $parts = $elem->getParts();
-        $this->assertEquals('Marketing;Sales', $parts[2]);
-    }
-
-    function testGetPartsNull() {
-
-        $vcard = new VCard();
-        $elem = $vcard->createProperty('ORG', null);
-
-        $this->assertEquals(0, count($elem->getParts()));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/FloatTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject;
-
-class FloatTest extends \PHPUnit_Framework_TestCase {
-
-    function testMimeDir() {
-
-        $input = "BEGIN:VCARD\r\nVERSION:4.0\r\nX-FLOAT;VALUE=FLOAT:0.234;1.245\r\nEND:VCARD\r\n";
-        $mimeDir = new VObject\Parser\MimeDir($input);
-
-        $result = $mimeDir->parse($input);
-
-        $this->assertInstanceOf('Sabre\VObject\Property\Float', $result->{'X-FLOAT'});
-
-        $this->assertEquals(array(
-            0.234,
-            1.245,
-        ), $result->{'X-FLOAT'}->getParts());
-
-        $this->assertEquals(
-            $input,
-            $result->serialize()
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/ICalendar/CalAddressTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-class CalAddressTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider values
-     */
-    function testGetNormalizedValue($expected, $input) {
-
-        $vobj = new \Sabre\VObject\Component\VCalendar();
-        $property = $vobj->add('ATTENDEE', $input);
-
-        $this->assertEquals(
-            $expected,
-            $property->getNormalizedValue()
-        );
-
-    }
-
-    function values() {
-
-        return array(
-            array('mailto:a@b.com', 'mailto:a@b.com'),
-            array('mailto:a@b.com', 'MAILTO:a@b.com'),
-            array('/foo/bar', '/foo/bar'),
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/ICalendar/DateTimeTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,359 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use Sabre\VObject\Component;
-use Sabre\VObject\Component\VCalendar;
-
-
-class DateTimeTest extends \PHPUnit_Framework_TestCase {
-
-    protected $vcal;
-
-    function setUp() {
-
-        $this->vcal = new VCalendar();
-
-    }
-
-    function testSetDateTime() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setDateTime($dt);
-
-        $this->assertEquals('19850704T013000', (string)$elem);
-        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
-        $this->assertNull($elem['VALUE']);
-
-        $this->assertTrue($elem->hasTime());
-
-    }
-
-    function testSetDateTimeLOCAL() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setDateTime($dt, $isFloating = true);
-
-        $this->assertEquals('19850704T013000', (string)$elem);
-        $this->assertNull($elem['TZID']);
-
-        $this->assertTrue($elem->hasTime());
-    }
-
-    function testSetDateTimeUTC() {
-
-        $tz = new \DateTimeZone('GMT');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setDateTime($dt);
-
-        $this->assertEquals('19850704T013000Z', (string)$elem);
-        $this->assertNull($elem['TZID']);
-
-        $this->assertTrue($elem->hasTime());
-    }
-
-    function testSetDateTimeLOCALTZ() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setDateTime($dt);
-
-        $this->assertEquals('19850704T013000', (string)$elem);
-        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
-
-        $this->assertTrue($elem->hasTime());
-    }
-
-    function testSetDateTimeDATE() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem['VALUE'] = 'DATE';
-        $elem->setDateTime($dt);
-
-        $this->assertEquals('19850704', (string)$elem);
-        $this->assertNull($elem['TZID']);
-        $this->assertEquals('DATE', (string)$elem['VALUE']);
-
-        $this->assertFalse($elem->hasTime());
-    }
-
-    function testSetValue() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setValue($dt);
-
-        $this->assertEquals('19850704T013000', (string)$elem);
-        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
-        $this->assertNull($elem['VALUE']);
-
-        $this->assertTrue($elem->hasTime());
-
-    }
-
-    function testSetValueArray() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt1 = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt2 = new \DateTime('1985-07-04 02:30:00', $tz);
-        $dt1->setTimeZone($tz);
-        $dt2->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setValue(array($dt1, $dt2));
-
-        $this->assertEquals('19850704T013000,19850704T023000', (string)$elem);
-        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
-        $this->assertNull($elem['VALUE']);
-
-        $this->assertTrue($elem->hasTime());
-
-    }
-
-    function testSetParts() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt1 = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt2 = new \DateTime('1985-07-04 02:30:00', $tz);
-        $dt1->setTimeZone($tz);
-        $dt2->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setParts(array($dt1, $dt2));
-
-        $this->assertEquals('19850704T013000,19850704T023000', (string)$elem);
-        $this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
-        $this->assertNull($elem['VALUE']);
-
-        $this->assertTrue($elem->hasTime());
-
-    }
-    function testSetPartsStrings() {
-
-        $dt1 = '19850704T013000Z';
-        $dt2 = '19850704T023000Z';
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setParts(array($dt1, $dt2));
-
-        $this->assertEquals('19850704T013000Z,19850704T023000Z', (string)$elem);
-        $this->assertNull($elem['VALUE']);
-
-        $this->assertTrue($elem->hasTime());
-
-    }
-
-
-    function testGetDateTimeCached() {
-
-        $tz = new \DateTimeZone('Europe/Amsterdam');
-        $dt = new \DateTime('1985-07-04 01:30:00', $tz);
-        $dt->setTimeZone($tz);
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $elem->setDateTime($dt);
-
-        $this->assertEquals($elem->getDateTime(), $dt);
-
-    }
-
-    function testGetDateTimeDateNULL() {
-
-        $elem = $this->vcal->createProperty('DTSTART');
-        $dt = $elem->getDateTime();
-
-        $this->assertNull($dt);
-
-    }
-
-    function testGetDateTimeDateDATE() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704');
-        $dt = $elem->getDateTime();
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 00:00:00', $dt->format('Y-m-d H:i:s'));
-
-    }
-
-    function testGetDateTimeDateDATEReferenceTimeZone() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704');
-
-        $tz = new \DateTimeZone('America/Toronto');
-        $dt = $elem->getDateTime($tz);
-        $dt->setTimeZone(new \DateTimeZone('UTC'));
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 04:00:00', $dt->format('Y-m-d H:i:s'));
-
-    }
-
-    function testGetDateTimeDateFloating() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
-        $dt = $elem->getDateTime();
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
-
-    }
-
-    function testGetDateTimeDateFloatingReferenceTimeZone() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
-
-        $tz = new \DateTimeZone('America/Toronto');
-        $dt = $elem->getDateTime($tz);
-        $dt->setTimeZone(new \DateTimeZone('UTC'));
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 05:30:00', $dt->format('Y-m-d H:i:s'));
-
-    }
-
-    function testGetDateTimeDateUTC() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704T013000Z');
-        $dt = $elem->getDateTime();
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
-        $this->assertEquals('UTC', $dt->getTimeZone()->getName());
-
-    }
-
-    function testGetDateTimeDateLOCALTZ() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
-        $elem['TZID'] = 'Europe/Amsterdam';
-
-        $dt = $elem->getDateTime();
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
-        $this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
-
-    }
-
-    /**
-     * @expectedException LogicException
-     */
-    function testGetDateTimeDateInvalid() {
-
-        $elem = $this->vcal->createProperty('DTSTART','bla');
-        $dt = $elem->getDateTime();
-
-    }
-
-    function testGetDateTimeWeirdTZ() {
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
-        $elem['TZID'] = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
-
-
-        $event = $this->vcal->createComponent('VEVENT');
-        $event->add($elem);
-
-        $timezone = $this->vcal->createComponent('VTIMEZONE');
-        $timezone->TZID = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
-        $timezone->{'X-LIC-LOCATION'} = 'Europe/Amsterdam';
-
-        $this->vcal->add($event);
-        $this->vcal->add($timezone);
-
-        $dt = $elem->getDateTime();
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
-        $this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
-
-    }
-
-    function testGetDateTimeBadTimeZone() {
-
-        $default = date_default_timezone_get();
-        date_default_timezone_set('Canada/Eastern');
-
-        $elem = $this->vcal->createProperty('DTSTART','19850704T013000');
-        $elem['TZID'] = 'Moon';
-
-
-        $event = $this->vcal->createComponent('VEVENT');
-        $event->add($elem);
-
-        $timezone = $this->vcal->createComponent('VTIMEZONE');
-        $timezone->TZID = 'Moon';
-        $timezone->{'X-LIC-LOCATION'} = 'Moon';
-
-
-        $this->vcal->add($event);
-        $this->vcal->add($timezone);
-
-        $dt = $elem->getDateTime();
-
-        $this->assertInstanceOf('DateTime', $dt);
-        $this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
-        $this->assertEquals('Canada/Eastern', $dt->getTimeZone()->getName());
-        date_default_timezone_set($default);
-
-    }
-
-    function testUpdateValueParameter() {
-
-        $dtStart = $this->vcal->createProperty('DTSTART', new \DateTime('2013-06-07 15:05:00'));
-        $dtStart['VALUE'] = 'DATE';
-
-        $this->assertEquals("DTSTART;VALUE=DATE:20130607\r\n", $dtStart->serialize());
-
-    }
-
-    function testValidate() {
-
-        $exDate = $this->vcal->createProperty('EXDATE', '-00011130T143000Z');
-        $messages = $exDate->validate();
-        $this->assertEquals(1, count($messages));
-        $this->assertEquals(3, $messages[0]['level']);
-
-    }
-
-    /**
-     * This issue was discovered on the sabredav mailing list.
-     */
-    function testCreateDatePropertyThroughAdd() {
-
-        $vcal = new VCalendar();
-        $vevent = $vcal->add('VEVENT');
-
-        $dtstart = $vevent->add(
-            'DTSTART',
-            new \DateTime('2014-03-07'),
-            array('VALUE' => 'DATE')
-        );
-
-        $this->assertEquals("DTSTART;VALUE=DATE:20140307\r\n", $dtstart->serialize());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/ICalendar/DurationTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use Sabre\VObject\Component\VCalendar;
-use Sabre\VObject\Component\VEvent;
-
-class DurationTest extends \PHPUnit_Framework_TestCase {
-
-    function testGetDateInterval() {
-
-        $vcal = new VCalendar();
-        $event = $vcal->add('VEVENT', array('DURATION' => array('PT1H')));
-
-        $this->assertEquals(
-            new \DateInterval('PT1H'),
-            $event->{'DURATION'}->getDateInterval()
-        );
-    }
-} 
--- a/vendor/sabre/vobject/tests/VObject/Property/ICalendar/RecurTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\ICalendar;
-
-use Sabre\VObject\Component\VCalendar;
-
-class RecurTest extends \PHPUnit_Framework_TestCase {
-
-    function testParts() {
-
-        $vcal = new VCalendar();
-        $recur = $vcal->add('RRULE', 'FREQ=Daily');
-
-        $this->assertInstanceOf('Sabre\VObject\Property\ICalendar\Recur', $recur);
-
-        $this->assertEquals(array('FREQ'=>'DAILY'), $recur->getParts());
-        $recur->setParts(array('freq'=>'MONTHLY'));
-
-        $this->assertEquals(array('FREQ'=>'MONTHLY'), $recur->getParts());
-
-    }
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    function testSetValueBadVal() {
-
-        $vcal = new VCalendar();
-        $recur = $vcal->add('RRULE', 'FREQ=Daily');
-        $recur->setValue(new \Exception());
-
-    }
-
-    function testSetSubParts() {
-
-        $vcal = new VCalendar();
-        $recur = $vcal->add('RRULE', array('FREQ'=>'DAILY', 'BYDAY'=>'mo,tu', 'BYMONTH' => array(0,1)));
-
-        $this->assertEquals(array(
-            'FREQ'=>'DAILY',
-            'BYDAY' => array('MO','TU'),
-            'BYMONTH' => array(0,1),
-        ), $recur->getParts());
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/TextTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property;
-
-use Sabre\VObject\Component\VCard;
-
-class TextTest extends \PHPUnit_Framework_TestCase {
-
-    function assertVCard21serialization($propValue, $expected) {
-
-        $doc = new VCard(array(
-            'VERSION'=>'2.1',
-            'PROP' => $propValue
-        ), false);
-
-        // Adding quoted-printable, because we're testing if it gets removed
-        // automatically.
-        $doc->PROP['ENCODING'] = 'QUOTED-PRINTABLE';
-        $doc->PROP['P1'] = 'V1';
-
-
-        $output = $doc->serialize();
-
-
-        $this->assertEquals("BEGIN:VCARD\r\nVERSION:2.1\r\n$expected\r\nEND:VCARD\r\n", $output);
-
-    }
-
-    function testSerializeVCard21() {
-
-        $this->assertVCard21Serialization(
-            'f;oo',
-            'PROP;P1=V1:f;oo'
-        );
-
-    }
-
-    function testSerializeVCard21Array() {
-
-        $this->assertVCard21Serialization(
-            array('f;oo','bar'),
-            'PROP;P1=V1:f\;oo;bar'
-        );
-
-    }
-    function testSerializeVCard21Fold() {
-
-        $this->assertVCard21Serialization(
-            str_repeat('x',80),
-            'PROP;P1=V1:' . str_repeat('x',64) . "\r\n " . str_repeat('x',16)
-        );
-
-    }
-
-
-
-    function testSerializeQuotedPrintable() {
-
-        $this->assertVCard21Serialization(
-            "foo\r\nbar",
-            'PROP;P1=V1;ENCODING=QUOTED-PRINTABLE:foo=0D=0Abar'
-        );
-    }
-
-    function testSerializeQuotedPrintableFold() {
-
-        $this->assertVCard21Serialization(
-            "foo\r\nbarxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
-            "PROP;P1=V1;ENCODING=QUOTED-PRINTABLE:foo=0D=0Abarxxxxxxxxxxxxxxxxxxxxxxxxxx=\r\n xxx"
-        );
-
-    }
-
-    function testValidateMinimumPropValue() {
-
-        $vcard = <<<IN
-BEGIN:VCARD
-VERSION:4.0
-UID:foo
-FN:Hi!
-N:A
-END:VCARD
-IN;
-
-        $vcard = \Sabre\VObject\Reader::read($vcard);
-        $this->assertEquals(1, count($vcard->validate()));
-
-        $this->assertEquals(1, count($vcard->N->getParts()));
-
-        $vcard->validate(\Sabre\VObject\Node::REPAIR);
-
-        $this->assertEquals(5, count($vcard->N->getParts()));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Property/VCard/DateAndOrTimeTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use
-    Sabre\VObject,
-    Sabre\VObject\Reader;
-
-class DateAndOrTimeTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @dataProvider dates
-     */
-    function testGetJsonValue($input, $output) {
-
-        $vcard = new VObject\Component\VCard();
-        $prop = $vcard->createProperty('BDAY', $input);
-
-        $this->assertEquals(array($output), $prop->getJsonValue());
-
-    }
-
-    function dates() {
-
-        return array(
-            array(
-                "19961022T140000",
-                "1996-10-22T14:00:00",
-            ),
-            array(
-                "--1022T1400",
-                "--10-22T14:00",
-            ),
-            array(
-                "---22T14",
-                "---22T14",
-            ),
-            array(
-                "19850412",
-                "1985-04-12",
-            ),
-            array(
-                "1985-04",
-                "1985-04",
-            ),
-            array(
-                "1985",
-                "1985",
-            ),
-            array(
-                "--0412",
-                "--04-12",
-            ),
-            array(
-                "T102200",
-                "T10:22:00",
-            ),
-            array(
-                "T1022",
-                "T10:22",
-            ),
-            array(
-                "T10",
-                "T10",
-            ),
-            array(
-                "T-2200",
-                "T-22:00",
-            ),
-            array(
-                "T102200Z",
-                "T10:22:00Z",
-            ),
-            array(
-                "T102200-0800",
-                "T10:22:00-0800",
-            ),
-            array(
-                "T--00",
-                "T--00",
-            ),
-        );
-
-    }
-
-    public function testSetParts() {
-
-        $vcard = new VObject\Component\VCard();
-
-        $prop = $vcard->createProperty('BDAY');
-        $prop->setParts(array(
-            new \DateTime('2014-04-02 18:37:00')
-        ));
-
-        $this->assertEquals('20140402T183700Z', $prop->getValue());
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    public function testSetPartsTooMany() {
-
-        $vcard = new VObject\Component\VCard();
-
-        $prop = $vcard->createProperty('BDAY');
-        $prop->setParts(array(
-            1,
-            2
-        ));
-
-    }
-
-    public function testSetPartsString() {
-
-        $vcard = new VObject\Component\VCard();
-
-        $prop = $vcard->createProperty('BDAY');
-        $prop->setParts(array(
-            "20140402T183700Z"
-        ));
-
-        $this->assertEquals('20140402T183700Z', $prop->getValue());
-
-    }
-
-    public function testSetValueDateTime() {
-
-        $vcard = new VObject\Component\VCard();
-
-        $prop = $vcard->createProperty('BDAY');
-        $prop->setValue(
-            new \DateTime('2014-04-02 18:37:00')
-        );
-
-        $this->assertEquals('20140402T183700Z', $prop->getValue());
-
-    }
-
-    public function testSetDateTimeOffset() {
-
-        $vcard = new VObject\Component\VCard();
-
-        $prop = $vcard->createProperty('BDAY');
-        $prop->setValue(
-            new \DateTime('2014-04-02 18:37:00', new \DateTimeZone('America/Toronto'))
-        );
-
-        $this->assertEquals('20140402T183700-0400', $prop->getValue());
-
-    }
-
-    public function testGetDateTime() {
-
-        $datetime = new \DateTime('2014-04-02 18:37:00', new \DateTimeZone('America/Toronto'));
-
-        $vcard = new VObject\Component\VCard();
-        $prop = $vcard->createProperty('BDAY', $datetime);
-
-        $dt = $prop->getDateTime();
-        $this->assertEquals('2014-04-02T18:37:00-04:00', $dt->format('c'), "For some reason this one failed. Current default timezone is: " . date_default_timezone_get());
-
-    }
-
-    public function testGetDateIncomplete() {
-
-        $datetime = '--0407';
-
-        $vcard = new VObject\Component\VCard();
-        $prop = $vcard->add('BDAY', $datetime);
-
-        $dt = $prop->getDateTime();
-        // Note: if the year changes between the last line and the next line of
-        // code, this test may fail.
-        //
-        // If that happens, head outside and have a drink.
-        $current = new \DateTime('now');
-        $year = $current->format('Y');
-
-        $this->assertEquals($year . '0407', $dt->format('Ymd'));
-
-    }
-
-    public function testGetDateIncompleteFromVCard() {
-
-        $vcard = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-BDAY:--0407
-END:VCARD
-VCF;
-        $vcard = Reader::read($vcard);
-        $prop = $vcard->BDAY;
-
-        $dt = $prop->getDateTime();
-        // Note: if the year changes between the last line and the next line of
-        // code, this test may fail.
-        //
-        // If that happens, head outside and have a drink.
-        $current = new \DateTime('now');
-        $year = $current->format('Y');
-
-        $this->assertEquals($year . '0407', $dt->format('Ymd'));
-
-    }
-
-    public function testValidate() {
-
-        $datetime = '--0407';
-
-        $vcard = new VObject\Component\VCard();
-        $prop = $vcard->add('BDAY', $datetime);
-
-        $this->assertEquals(array(), $prop->validate());
-
-    }
-
-    public function testValidateBroken() {
-
-        $datetime = '123';
-
-        $vcard = new VObject\Component\VCard();
-        $prop = $vcard->add('BDAY', $datetime);
-
-        $this->assertEquals(array(array(
-            'level' => 3,
-            'message' => 'The supplied value (123) is not a correct DATE-AND-OR-TIME property',
-            'node' => $prop,
-        )), $prop->validate());
-
-    }
-}
-
--- a/vendor/sabre/vobject/tests/VObject/Property/VCard/LanguageTagTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Property\VCard;
-
-use Sabre\VObject;
-
-class LanguageTagTest extends \PHPUnit_Framework_TestCase {
-
-    function testMimeDir() {
-
-        $input = "BEGIN:VCARD\r\nVERSION:4.0\r\nLANG:nl\r\nEND:VCARD\r\n";
-        $mimeDir = new VObject\Parser\MimeDir($input);
-
-        $result = $mimeDir->parse($input);
-
-        $this->assertInstanceOf('Sabre\VObject\Property\VCard\LanguageTag', $result->LANG);
-
-        $this->assertEquals('nl', $result->LANG->getValue());
-
-        $this->assertEquals(
-            $input,
-            $result->serialize()
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/PropertyTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    Sabre\VObject\Component\VCalendar;
-
-class PropertyTest extends \PHPUnit_Framework_TestCase {
-
-    public function testToString() {
-
-        $cal = new VCalendar();
-
-        $property = $cal->createProperty('propname','propvalue');
-        $this->assertEquals('PROPNAME', $property->name);
-        $this->assertEquals('propvalue', $property->__toString());
-        $this->assertEquals('propvalue', (string)$property);
-        $this->assertEquals('propvalue', $property->getValue());
-
-    }
-
-    public function testCreate() {
-
-        $cal = new VCalendar();
-
-        $params = array(
-            'param1' => 'value1',
-            'param2' => 'value2',
-        );
-
-        $property = $cal->createProperty('propname','propvalue', $params);
-
-        $this->assertEquals('value1', $property['param1']->getValue());
-        $this->assertEquals('value2', $property['param2']->getValue());
-
-    }
-
-    public function testSetValue() {
-
-        $cal = new VCalendar();
-
-        $property = $cal->createProperty('propname','propvalue');
-        $property->setValue('value2');
-
-        $this->assertEquals('PROPNAME', $property->name);
-        $this->assertEquals('value2', $property->__toString());
-
-    }
-
-    public function testParameterExists() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $property['paramname'] = 'paramvalue';
-
-        $this->assertTrue(isset($property['PARAMNAME']));
-        $this->assertTrue(isset($property['paramname']));
-        $this->assertFalse(isset($property['foo']));
-
-    }
-
-    public function testParameterGet() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $property['paramname'] = 'paramvalue';
-
-        $this->assertInstanceOf('Sabre\\VObject\\Parameter',$property['paramname']);
-
-    }
-
-    public function testParameterNotExists() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $property['paramname'] = 'paramvalue';
-
-        $this->assertInternalType('null',$property['foo']);
-
-    }
-
-    public function testParameterMultiple() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $property['paramname'] = 'paramvalue';
-        $property->add('paramname', 'paramvalue');
-
-        $this->assertInstanceOf('Sabre\\VObject\\Parameter',$property['paramname']);
-        $this->assertEquals(2,count($property['paramname']->getParts()));
-
-    }
-
-    public function testSetParameterAsString() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $property['paramname'] = 'paramvalue';
-
-        $this->assertEquals(1,count($property->parameters()));
-        $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property->parameters['PARAMNAME']);
-        $this->assertEquals('PARAMNAME',$property->parameters['PARAMNAME']->name);
-        $this->assertEquals('paramvalue',$property->parameters['PARAMNAME']->getValue());
-
-    }
-
-    public function testUnsetParameter() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $property['paramname'] = 'paramvalue';
-
-        unset($property['PARAMNAME']);
-        $this->assertEquals(0,count($property->parameters()));
-
-    }
-
-    public function testSerialize() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-
-        $this->assertEquals("PROPNAME:propvalue\r\n",$property->serialize());
-
-    }
-
-    public function testSerializeParam() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue', array(
-            'paramname' => 'paramvalue',
-            'paramname2' => 'paramvalue2',
-        ));
-
-        $this->assertEquals("PROPNAME;PARAMNAME=paramvalue;PARAMNAME2=paramvalue2:propvalue\r\n",$property->serialize());
-
-    }
-
-    public function testSerializeNewLine() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('SUMMARY',"line1\nline2");
-
-        $this->assertEquals("SUMMARY:line1\\nline2\r\n",$property->serialize());
-
-    }
-
-    public function testSerializeLongLine() {
-
-        $cal = new VCalendar();
-        $value = str_repeat('!',200);
-        $property = $cal->createProperty('propname',$value);
-
-        $expected = "PROPNAME:" . str_repeat('!',66) . "\r\n " . str_repeat('!',74) . "\r\n " . str_repeat('!',60) . "\r\n";
-
-        $this->assertEquals($expected,$property->serialize());
-
-    }
-
-    public function testSerializeUTF8LineFold() {
-
-        $cal = new VCalendar();
-        $value = str_repeat('!',65) . "\xc3\xa4bla"; // inserted umlaut-a
-        $property = $cal->createProperty('propname', $value);
-        $expected = "PROPNAME:" . str_repeat('!',65) . "\r\n \xc3\xa4bla\r\n";
-        $this->assertEquals($expected, $property->serialize());
-
-    }
-
-    public function testGetIterator() {
-
-        $cal = new VCalendar();
-        $it = new ElementList(array());
-        $property = $cal->createProperty('propname','propvalue');
-        $property->setIterator($it);
-        $this->assertEquals($it,$property->getIterator());
-
-    }
-
-
-    public function testGetIteratorDefault() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('propname','propvalue');
-        $it = $property->getIterator();
-        $this->assertTrue($it instanceof ElementList);
-        $this->assertEquals(1,count($it));
-
-    }
-
-    function testAddScalar() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('EMAIL');
-
-        $property->add('myparam','value');
-
-        $this->assertEquals(1, count($property->parameters()));
-
-        $this->assertTrue($property->parameters['MYPARAM'] instanceof Parameter);
-        $this->assertEquals('MYPARAM',$property->parameters['MYPARAM']->name);
-        $this->assertEquals('value',$property->parameters['MYPARAM']->getValue());
-
-    }
-
-    function testAddParameter() {
-
-        $cal = new VCalendar();
-        $prop = $cal->createProperty('EMAIL');
-
-        $prop->add('MYPARAM','value');
-
-        $this->assertEquals(1, count($prop->parameters()));
-        $this->assertEquals('MYPARAM',$prop['myparam']->name);
-
-    }
-
-    function testAddParameterTwice() {
-
-        $cal = new VCalendar();
-        $prop = $cal->createProperty('EMAIL');
-
-        $prop->add('MYPARAM', 'value1');
-        $prop->add('MYPARAM', 'value2');
-
-        $this->assertEquals(1, count($prop->parameters));
-        $this->assertEquals(2, count($prop->parameters['MYPARAM']->getParts()));
-
-        $this->assertEquals('MYPARAM',$prop['MYPARAM']->name);
-
-    }
-
-
-    function testClone() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('EMAIL','value');
-        $property['FOO'] = 'BAR';
-
-        $property2 = clone $property;
-
-        $property['FOO'] = 'BAZ';
-        $this->assertEquals('BAR', (string)$property2['FOO']);
-
-    }
-
-    function testCreateParams() {
-
-        $cal = new VCalendar();
-        $property = $cal->createProperty('X-PROP','value', array(
-            'param1' => 'value1',
-            'param2' => array('value2', 'value3')
-        ));
-
-        $this->assertEquals(1, count($property['PARAM1']->getParts()));
-        $this->assertEquals(2, count($property['PARAM2']->getParts()));
-
-    }
-
-    function testValidateNonUTF8() {
-
-        $calendar = new VCalendar();
-        $property = $calendar->createProperty('X-PROP', "Bla\x00");
-        $result = $property->validate(Property::REPAIR);
-
-        $this->assertEquals('Property contained a control character (0x00)', $result[0]['message']);
-        $this->assertEquals('Bla', $property->getValue());
-
-    }
-
-    function testValidateControlChars() {
-
-        $s = "chars[";
-        foreach (array(
-            0x7F, 0x5E, 0x5C, 0x3B, 0x3A, 0x2C, 0x22, 0x20,
-            0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-            0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-            0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-            0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-          ) as $c) {
-            $s .= sprintf('%02X(%c)', $c, $c);
-        }
-        $s .= "]end";
-
-        $calendar = new VCalendar();
-        $property = $calendar->createProperty('X-PROP', $s);
-        $result = $property->validate(Property::REPAIR);
-
-        $this->assertEquals('Property contained a control character (0x7f)', $result[0]['message']);
-        $this->assertEquals("chars[7F()5E(^)5C(\\\\)3B(\\;)3A(:)2C(\\,)22(\")20( )1F()1E()1D()1C()1B()1A()19()18()17()16()15()14()13()12()11()10()0F()0E()0D()0C()0B()0A(\\n)09(	)08()07()06()05()04()03()02()01()00()]end", $property->getRawMimeDirValue());
-
-    }
-
-
-    function testValidateBadPropertyName() {
-
-        $calendar = new VCalendar();
-        $property = $calendar->createProperty("X_*&PROP*", "Bla");
-        $result = $property->validate(Property::REPAIR);
-
-        $this->assertEquals($result[0]['message'], 'The propertyname: X_*&PROP* contains invalid characters. Only A-Z, 0-9 and - are allowed');
-        $this->assertEquals('X-PROP', $property->name);
-
-    }
-
-    function testGetValue() {
-
-        $calendar = new VCalendar();
-        $property = $calendar->createProperty("SUMMARY", null);
-        $this->assertEquals(array(), $property->getParts());
-        $this->assertNull($property->getValue());
-
-        $property->setValue(array());
-        $this->assertEquals(array(), $property->getParts());
-        $this->assertNull($property->getValue());
-
-        $property->setValue(array(1));
-        $this->assertEquals(array(1), $property->getParts());
-        $this->assertEquals(1, $property->getValue());
-
-        $property->setValue(array(1,2));
-        $this->assertEquals(array(1,2), $property->getParts());
-        $this->assertEquals('1,2', $property->getValue());
-
-        $property->setValue('str');
-        $this->assertEquals(array('str'), $property->getParts());
-        $this->assertEquals('str', $property->getValue());
-    }
-
-    /**
-     * ElementList should reject this.
-     *
-     * @expectedException \LogicException
-     */
-    public function testArrayAccessSetInt() {
-
-        $calendar = new VCalendar();
-        $property = $calendar->createProperty("X-PROP", null);
-
-        $calendar->add($property);
-        $calendar->{'X-PROP'}[0] = 'Something!';
-
-    }
-
-    /**
-     * ElementList should reject this.
-     *
-     * @expectedException \LogicException
-     */
-    public function testArrayAccessUnsetInt() {
-
-        $calendar = new VCalendar();
-        $property = $calendar->createProperty("X-PROP", null);
-
-        $calendar->add($property);
-        unset($calendar->{'X-PROP'}[0]);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/ReaderTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,449 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class ReaderTest extends \PHPUnit_Framework_TestCase {
-
-    function testReadComponent() {
-
-        $data = "BEGIN:VCALENDAR\r\nEND:VCALENDAR";
-
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(0, count($result->children));
-
-    }
-    function testReadStream() {
-
-        $data = "BEGIN:VCALENDAR\r\nEND:VCALENDAR";
-
-        $stream = fopen('php://memory', 'r+');
-        fwrite($stream, $data);
-        rewind($stream);
-
-        $result = Reader::read($stream);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(0, count($result->children));
-
-    }
-
-    function testReadComponentUnixNewLine() {
-
-        $data = "BEGIN:VCALENDAR\nEND:VCALENDAR";
-
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(0, count($result->children));
-
-    }
-
-    function testReadComponentLineFold() {
-
-        $data = "BEGIN:\r\n\tVCALENDAR\r\nE\r\n ND:VCALENDAR";
-
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(0, count($result->children));
-
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ParseException
-     */
-    function testReadCorruptComponent() {
-
-        $data = "BEGIN:VCALENDAR\r\nEND:FOO";
-
-        $result = Reader::read($data);
-
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ParseException
-     */
-    function testReadCorruptSubComponent() {
-
-        $data = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:FOO\r\nEND:VCALENDAR";
-
-        $result = Reader::read($data);
-
-    }
-
-    function testReadProperty() {
-
-        $data = "BEGIN:VCALENDAR\r\nSUMMARY:propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->SUMMARY;
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('SUMMARY', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-
-    }
-
-    function testReadPropertyWithNewLine() {
-
-        $data = "BEGIN:VCALENDAR\r\nSUMMARY:Line1\\nLine2\\NLine3\\\\Not the 4th line!\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->SUMMARY;
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('SUMMARY', $result->name);
-        $this->assertEquals("Line1\nLine2\nLine3\\Not the 4th line!", $result->getValue());
-
-    }
-
-    function testReadMappedProperty() {
-
-        $data = "BEGIN:VCALENDAR\r\nDTSTART:20110529\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->DTSTART;
-        $this->assertInstanceOf('Sabre\\VObject\\Property\\ICalendar\\DateTime', $result);
-        $this->assertEquals('DTSTART', $result->name);
-        $this->assertEquals('20110529', $result->getValue());
-
-    }
-
-    function testReadMappedPropertyGrouped() {
-
-        $data = "BEGIN:VCALENDAR\r\nfoo.DTSTART:20110529\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->DTSTART;
-        $this->assertInstanceOf('Sabre\\VObject\\Property\\ICalendar\\DateTime', $result);
-        $this->assertEquals('DTSTART', $result->name);
-        $this->assertEquals('20110529', $result->getValue());
-
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ParseException
-     */
-    function testReadBrokenLine() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;propValue";
-        $result = Reader::read($data);
-
-    }
-
-    function testReadPropertyInComponent() {
-
-        $data = array(
-            "BEGIN:VCALENDAR",
-            "PROPNAME:propValue",
-            "END:VCALENDAR"
-        );
-
-        $result = Reader::read(implode("\r\n",$data));
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(1, count($result->children()));
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result->children[0]);
-        $this->assertEquals('PROPNAME', $result->children[0]->name);
-        $this->assertEquals('propValue', $result->children[0]->getValue());
-
-    }
-
-    function testReadNestedComponent() {
-
-        $data = array(
-            "BEGIN:VCALENDAR",
-            "BEGIN:VTIMEZONE",
-            "BEGIN:DAYLIGHT",
-            "END:DAYLIGHT",
-            "END:VTIMEZONE",
-            "END:VCALENDAR"
-        );
-
-        $result = Reader::read(implode("\r\n",$data));
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(1, count($result->children()));
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result->children[0]);
-        $this->assertEquals('VTIMEZONE', $result->children[0]->name);
-        $this->assertEquals(1, count($result->children[0]->children()));
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result->children[0]->children[0]);
-        $this->assertEquals('DAYLIGHT', $result->children[0]->children[0]->name);
-
-
-    }
-
-    function testReadPropertyParameter() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PARAMNAME=paramvalue:propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('PARAMNAME', $result->parameters['PARAMNAME']->name);
-        $this->assertEquals('paramvalue', $result->parameters['PARAMNAME']->getValue());
-
-    }
-
-    function testReadPropertyRepeatingParameter() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;N=1;N=2;N=3,4;N=\"5\",6;N=\"7,8\";N=9,10;N=^'11^':propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('N', $result->parameters['N']->name);
-        $this->assertEquals('1,2,3,4,5,6,7,8,9,10,"11"', $result->parameters['N']->getValue());
-        $this->assertEquals(array(1,2,3,4,5,6,"7,8",9,10,'"11"'), $result->parameters['N']->getParts());
-
-    }
-
-    function testReadPropertyRepeatingNamelessGuessedParameter() {
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;WORK;VOICE;PREF:propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('TYPE', $result->parameters['TYPE']->name);
-        $this->assertEquals('WORK,VOICE,PREF', $result->parameters['TYPE']->getValue());
-        $this->assertEquals(array('WORK', 'VOICE', 'PREF'), $result->parameters['TYPE']->getParts());
-
-    }
-
-    function testReadPropertyNoName() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PRODIGY:propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('TYPE', $result->parameters['TYPE']->name);
-        $this->assertTrue($result->parameters['TYPE']->noName);
-        $this->assertEquals('PRODIGY', $result->parameters['TYPE']);
-
-    }
-
-    function testReadPropertyParameterExtraColon() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PARAMNAME=paramvalue:propValue:anotherrandomstring\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue:anotherrandomstring', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('PARAMNAME', $result->parameters['PARAMNAME']->name);
-        $this->assertEquals('paramvalue', $result->parameters['PARAMNAME']->getValue());
-
-    }
-
-    function testReadProperty2Parameters() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PARAMNAME=paramvalue;PARAMNAME2=paramvalue2:propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(2, count($result->parameters()));
-        $this->assertEquals('PARAMNAME', $result->parameters['PARAMNAME']->name);
-        $this->assertEquals('paramvalue', $result->parameters['PARAMNAME']->getValue());
-        $this->assertEquals('PARAMNAME2', $result->parameters['PARAMNAME2']->name);
-        $this->assertEquals('paramvalue2', $result->parameters['PARAMNAME2']->getValue());
-
-    }
-
-    function testReadPropertyParameterQuoted() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PARAMNAME=\"paramvalue\":propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->PROPNAME;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('PARAMNAME', $result->parameters['PARAMNAME']->name);
-        $this->assertEquals('paramvalue', $result->parameters['PARAMNAME']->getValue());
-
-    }
-
-    function testReadPropertyParameterNewLines() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PARAMNAME=paramvalue1^nvalue2^^nvalue3:propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $result = $result->propname;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('PARAMNAME', $result->parameters['PARAMNAME']->name);
-        $this->assertEquals("paramvalue1\nvalue2^nvalue3", $result->parameters['PARAMNAME']->getValue());
-
-    }
-
-    function testReadPropertyParameterQuotedColon() {
-
-        $data = "BEGIN:VCALENDAR\r\nPROPNAME;PARAMNAME=\"param:value\":propValue\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-        $result = $result->propname;
-
-        $this->assertInstanceOf('Sabre\\VObject\\Property', $result);
-        $this->assertEquals('PROPNAME', $result->name);
-        $this->assertEquals('propValue', $result->getValue());
-        $this->assertEquals(1, count($result->parameters()));
-        $this->assertEquals('PARAMNAME', $result->parameters['PARAMNAME']->name);
-        $this->assertEquals('param:value', $result->parameters['PARAMNAME']->getValue());
-
-    }
-
-    function testReadForgiving() {
-
-        $data = array(
-            "BEGIN:VCALENDAR",
-            "X_PROP:propValue",
-            "END:VCALENDAR"
-        );
-
-        $caught = false;
-        try {
-            $result = Reader::read(implode("\r\n",$data));
-        } catch (ParseException $e) {
-            $caught = true;
-        }
-
-        $this->assertEquals(true, $caught);
-
-        $result = Reader::read(implode("\r\n",$data), Reader::OPTION_FORGIVING);
-
-        $expected = implode("\r\n", array(
-            "BEGIN:VCALENDAR",
-            "X_PROP:propValue",
-            "END:VCALENDAR",
-            ""
-        ));
-
-        $this->assertEquals($expected, $result->serialize());
-
-    }
-
-    function testReadWithInvalidLine() {
-
-        $data = array(
-            "BEGIN:VCALENDAR",
-            "DESCRIPTION:propValue",
-            "Yes, we've actually seen a file with non-idented property values on multiple lines",
-            "END:VCALENDAR"
-        );
-
-        $caught = false;
-        try {
-            $result = Reader::read(implode("\r\n",$data));
-        } catch (ParseException $e) {
-            $caught = true;
-        }
-
-        $this->assertEquals(true, $caught);
-
-        $result = Reader::read(implode("\r\n",$data), Reader::OPTION_IGNORE_INVALID_LINES);
-
-        $expected = implode("\r\n", array(
-            "BEGIN:VCALENDAR",
-            "DESCRIPTION:propValue",
-            "END:VCALENDAR",
-            ""
-        ));
-
-        $this->assertEquals($expected, $result->serialize());
-
-    }
-
-    /**
-     * Reported as Issue 32.
-     *
-     * @expectedException \Sabre\VObject\ParseException
-     */
-    public function testReadIncompleteFile() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:1.0
-BEGIN:VEVENT
-X-FUNAMBOL-FOLDER:DEFAULT_FOLDER
-X-FUNAMBOL-ALLDAY:0
-DTSTART:20111017T110000Z
-DTEND:20111017T123000Z
-X-MICROSOFT-CDO-BUSYSTATUS:BUSY
-CATEGORIES:
-LOCATION;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:Netviewer Meeting
-PRIORITY:1
-STATUS:3
-X-MICROSOFT-CDO-REPLYTIME:20111017T064200Z
-SUMMARY;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:Kopieren: test
-CLASS:PUBLIC
-AALARM:
-RRULE:
-X-FUNAMBOL-BILLINGINFO:
-X-FUNAMBOL-COMPANIES:
-X-FUNAMBOL-MILEAGE:
-X-FUNAMBOL-NOAGING:0
-ATTENDEE;STATUS=NEEDS ACTION;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:'Heino' heino@test.com
-ATTENDEE;STATUS=NEEDS ACTION;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:'Markus' test@test.com
-ATTENDEE;STATUS=NEEDS AC
-ICS;
-
-        Reader::read($input);
-
-    }
-
-    /**
-     * @expectedException \InvalidArgumentException
-     */
-    public function testReadBrokenInput() {
-
-        Reader::read(false);
-
-    }
-
-    public function testReadBOM() {
-
-        $data = chr(0xef) . chr(0xbb) . chr(0xbf) . "BEGIN:VCALENDAR\r\nEND:VCALENDAR";
-        $result = Reader::read($data);
-
-        $this->assertInstanceOf('Sabre\\VObject\\Component', $result);
-        $this->assertEquals('VCALENDAR', $result->name);
-        $this->assertEquals(0, count($result->children));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    DateTime;
-
-class RecurrenceIteratorByMonthInDailyTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * This tests the expansion of dates with DAILY frequency in RRULE with BYMONTH restrictions
-     */
-    function testExpand() {
-
-        $ics = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Apple Inc.//iCal 4.0.4//EN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-TRANSP:OPAQUE
-DTEND:20070925T183000Z
-UID:uuid
-DTSTAMP:19700101T000000Z
-LOCATION:
-DESCRIPTION:
-STATUS:CONFIRMED
-SEQUENCE:18
-SUMMARY:Stuff
-DTSTART:20070925T160000Z
-CREATED:20071004T144642Z
-RRULE:FREQ=DAILY;BYMONTH=9,10;BYDAY=SU
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($ics);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $vcal->expand(new DateTime('2013-09-28'), new DateTime('2014-09-11'));
-
-        foreach ($vcal->VEVENT as $event) {
-            $dates[] = $event->DTSTART->getValue();
-        }
-
-        $expectedDates = array(
-            "20130929T160000Z",
-            "20131006T160000Z",
-            "20131013T160000Z",
-            "20131020T160000Z",
-            "20131027T160000Z",
-            "20140907T160000Z"
-        );
-
-        $this->assertEquals($expectedDates, $dates, 'Recursed dates are restricted by month');
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/FifthTuesdayProblemTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur\EventIterator;
-
-use Sabre\VObject\Recur;
-use Sabre\VObject\Reader;
-
-class FifthTuesdayProblemTest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * A pretty slow test. Had to be marked as 'medium' for phpunit to not die
-     * after 1 second. Would be good to optimize later.
-     *
-     * @medium
-     */
-    function testGetDTEnd() {
-
-        $ics = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Apple Inc.//iCal 4.0.4//EN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-TRANSP:OPAQUE
-DTEND;TZID=America/New_York:20070925T170000
-UID:uuid
-DTSTAMP:19700101T000000Z
-LOCATION:
-DESCRIPTION:
-STATUS:CONFIRMED
-SEQUENCE:18
-SUMMARY:Stuff
-DTSTART;TZID=America/New_York:20070925T160000
-CREATED:20071004T144642Z
-RRULE:FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vObject = Reader::read($ics);
-        $it = new Recur\EventIterator($vObject, (string)$vObject->VEVENT->UID);
-
-        while($it->valid()) {
-            $it->next();
-        }
-
-        // If we got here, it means we were successful. The bug that was in the
-        // system before would fail on the 5th tuesday of the month, if the 5th
-        // tuesday did not exist.
-        $this->assertTrue(true);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    DateTime,
-    DateTimeZone;
-
-/**
- * This is a unittest for Issue #53.
- */
-class RecurrenceIteratorIncorrectExpandTest extends \PHPUnit_Framework_TestCase {
-
-    function testExpand() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foo
-DTSTART:20130711T050000Z
-DTEND:20130711T053000Z
-RRULE:FREQ=DAILY;INTERVAL=1;COUNT=2
-END:VEVENT
-BEGIN:VEVENT
-UID:foo
-DTSTART:20130719T050000Z
-DTEND:20130719T053000Z
-RECURRENCE-ID:20130712T050000Z
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $vcal->expand(new DateTime('2011-01-01'), new DateTime('2014-01-01'));
-
-        $result = $vcal->serialize();
-
-        $output = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foo
-DTSTART:20130711T050000Z
-DTEND:20130711T053000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foo
-DTSTART:20130719T050000Z
-DTEND:20130719T053000Z
-RECURRENCE-ID:20130712T050000Z
-END:VEVENT
-END:VCALENDAR
-
-ICS;
-        $this->assertEquals($output, str_replace("\r", "", $result));
-    
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/InfiniteLoopProblemTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur\EventIterator;
-
-use
-    DateTime,
-    DateTimeZone,
-    Sabre\VObject\Component\VCalendar,
-    Sabre\VObject\Recur;
-
-class EventIteratorInfiniteLoopProblemTest extends \PHPUnit_Framework_TestCase {
-
-    public function setUp() {
-
-        $this->vcal = new VCalendar();
-
-    }
-
-    /**
-     * This bug came from a Fruux customer. This would result in a never-ending
-     * request.
-     */
-    function testFastForwardTooFar() {
-
-        $ev = $this->vcal->createComponent('VEVENT');
-        $ev->UID = 'foobar';
-        $ev->DTSTART = '20090420T180000Z';
-        $ev->RRULE = 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1';
-
-        $this->assertFalse($ev->isInTimeRange(new DateTime('2012-01-01 12:00:00'),new DateTime('3000-01-01 00:00:00')));
-
-    }
-
-    /**
-     * Different bug, also likely an infinite loop.
-     */
-    function testYearlyByMonthLoop() {
-
-        $ev = $this->vcal->createComponent('VEVENT');
-        $ev->UID = 'uuid';
-        $ev->DTSTART = '20120101T154500';
-        $ev->DTSTART['TZID'] = 'Europe/Berlin';
-        $ev->RRULE = 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA';
-        $ev->DTEND = '20120101T164500';
-        $ev->DTEND['TZID'] = 'Europe/Berlin';
-
-        // This recurrence rule by itself is a yearly rule that should happen
-        // every february.
-        //
-        // The BYDAY part expands this to every day of the month, but the
-        // BYSETPOS limits this to only the 1st day of the month. Very crazy
-        // way to specify this, and could have certainly been a lot easier.
-        $this->vcal->add($ev);
-
-        $it = new Recur\EventIterator($this->vcal,'uuid');
-        $it->fastForward(new DateTime('2012-01-29 23:00:00', new DateTimeZone('UTC')));
-
-        $collect = array();
-
-        while($it->valid()) {
-            $collect[] = $it->getDTSTART();
-            if ($it->getDTSTART() > new DateTime('2013-02-05 22:59:59', new DateTimeZone('UTC'))) {
-                break;
-            }
-            $it->next();
-
-        }
-
-        $this->assertEquals(
-            array(new DateTime('2012-02-01 15:45:00', new DateTimeZone('Europe/Berlin'))),
-            $collect
-        );
-
-    }
-
-    /**
-     * Something, somewhere produced an ics with an interval set to 0. Because
-     * this means we increase the current day (or week, month) by 0, this also
-     * results in an infinite loop.
-     *
-     * @expectedException InvalidArgumentException
-     * @return void
-     */
-    function testZeroInterval() {
-
-        $ev = $this->vcal->createComponent('VEVENT');
-        $ev->UID = 'uuid';
-        $ev->DTSTART = '20120824T145700Z';
-        $ev->RRULE = 'FREQ=YEARLY;INTERVAL=0';
-        $this->vcal->add($ev);
-
-        $it = new Recur\EventIterator($this->vcal,'uuid');
-        $it->fastForward(new DateTime('2013-01-01 23:00:00', new DateTimeZone('UTC')));
-
-        // if we got this far.. it means we are no longer infinitely looping
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/Issue48Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    DateTime,
-    DateTimeZone;
-
-class Issue48Test extends \PHPUnit_Framework_TestCase {
-
-    function testExpand() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foo
-DTEND;TZID=Europe/Moscow:20130710T120000
-DTSTART;TZID=Europe/Moscow:20130710T110000
-RRULE:FREQ=DAILY;UNTIL=20130712T195959Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foo
-DTEND;TZID=Europe/Moscow:20130713T120000
-DTSTART;TZID=Europe/Moscow:20130713T110000
-RECURRENCE-ID;TZID=Europe/Moscow:20130711T110000
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $it = new Recur\EventIterator($vcal, 'foo');
-
-        $result = iterator_to_array($it);
-
-        $tz = new DateTimeZone('Europe/Moscow');
-
-        $expected = array(
-            new DateTime('2013-07-10 11:00:00', $tz),
-            new DateTime('2013-07-12 11:00:00', $tz),
-            new DateTime('2013-07-13 11:00:00', $tz),
-        );
-
-        $this->assertEquals($expected, $result);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/Issue50Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    DateTime,
-    DateTimeZone;
-
-class Issue50Test extends \PHPUnit_Framework_TestCase {
-
-    function testExpand() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
-BEGIN:VTIMEZONE
-TZID:Europe/Brussels
-X-LIC-LOCATION:Europe/Brussels
-BEGIN:DAYLIGHT
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-TZNAME:CEST
-DTSTART:19700329T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-TZNAME:CET
-DTSTART:19701025T030000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-CREATED:20130705T142510Z
-LAST-MODIFIED:20130715T132556Z
-DTSTAMP:20130715T132556Z
-UID:1aef0b27-3d92-4581-829a-11999dd36724
-SUMMARY:Werken
-RRULE:FREQ=DAILY;COUNT=5
-DTSTART;TZID=Europe/Brussels:20130715T090000
-DTEND;TZID=Europe/Brussels:20130715T170000
-LOCATION:Job
-DESCRIPTION:Vrij
-X-MOZ-GENERATION:9
-END:VEVENT
-BEGIN:VEVENT
-CREATED:20130715T081654Z
-LAST-MODIFIED:20130715T110931Z
-DTSTAMP:20130715T110931Z
-UID:1aef0b27-3d92-4581-829a-11999dd36724
-SUMMARY:Werken
-RECURRENCE-ID;TZID=Europe/Brussels:20130719T090000
-DTSTART;TZID=Europe/Brussels:20130719T070000
-DTEND;TZID=Europe/Brussels:20130719T150000
-SEQUENCE:1
-LOCATION:Job
-DESCRIPTION:Vrij
-X-MOZ-GENERATION:1
-END:VEVENT
-BEGIN:VEVENT
-CREATED:20130715T111654Z
-LAST-MODIFIED:20130715T132556Z
-DTSTAMP:20130715T132556Z
-UID:1aef0b27-3d92-4581-829a-11999dd36724
-SUMMARY:Werken
-RECURRENCE-ID;TZID=Europe/Brussels:20130716T090000
-DTSTART;TZID=Europe/Brussels:20130716T070000
-DTEND;TZID=Europe/Brussels:20130716T150000
-SEQUENCE:1
-LOCATION:Job
-X-MOZ-GENERATION:2
-END:VEVENT
-BEGIN:VEVENT
-CREATED:20130715T125942Z
-LAST-MODIFIED:20130715T130023Z
-DTSTAMP:20130715T130023Z
-UID:1aef0b27-3d92-4581-829a-11999dd36724
-SUMMARY:Werken
-RECURRENCE-ID;TZID=Europe/Brussels:20130717T090000
-DTSTART;TZID=Europe/Brussels:20130717T070000
-DTEND;TZID=Europe/Brussels:20130717T150000
-SEQUENCE:1
-LOCATION:Job
-X-MOZ-GENERATION:3
-END:VEVENT
-BEGIN:VEVENT
-CREATED:20130715T130024Z
-LAST-MODIFIED:20130715T130034Z
-DTSTAMP:20130715T130034Z
-UID:1aef0b27-3d92-4581-829a-11999dd36724
-SUMMARY:Werken
-RECURRENCE-ID;TZID=Europe/Brussels:20130718T090000
-DTSTART;TZID=Europe/Brussels:20130718T090000
-DTEND;TZID=Europe/Brussels:20130718T170000
-LOCATION:Job
-X-MOZ-GENERATION:5
-DESCRIPTION:Vrij
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $it = new Recur\EventIterator($vcal, '1aef0b27-3d92-4581-829a-11999dd36724');
-
-        $result = array();
-        foreach($it as $instance) {
-
-            $result[] = $instance;
-
-        }
-
-        $tz = new DateTimeZone('Europe/Brussels');
-
-        $this->assertEquals(array(
-            new DateTime('2013-07-15 09:00:00', $tz),
-            new DateTime('2013-07-16 07:00:00', $tz),
-            new DateTime('2013-07-17 07:00:00', $tz),
-            new DateTime('2013-07-18 09:00:00', $tz),
-            new DateTime('2013-07-19 07:00:00', $tz),
-        ), $result);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/MainTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1427 +0,0 @@
-<?php
-
-namespace Sabre\VObject\EventIterator;
-
-use DateTime;
-use DateTimeZone;
-use Sabre\VObject\Recur\EventIterator;
-use Sabre\VObject\Component\VCalendar;
-
-class MainTest extends \PHPUnit_Framework_TestCase {
-
-    function testValues() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;BYHOUR=10;BYMINUTE=5;BYSECOND=16;BYWEEKNO=32;BYYEARDAY=100,200';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $this->assertTrue($it->isInfinite());
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     * @depends testValues
-     */
-    function testInvalidFreq() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-        $ev->RRULE = 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z';
-        $ev->UID = 'foo';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testVCalendarNoUID() {
-
-        $vcal = new VCalendar();
-        $it = new EventIterator($vcal);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testVCalendarInvalidUID() {
-
-        $vcal = new VCalendar();
-        $it = new EventIterator($vcal,'foo');
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testHourly() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=HOURLY;INTERVAL=3;UNTIL=20111025T000000Z';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07 12:00:00', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,$ev->uid);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07 12:00:00', $tz),
-                new DateTime('2011-10-07 15:00:00', $tz),
-                new DateTime('2011-10-07 18:00:00', $tz),
-                new DateTime('2011-10-07 21:00:00', $tz),
-                new DateTime('2011-10-08 00:00:00', $tz),
-                new DateTime('2011-10-08 03:00:00', $tz),
-                new DateTime('2011-10-08 06:00:00', $tz),
-                new DateTime('2011-10-08 09:00:00', $tz),
-                new DateTime('2011-10-08 12:00:00', $tz),
-                new DateTime('2011-10-08 15:00:00', $tz),
-                new DateTime('2011-10-08 18:00:00', $tz),
-                new DateTime('2011-10-08 21:00:00', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testDaily() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,$ev->uid);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-10', $tz),
-                new DateTime('2011-10-13', $tz),
-                new DateTime('2011-10-16', $tz),
-                new DateTime('2011-10-19', $tz),
-                new DateTime('2011-10-22', $tz),
-                new DateTime('2011-10-25', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testNoRRULE() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,$ev->uid);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testDailyByDayByHour() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;BYDAY=SA,SU;BYHOUR=6,7';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-08 06:00:00', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new datetime('2011-10-08 06:00:00', $tz),
-                new datetime('2011-10-08 07:00:00', $tz),
-                new datetime('2011-10-09 06:00:00', $tz),
-                new datetime('2011-10-09 07:00:00', $tz),
-                new datetime('2011-10-15 06:00:00', $tz),
-                new datetime('2011-10-15 07:00:00', $tz),
-                new datetime('2011-10-16 06:00:00', $tz),
-                new datetime('2011-10-16 07:00:00', $tz),
-                new datetime('2011-10-22 06:00:00', $tz),
-                new datetime('2011-10-22 07:00:00', $tz),
-                new datetime('2011-10-23 06:00:00', $tz),
-                new datetime('2011-10-23 07:00:00', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testDailyByHour() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;INTERVAL=2;BYHOUR=10,11,12,13,14,15';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2012-10-11 12:00:00', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new datetime('2012-10-11 12:00:00', $tz),
-                new datetime('2012-10-11 13:00:00', $tz),
-                new datetime('2012-10-11 14:00:00', $tz),
-                new datetime('2012-10-11 15:00:00', $tz),
-                new datetime('2012-10-13 10:00:00', $tz),
-                new datetime('2012-10-13 11:00:00', $tz),
-                new datetime('2012-10-13 12:00:00', $tz),
-                new datetime('2012-10-13 13:00:00', $tz),
-                new datetime('2012-10-13 14:00:00', $tz),
-                new datetime('2012-10-13 15:00:00', $tz),
-                new datetime('2012-10-15 10:00:00', $tz),
-                new datetime('2012-10-15 11:00:00', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testDailyByDay() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-11', $tz),
-                new DateTime('2011-10-19', $tz),
-                new DateTime('2011-10-21', $tz),
-                new DateTime('2011-10-25', $tz),
-                new DateTime('2011-11-02', $tz),
-                new DateTime('2011-11-04', $tz),
-                new DateTime('2011-11-08', $tz),
-                new DateTime('2011-11-16', $tz),
-                new DateTime('2011-11-18', $tz),
-                new DateTime('2011-11-22', $tz),
-                new DateTime('2011-11-30', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testWeekly() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;COUNT=10';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-21', $tz),
-                new DateTime('2011-11-04', $tz),
-                new DateTime('2011-11-18', $tz),
-                new DateTime('2011-12-02', $tz),
-                new DateTime('2011-12-16', $tz),
-                new DateTime('2011-12-30', $tz),
-                new DateTime('2012-01-13', $tz),
-                new DateTime('2012-01-27', $tz),
-                new DateTime('2012-02-10', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testWeeklyByDayByHour() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=MO;BYHOUR=8,9,10';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07 08:00:00', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Grabbing the next 12 items
-        $max = 15;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07 08:00:00', $tz),
-                new DateTime('2011-10-07 09:00:00', $tz),
-                new DateTime('2011-10-07 10:00:00', $tz),
-                new DateTime('2011-10-18 08:00:00', $tz),
-                new DateTime('2011-10-18 09:00:00', $tz),
-                new DateTime('2011-10-18 10:00:00', $tz),
-                new DateTime('2011-10-19 08:00:00', $tz),
-                new DateTime('2011-10-19 09:00:00', $tz),
-                new DateTime('2011-10-19 10:00:00', $tz),
-                new DateTime('2011-10-21 08:00:00', $tz),
-                new DateTime('2011-10-21 09:00:00', $tz),
-                new DateTime('2011-10-21 10:00:00', $tz),
-                new DateTime('2011-11-01 08:00:00', $tz),
-                new DateTime('2011-11-01 09:00:00', $tz),
-                new DateTime('2011-11-01 10:00:00', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testWeeklyByDaySpecificHour() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07 18:00:00', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07 18:00:00', $tz),
-                new DateTime('2011-10-18 18:00:00', $tz),
-                new DateTime('2011-10-19 18:00:00', $tz),
-                new DateTime('2011-10-21 18:00:00', $tz),
-                new DateTime('2011-11-01 18:00:00', $tz),
-                new DateTime('2011-11-02 18:00:00', $tz),
-                new DateTime('2011-11-04 18:00:00', $tz),
-                new DateTime('2011-11-15 18:00:00', $tz),
-                new DateTime('2011-11-16 18:00:00', $tz),
-                new DateTime('2011-11-18 18:00:00', $tz),
-                new DateTime('2011-11-29 18:00:00', $tz),
-                new DateTime('2011-11-30 18:00:00', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testWeeklyByDay() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-18', $tz),
-                new DateTime('2011-10-19', $tz),
-                new DateTime('2011-10-21', $tz),
-                new DateTime('2011-11-01', $tz),
-                new DateTime('2011-11-02', $tz),
-                new DateTime('2011-11-04', $tz),
-                new DateTime('2011-11-15', $tz),
-                new DateTime('2011-11-16', $tz),
-                new DateTime('2011-11-18', $tz),
-                new DateTime('2011-11-29', $tz),
-                new DateTime('2011-11-30', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthly() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=3;COUNT=5';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-12-05', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 14;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-12-05', $tz),
-                new DateTime('2012-03-05', $tz),
-                new DateTime('2012-06-05', $tz),
-                new DateTime('2012-09-05', $tz),
-                new DateTime('2012-12-05', $tz),
-            ),
-            $result
-        );
-
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyEndOfMonth() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=12';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-12-31', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 14;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-12-31', $tz),
-                new DateTime('2012-08-31', $tz),
-                new DateTime('2012-10-31', $tz),
-                new DateTime('2012-12-31', $tz),
-                new DateTime('2013-08-31', $tz),
-                new DateTime('2013-10-31', $tz),
-                new DateTime('2013-12-31', $tz),
-                new DateTime('2014-08-31', $tz),
-                new DateTime('2014-10-31', $tz),
-                new DateTime('2014-12-31', $tz),
-                new DateTime('2015-08-31', $tz),
-                new DateTime('2015-10-31', $tz),
-            ),
-            $result
-        );
-
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByMonthDay() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-01', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 14;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-01', $tz),
-                new DateTime('2011-01-25', $tz),
-                new DateTime('2011-01-31', $tz),
-                new DateTime('2011-06-01', $tz),
-                new DateTime('2011-06-24', $tz),
-                new DateTime('2011-11-01', $tz),
-                new DateTime('2011-11-24', $tz),
-                new DateTime('2012-04-01', $tz),
-                new DateTime('2012-04-24', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * A pretty slow test. Had to be marked as 'medium' for phpunit to not die
-     * after 1 second. Would be good to optimize later.
-     *
-     * @depends testValues
-     * @medium
-     */
-    function testMonthlyByDay() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-03', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-03', $tz),
-                new DateTime('2011-01-05', $tz),
-                new DateTime('2011-01-10', $tz),
-                new DateTime('2011-01-17', $tz),
-                new DateTime('2011-01-18', $tz),
-                new DateTime('2011-01-20', $tz),
-                new DateTime('2011-01-24', $tz),
-                new DateTime('2011-01-31', $tz),
-                new DateTime('2011-03-02', $tz),
-                new DateTime('2011-03-07', $tz),
-                new DateTime('2011-03-14', $tz),
-                new DateTime('2011-03-17', $tz),
-                new DateTime('2011-03-21', $tz),
-                new DateTime('2011-03-22', $tz),
-                new DateTime('2011-03-28', $tz),
-                new DateTime('2011-05-02', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByDayByMonthDay() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-08-01', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-08-01', $tz),
-                new DateTime('2012-10-01', $tz),
-                new DateTime('2013-04-01', $tz),
-                new DateTime('2013-07-01', $tz),
-                new DateTime('2014-09-01', $tz),
-                new DateTime('2014-12-01', $tz),
-                new DateTime('2015-06-01', $tz),
-                new DateTime('2016-02-01', $tz),
-                new DateTime('2016-08-01', $tz),
-                new DateTime('2017-05-01', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByDayBySetPos() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-03', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-03', $tz),
-                new DateTime('2011-01-31', $tz),
-                new DateTime('2011-02-01', $tz),
-                new DateTime('2011-02-28', $tz),
-                new DateTime('2011-03-01', $tz),
-                new DateTime('2011-03-31', $tz),
-                new DateTime('2011-04-01', $tz),
-                new DateTime('2011-04-29', $tz),
-                new DateTime('2011-05-02', $tz),
-                new DateTime('2011-05-31', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearly() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=10;INTERVAL=3';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-01', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-01', $tz),
-                new DateTime('2014-01-01', $tz),
-                new DateTime('2017-01-01', $tz),
-                new DateTime('2020-01-01', $tz),
-                new DateTime('2023-01-01', $tz),
-                new DateTime('2026-01-01', $tz),
-                new DateTime('2029-01-01', $tz),
-                new DateTime('2032-01-01', $tz),
-                new DateTime('2035-01-01', $tz),
-                new DateTime('2038-01-01', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearlyLeapYear() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=3';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2012-02-29', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2012-02-29', $tz),
-                new DateTime('2016-02-29', $tz),
-                new DateTime('2020-02-29', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearlyByMonth() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-04-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-04-07', $tz),
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2015-04-07', $tz),
-                new DateTime('2015-10-07', $tz),
-                new DateTime('2019-04-07', $tz),
-                new DateTime('2019-10-07', $tz),
-                new DateTime('2023-04-07', $tz),
-                new DateTime('2023-10-07', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearlyByMonthByDay() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-04-04', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-04-04', $tz),
-                new DateTime('2011-04-24', $tz),
-                new DateTime('2011-10-03', $tz),
-                new DateTime('2011-10-30', $tz),
-                new DateTime('2016-04-04', $tz),
-                new DateTime('2016-04-24', $tz),
-                new DateTime('2016-10-03', $tz),
-                new DateTime('2016-10-30', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testFastForward() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-04-04', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        // The idea is that we're fast-forwarding too far in the future, so
-        // there will be no results left.
-        $it->fastForward(new DateTime('2020-05-05', new DateTimeZone('UTC')));
-
-        $max = 20;
-        $result = array();
-        while($item = $it->current()) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-            $it->next();
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-        $this->assertEquals(array(), $result);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testComplexExclusions() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=10';
-        $dtStart = $vcal->createProperty('DTSTART');
-
-        $tz = new DateTimeZone('Canada/Eastern');
-        $dtStart->setDateTime(new DateTime('2011-01-01 13:50:20', $tz));
-
-        $exDate1 = $vcal->createProperty('EXDATE');
-        $exDate1->setDateTimes(array(new DateTime('2012-01-01 13:50:20', $tz), new DateTime('2014-01-01 13:50:20', $tz)));
-        $exDate2 = $vcal->createProperty('EXDATE');
-        $exDate2->setDateTimes(array(new DateTime('2016-01-01 13:50:20', $tz)));
-
-        $ev->add($dtStart);
-        $ev->add($exDate1);
-        $ev->add($exDate2);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,(string)$ev->uid);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-01 13:50:20', $tz),
-                new DateTime('2013-01-01 13:50:20', $tz),
-                new DateTime('2015-01-01 13:50:20', $tz),
-                new DateTime('2017-01-01 13:50:20', $tz),
-                new DateTime('2018-01-01 13:50:20', $tz),
-                new DateTime('2019-01-01 13:50:20', $tz),
-                new DateTime('2020-01-01 13:50:20', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testOverridenEvent() {
-
-        $vcal = new VCalendar();
-
-        $ev1 = $vcal->createComponent('VEVENT');
-        $ev1->UID = 'overridden';
-        $ev1->RRULE = 'FREQ=DAILY;COUNT=10';
-        $ev1->DTSTART = '20120107T120000Z';
-        $ev1->SUMMARY = 'baseEvent';
-
-        $vcal->add($ev1);
-
-        // ev2 overrides an event, and puts it on 2pm instead.
-        $ev2 = $vcal->createComponent('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120110T120000Z';
-        $ev2->DTSTART = '20120110T140000Z';
-        $ev2->SUMMARY = 'Event 2';
-
-        $vcal->add($ev2);
-
-        // ev3 overrides an event, and puts it 2 days and 2 hours later
-        $ev3 = $vcal->createComponent('VEVENT');
-        $ev3->UID = 'overridden';
-        $ev3->{'RECURRENCE-ID'} = '20120113T120000Z';
-        $ev3->DTSTART = '20120115T140000Z';
-        $ev3->SUMMARY = 'Event 3';
-
-        $vcal->add($ev3);
-
-        $it = new EventIterator($vcal,'overridden');
-
-        $dates = array();
-        $summaries = array();
-        while($it->valid()) {
-
-            $dates[] = $it->getDTStart();
-            $summaries[] = (string)$it->getEventObject()->SUMMARY;
-            $it->next();
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-        $this->assertEquals(array(
-            new DateTime('2012-01-07 12:00:00',$tz),
-            new DateTime('2012-01-08 12:00:00',$tz),
-            new DateTime('2012-01-09 12:00:00',$tz),
-            new DateTime('2012-01-10 14:00:00',$tz),
-            new DateTime('2012-01-11 12:00:00',$tz),
-            new DateTime('2012-01-12 12:00:00',$tz),
-            new DateTime('2012-01-14 12:00:00',$tz),
-            new DateTime('2012-01-15 12:00:00',$tz),
-            new DateTime('2012-01-15 14:00:00',$tz),
-            new DateTime('2012-01-16 12:00:00',$tz),
-        ), $dates);
-
-        $this->assertEquals(array(
-            'baseEvent',
-            'baseEvent',
-            'baseEvent',
-            'Event 2',
-            'baseEvent',
-            'baseEvent',
-            'baseEvent',
-            'baseEvent',
-            'Event 3',
-            'baseEvent',
-        ), $summaries);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testOverridenEvent2() {
-
-        $vcal = new VCalendar();
-
-        $ev1 = $vcal->createComponent('VEVENT');
-        $ev1->UID = 'overridden';
-        $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
-        $ev1->DTSTART = '20120112T120000Z';
-        $ev1->SUMMARY = 'baseEvent';
-
-        $vcal->add($ev1);
-
-        // ev2 overrides an event, and puts it 6 days earlier instead.
-        $ev2 = $vcal->createComponent('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120119T120000Z';
-        $ev2->DTSTART = '20120113T120000Z';
-        $ev2->SUMMARY = 'Override!';
-
-        $vcal->add($ev2);
-
-        $it = new EventIterator($vcal,'overridden');
-
-        $dates = array();
-        $summaries = array();
-        while($it->valid()) {
-
-            $dates[] = $it->getDTStart();
-            $summaries[] = (string)$it->getEventObject()->SUMMARY;
-            $it->next();
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-        $this->assertEquals(array(
-            new DateTime('2012-01-12 12:00:00',$tz),
-            new DateTime('2012-01-13 12:00:00',$tz),
-            new DateTime('2012-01-26 12:00:00',$tz),
-
-        ), $dates);
-
-        $this->assertEquals(array(
-            'baseEvent',
-            'Override!',
-            'baseEvent',
-        ), $summaries);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testOverridenEventNoValuesExpected() {
-
-        $vcal = new VCalendar();
-        $ev1 = $vcal->createComponent('VEVENT');
-
-        $ev1->UID = 'overridden';
-        $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
-        $ev1->DTSTART = '20120124T120000Z';
-        $ev1->SUMMARY = 'baseEvent';
-
-        $vcal->add($ev1);
-
-        // ev2 overrides an event, and puts it 6 days earlier instead.
-        $ev2 = $vcal->createComponent('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120131T120000Z';
-        $ev2->DTSTART = '20120125T120000Z';
-        $ev2->SUMMARY = 'Override!';
-
-        $vcal->add($ev2);
-
-        $it = new EventIterator($vcal,'overridden');
-
-        $dates = array();
-        $summaries = array();
-
-        // The reported problem was specifically related to the VCALENDAR
-        // expansion. In this parcitular case, we had to forward to the 28th of
-        // january.
-        $it->fastForward(new DateTime('2012-01-28 23:00:00'));
-
-        // We stop the loop when it hits the 6th of februari. Normally this
-        // iterator would hit 24, 25 (overriden from 31) and 7 feb but because
-        // we 'filter' from the 28th till the 6th, we should get 0 results.
-        while($it->valid() && $it->getDTSTart() < new DateTime('2012-02-06 23:00:00')) {
-
-            $dates[] = $it->getDTStart();
-            $summaries[] = (string)$it->getEventObject()->SUMMARY;
-            $it->next();
-
-        }
-
-        $this->assertEquals(array(), $dates);
-        $this->assertEquals(array(), $summaries);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testRDATE() {
-
-        $vcal = new VCalendar();
-        $ev = $vcal->createComponent('VEVENT');
-
-        $ev->UID = 'bla';
-        $ev->RDATE = array(
-            new DateTime('2014-08-07', new DateTimeZone('UTC')),
-            new DateTime('2014-08-08', new DateTimeZone('UTC')),
-        );
-        $dtStart = $vcal->createProperty('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')));
-
-        $ev->add($dtStart);
-
-        $vcal->add($ev);
-
-        $it = new EventIterator($vcal,$ev->uid);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2014-08-07', $tz),
-                new DateTime('2014-08-08', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     * @expectedException \InvalidArgumentException
-     */
-    function testNoMasterBadUID() {
-
-        $vcal = new VCalendar();
-        // ev2 overrides an event, and puts it on 2pm instead.
-        $ev2 = $vcal->createComponent('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120110T120000Z';
-        $ev2->DTSTART = '20120110T140000Z';
-        $ev2->SUMMARY = 'Event 2';
-
-        $vcal->add($ev2);
-
-        // ev3 overrides an event, and puts it 2 days and 2 hours later
-        $ev3 = $vcal->createComponent('VEVENT');
-        $ev3->UID = 'overridden';
-        $ev3->{'RECURRENCE-ID'} = '20120113T120000Z';
-        $ev3->DTSTART = '20120115T140000Z';
-        $ev3->SUMMARY = 'Event 3';
-
-        $vcal->add($ev3);
-
-        $it = new EventIterator($vcal,'broken');
-
-    }
-}
-
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-use
-    DateTime,
-    DateTimeZone;
-
-class RecurrenceIteratorMissingOverriddenTest extends \PHPUnit_Framework_TestCase {
-
-    function testExpand() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foo
-DTSTART:20130727T120000Z
-DURATION:PT1H
-RRULE:FREQ=DAILY;COUNT=2
-SUMMARY:A
-END:VEVENT
-BEGIN:VEVENT
-RECURRENCE-ID:20130728T120000Z
-UID:foo
-DTSTART:20140101T120000Z
-DURATION:PT1H
-SUMMARY:B
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $vcal->expand(new DateTime('2011-01-01'), new DateTime('2015-01-01'));
-
-        $result = $vcal->serialize();
-
-        $output = <<<ICS
-BEGIN:VCALENDAR
-VERSION:2.0
-BEGIN:VEVENT
-UID:foo
-DTSTART:20130727T120000Z
-DURATION:PT1H
-SUMMARY:A
-END:VEVENT
-BEGIN:VEVENT
-RECURRENCE-ID:20130728T120000Z
-UID:foo
-DTSTART:20140101T120000Z
-DURATION:PT1H
-SUMMARY:B
-END:VEVENT
-END:VCALENDAR
-
-ICS;
-        $this->assertEquals($output, str_replace("\r","",$result));
-    
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/NoInstancesTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use
-    Sabre\VObject\Reader;
-
-class IssueEXDATETest extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * @expectedException \Sabre\VObject\Recur\NoInstancesException
-     */
-    function testRecurrence() {
-
-        $input = <<<ICS
-BEGIN:VCALENDAR
-PRODID:-//Google Inc//Google Calendar 70.9054//EN
-VERSION:2.0
-BEGIN:VEVENT
-DTSTART;TZID=Europe/Berlin:20130329T140000
-DTEND;TZID=Europe/Berlin:20130329T153000
-RRULE:FREQ=WEEKLY;BYDAY=FR;UNTIL=20130412T115959Z
-EXDATE;TZID=Europe/Berlin:20130405T140000
-EXDATE;TZID=Europe/Berlin:20130329T140000
-DTSTAMP:20140916T201215Z
-UID:foo
-SEQUENCE:1
-SUMMARY:foo
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
-
-        $it = new EventIterator($vcal, 'foo');
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/EventIterator/OverrideFirstEventTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-<?php
-
-namespace Sabre\VObject\RecurrenceIterator;
-
-use Sabre\VObject\Reader;
-use DateTime;
-
-class OverrideFirstEventTest extends \PHPUnit_Framework_TestCase {
-
-    function testOverrideFirstEvent() {
-
-        $input =  <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140803T120000Z
-RRULE:FREQ=WEEKLY
-SUMMARY:Original
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140803T120000Z
-DTSTART:20140803T120000Z
-SUMMARY:Overridden
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-09-01'));
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-RECURRENCE-ID:20140803T120000Z
-DTSTART:20140803T120000Z
-SUMMARY:Overridden
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140810T120000Z
-SUMMARY:Original
-RECURRENCE-ID:20140810T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140817T120000Z
-SUMMARY:Original
-RECURRENCE-ID:20140817T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140824T120000Z
-SUMMARY:Original
-RECURRENCE-ID:20140824T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140831T120000Z
-SUMMARY:Original
-RECURRENCE-ID:20140831T120000Z
-END:VEVENT
-END:VCALENDAR
-
-ICS;
-
-        $newIcs = $vcal->serialize();
-        $newIcs = str_replace("\r\n","\n", $newIcs);
-        $this->assertEquals(
-            $expected,
-            $newIcs
-        );
-
-
-    }
-
-    function testRemoveFirstEvent() {
-
-        $input =  <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140803T120000Z
-RRULE:FREQ=WEEKLY
-EXDATE:20140803T120000Z
-SUMMARY:Original
-END:VEVENT
-END:VCALENDAR
-ICS;
-
-        $vcal = Reader::read($input);
-        $vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-08-19'));
-
-        $expected = <<<ICS
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140810T120000Z
-SUMMARY:Original
-RECURRENCE-ID:20140810T120000Z
-END:VEVENT
-BEGIN:VEVENT
-UID:foobar
-DTSTART:20140817T120000Z
-SUMMARY:Original
-RECURRENCE-ID:20140817T120000Z
-END:VEVENT
-END:VCALENDAR
-
-ICS;
-
-        $newIcs = $vcal->serialize();
-        $newIcs = str_replace("\r\n","\n", $newIcs);
-        $this->assertEquals(
-            $expected,
-            $newIcs
-        );
-
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/RDateIteratorTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use DateTime;
-use DateTimeZone;
-
-class RDateIteratorTest extends \PHPUnit_Framework_TestCase {
-
-    function testSimple() {
-
-        $utc = new DateTimeZone('UTC');
-        $it = new RDateIterator('20140901T000000Z,20141001T000000Z', new DateTime('2014-08-01 00:00:00', $utc));
-
-        $expected = array(
-            new DateTime('2014-08-01 00:00:00', $utc),
-            new DateTime('2014-09-01 00:00:00', $utc),
-            new DateTime('2014-10-01 00:00:00', $utc),
-        );
-
-        $this->assertEquals(
-            $expected,
-            iterator_to_array($it)
-        );
-
-        $this->assertFalse($it->isInfinite());
-
-    }
-
-    function testFastForward() {
-
-        $utc = new DateTimeZone('UTC');
-        $it = new RDateIterator('20140901T000000Z,20141001T000000Z', new DateTime('2014-08-01 00:00:00', $utc));
-
-        $it->fastForward(new DateTime('2014-08-15 00:00:00'));
-
-        $result = array();
-        while($it->valid()) {
-            $result[] = $it->current();
-            $it->next();
-        }
-
-        $expected = array(
-            new DateTime('2014-09-01 00:00:00', $utc),
-            new DateTime('2014-10-01 00:00:00', $utc),
-        );
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-        $this->assertFalse($it->isInfinite());
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/Recur/RRuleIteratorTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,698 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Recur;
-
-use DateTime;
-use DateTimeZone;
-
-class RRuleIteratorTest extends \PHPUnit_Framework_TestCase {
-
-    function testHourly() {
-
-        $this->parse(
-            'FREQ=HOURLY;INTERVAL=3;COUNT=12',
-            '2011-10-07 12:00:00',
-            array(
-                '2011-10-07 12:00:00',
-                '2011-10-07 15:00:00',
-                '2011-10-07 18:00:00',
-                '2011-10-07 21:00:00',
-                '2011-10-08 00:00:00',
-                '2011-10-08 03:00:00',
-                '2011-10-08 06:00:00',
-                '2011-10-08 09:00:00',
-                '2011-10-08 12:00:00',
-                '2011-10-08 15:00:00',
-                '2011-10-08 18:00:00',
-                '2011-10-08 21:00:00',
-            )
-        );
-
-    }
-
-    function testDaily() {
-
-        $this->parse(
-            'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z',
-            '2011-10-07',
-            array(
-                '2011-10-07 00:00:00',
-                '2011-10-10 00:00:00',
-                '2011-10-13 00:00:00',
-                '2011-10-16 00:00:00',
-                '2011-10-19 00:00:00',
-                '2011-10-22 00:00:00',
-                '2011-10-25 00:00:00',
-            )
-        );
-
-    }
-
-    function testDailyByDayByHour() {
-
-        $this->parse(
-            'FREQ=DAILY;BYDAY=SA,SU;BYHOUR=6,7',
-            '2011-10-08 06:00:00',
-            array(
-                '2011-10-08 06:00:00',
-                '2011-10-08 07:00:00',
-                '2011-10-09 06:00:00',
-                '2011-10-09 07:00:00',
-                '2011-10-15 06:00:00',
-                '2011-10-15 07:00:00',
-                '2011-10-16 06:00:00',
-                '2011-10-16 07:00:00',
-                '2011-10-22 06:00:00',
-                '2011-10-22 07:00:00',
-                '2011-10-23 06:00:00',
-                '2011-10-23 07:00:00',
-            )
-        );
-
-    }
-
-    function testDailyByHour() {
-
-        $this->parse(
-            'FREQ=DAILY;INTERVAL=2;BYHOUR=10,11,12,13,14,15',
-            '2012-10-11 12:00:00',
-            array(
-                '2012-10-11 12:00:00',
-                '2012-10-11 13:00:00',
-                '2012-10-11 14:00:00',
-                '2012-10-11 15:00:00',
-                '2012-10-13 10:00:00',
-                '2012-10-13 11:00:00',
-                '2012-10-13 12:00:00',
-                '2012-10-13 13:00:00',
-                '2012-10-13 14:00:00',
-                '2012-10-13 15:00:00',
-                '2012-10-15 10:00:00',
-                '2012-10-15 11:00:00',
-            )
-        );
-
-    }
-
-    function testDailyByDay() {
-
-        $this->parse(
-            'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR',
-            '2011-10-07 12:00:00',
-            array(
-                '2011-10-07 12:00:00',
-                '2011-10-11 12:00:00',
-                '2011-10-19 12:00:00',
-                '2011-10-21 12:00:00',
-                '2011-10-25 12:00:00',
-                '2011-11-02 12:00:00',
-                '2011-11-04 12:00:00',
-                '2011-11-08 12:00:00',
-                '2011-11-16 12:00:00',
-                '2011-11-18 12:00:00',
-                '2011-11-22 12:00:00',
-                '2011-11-30 12:00:00',
-            )
-        );
-
-    }
-
-    function testDailyCount() {
-
-        $this->parse(
-            'FREQ=DAILY;COUNT=5',
-            '2014-08-01 18:03:00',
-            array(
-                '2014-08-01 18:03:00',
-                '2014-08-02 18:03:00',
-                '2014-08-03 18:03:00',
-                '2014-08-04 18:03:00',
-                '2014-08-05 18:03:00',
-            )
-        );
-
-    }
-
-    function testDailyByMonth() {
-
-        $this->parse(
-            'FREQ=DAILY;BYMONTH=9,10;BYDAY=SU',
-            '2007-10-04 16:00:00',
-            array(
-                "2013-09-29 16:00:00",
-                "2013-10-06 16:00:00",
-                "2013-10-13 16:00:00",
-                "2013-10-20 16:00:00",
-                "2013-10-27 16:00:00",
-                "2014-09-07 16:00:00"
-            ),
-            '2013-09-28'
-        );
-
-    }
-
-    function testWeekly() {
-
-        $this->parse(
-            'FREQ=WEEKLY;INTERVAL=2;COUNT=10',
-            '2011-10-07 00:00:00',
-            array(
-                '2011-10-07 00:00:00',
-                '2011-10-21 00:00:00',
-                '2011-11-04 00:00:00',
-                '2011-11-18 00:00:00',
-                '2011-12-02 00:00:00',
-                '2011-12-16 00:00:00',
-                '2011-12-30 00:00:00',
-                '2012-01-13 00:00:00',
-                '2012-01-27 00:00:00',
-                '2012-02-10 00:00:00',
-            )
-        );
-
-    }
-
-    function testWeeklyByDay() {
-
-        $this->parse(
-            'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=MO;WKST=SA',
-            '2014-08-01 00:00:00',
-            array(
-                '2014-08-01 00:00:00',
-                '2014-08-04 00:00:00',
-                '2014-08-11 00:00:00',
-                '2014-08-18 00:00:00',
-            )
-        );
-
-    }
-
-    function testWeeklyByDay2() {
-
-        $this->parse(
-            'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
-            '2011-10-07 00:00:00',
-            array(
-                '2011-10-07 00:00:00',
-                '2011-10-18 00:00:00',
-                '2011-10-19 00:00:00',
-                '2011-10-21 00:00:00',
-                '2011-11-01 00:00:00',
-                '2011-11-02 00:00:00',
-                '2011-11-04 00:00:00',
-                '2011-11-15 00:00:00',
-                '2011-11-16 00:00:00',
-                '2011-11-18 00:00:00',
-                '2011-11-29 00:00:00',
-                '2011-11-30 00:00:00',
-            )
-        );
-
-    }
-
-    function testWeeklyByDayByHour() {
-
-        $this->parse(
-            'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=MO;BYHOUR=8,9,10',
-            '2011-10-07 08:00:00',
-            array(
-                '2011-10-07 08:00:00',
-                '2011-10-07 09:00:00',
-                '2011-10-07 10:00:00',
-                '2011-10-18 08:00:00',
-                '2011-10-18 09:00:00',
-                '2011-10-18 10:00:00',
-                '2011-10-19 08:00:00',
-                '2011-10-19 09:00:00',
-                '2011-10-19 10:00:00',
-                '2011-10-21 08:00:00',
-                '2011-10-21 09:00:00',
-                '2011-10-21 10:00:00',
-                '2011-11-01 08:00:00',
-                '2011-11-01 09:00:00',
-                '2011-11-01 10:00:00',
-            )
-        );
-
-    }
-
-    function testWeeklyByDaySpecificHour() {
-
-        $this->parse(
-            'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU',
-            '2011-10-07 18:00:00',
-            array(
-                '2011-10-07 18:00:00',
-                '2011-10-18 18:00:00',
-                '2011-10-19 18:00:00',
-                '2011-10-21 18:00:00',
-                '2011-11-01 18:00:00',
-                '2011-11-02 18:00:00',
-                '2011-11-04 18:00:00',
-                '2011-11-15 18:00:00',
-                '2011-11-16 18:00:00',
-                '2011-11-18 18:00:00',
-                '2011-11-29 18:00:00',
-                '2011-11-30 18:00:00',
-            )
-        );
-
-    }
-
-    function testMonthly() {
-
-        $this->parse(
-            'FREQ=MONTHLY;INTERVAL=3;COUNT=5',
-            '2011-12-05 00:00:00',
-            array(
-                 '2011-12-05 00:00:00',
-                 '2012-03-05 00:00:00',
-                 '2012-06-05 00:00:00',
-                 '2012-09-05 00:00:00',
-                 '2012-12-05 00:00:00',
-            )
-        );
-
-    }
-
-    function testMonlthyEndOfMonth() {
-
-        $this->parse(
-            'FREQ=MONTHLY;INTERVAL=2;COUNT=12',
-            '2011-12-31 00:00:00',
-            array(
-                '2011-12-31 00:00:00',
-                '2012-08-31 00:00:00',
-                '2012-10-31 00:00:00',
-                '2012-12-31 00:00:00',
-                '2013-08-31 00:00:00',
-                '2013-10-31 00:00:00',
-                '2013-12-31 00:00:00',
-                '2014-08-31 00:00:00',
-                '2014-10-31 00:00:00',
-                '2014-12-31 00:00:00',
-                '2015-08-31 00:00:00',
-                '2015-10-31 00:00:00',
-            )
-        );
-
-    }
-
-    function testMonthlyByMonthDay() {
-
-        $this->parse(
-            'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7',
-            '2011-01-01 00:00:00',
-            array(
-                '2011-01-01 00:00:00',
-                '2011-01-25 00:00:00',
-                '2011-01-31 00:00:00',
-                '2011-06-01 00:00:00',
-                '2011-06-24 00:00:00',
-                '2011-11-01 00:00:00',
-                '2011-11-24 00:00:00',
-                '2012-04-01 00:00:00',
-                '2012-04-24 00:00:00',
-            )
-        );
-
-    }
-
-    function testMonthlyByDay() {
-
-        $this->parse(
-            'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH',
-            '2011-01-03 00:00:00',
-            array(
-                '2011-01-03 00:00:00',
-                '2011-01-05 00:00:00',
-                '2011-01-10 00:00:00',
-                '2011-01-17 00:00:00',
-                '2011-01-18 00:00:00',
-                '2011-01-20 00:00:00',
-                '2011-01-24 00:00:00',
-                '2011-01-31 00:00:00',
-                '2011-03-02 00:00:00',
-                '2011-03-07 00:00:00',
-                '2011-03-14 00:00:00',
-                '2011-03-17 00:00:00',
-                '2011-03-21 00:00:00',
-                '2011-03-22 00:00:00',
-                '2011-03-28 00:00:00',
-                '2011-05-02 00:00:00',
-            )
-        );
-
-    }
-
-    function testMonthlyByDayByMonthDay() {
-
-        $this->parse(
-            'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1',
-            '2011-08-01 00:00:00',
-            array(
-                '2011-08-01 00:00:00',
-                '2012-10-01 00:00:00',
-                '2013-04-01 00:00:00',
-                '2013-07-01 00:00:00',
-                '2014-09-01 00:00:00',
-                '2014-12-01 00:00:00',
-                '2015-06-01 00:00:00',
-                '2016-02-01 00:00:00',
-                '2016-08-01 00:00:00',
-                '2017-05-01 00:00:00',
-            )
-        );
-
-    }
-
-    function testMonthlyByDayBySetPos() {
-
-        $this->parse(
-            'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1',
-            '2011-01-03 00:00:00',
-            array(
-                '2011-01-03 00:00:00',
-                '2011-01-31 00:00:00',
-                '2011-02-01 00:00:00',
-                '2011-02-28 00:00:00',
-                '2011-03-01 00:00:00',
-                '2011-03-31 00:00:00',
-                '2011-04-01 00:00:00',
-                '2011-04-29 00:00:00',
-                '2011-05-02 00:00:00',
-                '2011-05-31 00:00:00',
-            )
-        );
-
-    }
-
-    function testYearly() {
-
-        $this->parse(
-            'FREQ=YEARLY;COUNT=10;INTERVAL=3',
-            '2011-01-01 00:00:00',
-            array(
-                '2011-01-01 00:00:00',
-                '2014-01-01 00:00:00',
-                '2017-01-01 00:00:00',
-                '2020-01-01 00:00:00',
-                '2023-01-01 00:00:00',
-                '2026-01-01 00:00:00',
-                '2029-01-01 00:00:00',
-                '2032-01-01 00:00:00',
-                '2035-01-01 00:00:00',
-                '2038-01-01 00:00:00',
-            )
-        );
-    }
-
-    function testYearlyLeapYear() {
-
-        $this->parse(
-            'FREQ=YEARLY;COUNT=3',
-            '2012-02-29 00:00:00',
-            array(
-                '2012-02-29 00:00:00',
-                '2016-02-29 00:00:00',
-                '2020-02-29 00:00:00',
-            )
-        );
-    }
-
-    function testYearlyByMonth() {
-
-        $this->parse(
-            'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10',
-            '2011-04-07 00:00:00',
-            array(
-                '2011-04-07 00:00:00',
-                '2011-10-07 00:00:00',
-                '2015-04-07 00:00:00',
-                '2015-10-07 00:00:00',
-                '2019-04-07 00:00:00',
-                '2019-10-07 00:00:00',
-                '2023-04-07 00:00:00',
-                '2023-10-07 00:00:00',
-            )
-        );
-
-    }
-
-    function testYearlyByMonthByDay() {
-
-        $this->parse(
-            'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
-            '2011-04-04 00:00:00',
-            array(
-                '2011-04-04 00:00:00',
-                '2011-04-24 00:00:00',
-                '2011-10-03 00:00:00',
-                '2011-10-30 00:00:00',
-                '2016-04-04 00:00:00',
-                '2016-04-24 00:00:00',
-                '2016-10-03 00:00:00',
-                '2016-10-30 00:00:00',
-            )
-        );
-
-    }
-
-    function testFastForward() {
-
-        // The idea is that we're fast-forwarding too far in the future, so
-        // there will be no results left.
-        $this->parse(
-            'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU',
-            '2011-04-04 00:00:00',
-            array(),
-            '2020-05-05 00:00:00'
-        );
-
-    } 
-
-    /**
-     * The bug that was in the
-     * system before would fail on the 5th tuesday of the month, if the 5th
-     * tuesday did not exist.
-     *
-     * A pretty slow test. Had to be marked as 'medium' for phpunit to not die
-     * after 1 second. Would be good to optimize later.
-     *
-     * @medium
-     */
-    function testFifthTuesdayProblem() {
-
-        $this->parse(
-            'FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU',
-            '2007-10-04 14:46:42',
-            array(
-                "2007-10-04 14:46:42",
-            )
-        );
-
-    }
-
-    /**
-     * This bug came from a Fruux customer. This would result in a never-ending
-     * request.
-     */
-    function testFastFowardTooFar() {
-
-        $this->parse(
-            'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1',
-            '2009-04-20 18:00:00',
-            array(
-                '2009-04-20 18:00:00',
-                '2009-04-27 18:00:00',
-                '2009-05-04 18:00:00',
-                '2009-05-11 18:00:00',
-                '2009-05-18 18:00:00',
-                '2009-05-25 18:00:00',
-                '2009-06-01 18:00:00',
-                '2009-06-08 18:00:00',
-                '2009-06-15 18:00:00',
-                '2009-06-22 18:00:00',
-                '2009-06-29 18:00:00',
-            )
-        );
-
-    }
-
-    /**
-     * This also at one point caused an infinite loop. We're keeping the test.
-     */
-    function testYearlyByMonthLoop() {
-
-        $this->parse(
-            'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
-            '2012-01-01 15:45:00',
-            array(
-                '2012-02-01 15:45:00',
-            ),
-            '2012-01-29 23:00:00'
-        );
-
-
-    }
-
-    /**
-     * Something, somewhere produced an ics with an interval set to 0. Because
-     * this means we increase the current day (or week, month) by 0, this also
-     * results in an infinite loop.
-     *
-     * @expectedException InvalidArgumentException
-     */
-    function testZeroInterval() {
-
-        $this->parse(
-            'FREQ=YEARLY;INTERVAL=0',
-            '2012-08-24 14:57:00',
-            array(),
-            '2013-01-01 23:00:00'
-        );
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testInvalidFreq() {
-
-        $this->parse(
-            'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z',
-            '2011-10-07',
-            array()
-        );
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testByDayBadOffset() {
-
-        $this->parse(
-            'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=0MO;WKST=SA',
-            '2014-08-01 00:00:00',
-            array()
-        );
-
-    }
-
-    function testUntilBeginHAsTimezone() {
-
-        $this->parse(
-            'FREQ=WEEKLY;UNTIL=20131118T183000',
-            '2013-09-23 18:30:00',
-            array(
-                '2013-09-23 18:30:00',
-                '2013-09-30 18:30:00',
-                '2013-10-07 18:30:00',
-                '2013-10-14 18:30:00',
-                '2013-10-21 18:30:00',
-                '2013-10-28 18:30:00',
-                '2013-11-04 18:30:00',
-                '2013-11-11 18:30:00',
-                '2013-11-18 18:30:00',
-            ),
-            null,
-            'America/New_York'
-        );
-
-    }
-
-    function testUntilBeforeDtStart() {
-
-        $this->parse(
-            'FREQ=DAILY;UNTIL=20140101T000000Z',
-            '2014-08-02 00:15:00',
-            array(
-                '2014-08-02 00:15:00',
-            )
-        );
-
-    }
-
-    function testIgnoredStuff() {
-
-        $this->parse(
-            'FREQ=DAILY;BYSECOND=1;BYMINUTE=1;BYYEARDAY=1;BYWEEKNO=1;COUNT=2',
-            '2014-08-02 00:15:00',
-            array(
-                '2014-08-02 00:15:00',
-                '2014-08-03 00:15:00',
-            )
-        );
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testUnsupportedPart() {
-
-        $this->parse(
-            'FREQ=DAILY;BYWODAN=1',
-            '2014-08-02 00:15:00',
-            array()
-        );
-
-    }
-
-    function testIteratorFunctions() {
-
-        $parser = new RRuleIterator('FREQ=DAILY', new DateTime('2014-08-02 00:00:13'));
-        $parser->next();
-        $this->assertEquals(
-            new DateTime('2014-08-03 00:00:13'),
-            $parser->current()
-        );
-        $this->assertEquals(
-            1,
-            $parser->key()
-        );
-
-        $parser->rewind();
-
-        $this->assertEquals(
-            new DateTime('2014-08-02 00:00:13'),
-            $parser->current()
-        );
-        $this->assertEquals(
-            0,
-            $parser->key()
-        );
-
-    }
-
-    function parse($rule, $start, $expected, $fastForward = null, $tz = 'UTC') {
-
-        $dt = new DateTime($start, new DateTimeZone($tz));
-        $parser = new RRuleIterator($rule, $dt);
-
-        if ($fastForward) {
-            $parser->fastForward(new DateTime($fastForward));
-        }
-
-        $result = array();
-        while($parser->valid()) {
-
-            $item = $parser->current();
-            $result[] = $item->format('Y-m-d H:i:s');
-
-            if ($parser->isInfinite() && count($result) >= count($expected)) {
-                break;
-            }
-            $parser->next();
-
-        }
-
-        $this->assertEquals(
-            $expected,
-            $result
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/RecurrenceIterator/UntilRespectsTimezoneTest.ics	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-X-WR-TIMEZONE:America/New_York
-PRODID:-//www.churchcommunitybuilder.com//Church Community Builder//EN
-CALSCALE:GREGORIAN
-METHOD:PUBLISH
-X-WR-CALNAME:Test Event
-BEGIN:VTIMEZONE
-TZID:America/New_York
-X-LIC-LOCATION:America/New_York
-BEGIN:DAYLIGHT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-DTSTART:19700308T020000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-DTSTART:19701101T020000
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:10621-1440@ccbchurch.com
-DTSTART;TZID=America/New_York:20130923T183000
-DTEND;TZID=America/New_York:20130923T203000
-DTSTAMP:20131216T170211
-RRULE:FREQ=WEEKLY;UNTIL=20131118T183000
-CREATED:20130423T161111
-DESCRIPTION:Test Event ending November 11, 2013
-LAST-MODIFIED:20131126T163428
-SEQUENCE:1387231331
-SUMMARY:Test
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
--- a/vendor/sabre/vobject/tests/VObject/SlashRTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * This issue was pointed out in Issue 55. \r should be stripped completely 
- * when encoding property values.
- */
-class SlashRTest extends \PHPUnit_Framework_TestCase {
-
-    function testEncode() {
-
-        $vcal = new Component\VCalendar();
-        $prop = $vcal->add('test', "abc\r\ndef");
-        $this->assertEquals("TEST:abc\\ndef\r\n", $prop->serialize());
-
-    }
-
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Splitter/ICalendarTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,325 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-use Sabre\VObject;
-
-class ICalendarTest extends \PHPUnit_Framework_TestCase {
-
-    protected $version;
-
-    function setUp() {
-        $this->version = VObject\Version::VERSION;
-    }
-
-    function createStream($data) {
-
-        $stream = fopen('php://memory','r+');
-        fwrite($stream, $data);
-        rewind($stream);
-        return $stream;
-
-    }
-
-    function testICalendarImportValidEvent() {
-
-        $data = <<<EOT
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foo
-DTSTAMP:20140122T233226Z
-DTSTART:20140101T070000Z
-END:VEVENT
-END:VCALENDAR
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-        $return = "";
-        while($object=$objects->getNext()) {
-            $return .= $object->serialize();
-        }
-        $this->assertEquals(array(), VObject\Reader::read($return)->validate());
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ParseException
-     */
-    function testICalendarImportWrongType() {
-
-        $data = <<<EOT
-BEGIN:VCARD
-UID:foo1
-END:VCARD
-BEGIN:VCARD
-UID:foo2
-END:VCARD
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-    }
-
-    function testICalendarImportEndOfData() {
-        $data = <<<EOT
-BEGIN:VCALENDAR
-BEGIN:VEVENT
-UID:foo
-DTSTAMP:20140122T233226Z
-END:VEVENT
-END:VCALENDAR
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-        $return = "";
-        while($object=$objects->getNext()) {
-            $return .= $object->serialize();
-        }
-        $this->assertNull($object=$objects->getNext());
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ParseException
-     */
-    function testICalendarImportInvalidEvent() {
-        $data = <<<EOT
-EOT;
-        $tempFile = $this->createStream($data);
-        $objects = new ICalendar($tempFile);
-
-    }
-
-    function testICalendarImportMultipleValidEvents() {
-
-        $event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo1
-DTSTAMP:20140122T233226Z
-DTSTART:20140101T050000Z
-END:VEVENT
-EOT;
-
-$event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo2
-DTSTAMP:20140122T233226Z
-DTSTART:20140101T060000Z
-END:VEVENT
-EOT;
-
-        $data = <<<EOT
-BEGIN:VCALENDAR
-$event[0]
-$event[1]
-END:VCALENDAR
-
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-        $return = "";
-        $i = 0;
-        while($object=$objects->getNext()) {
-
-            $expected = <<<EOT
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $this->version//EN
-CALSCALE:GREGORIAN
-$event[$i]
-END:VCALENDAR
-
-EOT;
-
-            $return .= $object->serialize();
-            $expected = str_replace("\n", "\r\n", $expected);
-            $this->assertEquals($expected, $object->serialize());
-            $i++;
-        }
-        $this->assertEquals(array(), VObject\Reader::read($return)->validate());
-    }
-
-    function testICalendarImportEventWithoutUID() {
-
-        $data = <<<EOT
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $this->version//EN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-DTSTART:20140101T040000Z
-DTSTAMP:20140122T233226Z
-END:VEVENT
-END:VCALENDAR
-
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-        $return = "";
-        while($object=$objects->getNext()) {
-            $return .= $object->serialize();
-        }
-
-        $messages = VObject\Reader::read($return)->validate();
-
-        if ($messages) {
-            $messages = array_map(
-                function($item) { return $item['message']; },
-                $messages
-            );
-            $this->fail('Validation errors: ' . implode("\n", $messages));
-        } else {
-            $this->assertEquals(array(), $messages);
-        }
-    }
-
-    function testICalendarImportMultipleVTIMEZONESAndMultipleValidEvents() {
-
-        $timezones = <<<EOT
-BEGIN:VTIMEZONE
-TZID:Europe/Berlin
-BEGIN:DAYLIGHT
-TZOFFSETFROM:+0100
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
-DTSTART:19810329T020000
-TZNAME:MESZ
-TZOFFSETTO:+0200
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:+0200
-RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
-DTSTART:19961027T030000
-TZNAME:MEZ
-TZOFFSETTO:+0100
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VTIMEZONE
-TZID:Europe/London
-BEGIN:DAYLIGHT
-TZOFFSETFROM:+0000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
-DTSTART:19810329T010000
-TZNAME:GMT+01:00
-TZOFFSETTO:+0100
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:+0100
-RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
-DTSTART:19961027T020000
-TZNAME:GMT
-TZOFFSETTO:+0000
-END:STANDARD
-END:VTIMEZONE
-EOT;
-
-        $event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo1
-DTSTAMP:20140122T232710Z
-DTSTART:20140101T010000Z
-END:VEVENT
-EOT;
-
-        $event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo2
-DTSTAMP:20140122T232710Z
-DTSTART:20140101T020000Z
-END:VEVENT
-EOT;
-
-        $event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo3
-DTSTAMP:20140122T232710Z
-DTSTART:20140101T030000Z
-END:VEVENT
-EOT;
-
-        $data = <<<EOT
-BEGIN:VCALENDAR
-$timezones
-$event[0]
-$event[1]
-$event[2]
-END:VCALENDAR
-
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-        $return = "";
-        $i = 0;
-        while($object=$objects->getNext()) {
-
-            $expected = <<<EOT
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Sabre//Sabre VObject $this->version//EN
-CALSCALE:GREGORIAN
-$timezones
-$event[$i]
-END:VCALENDAR
-
-EOT;
-            $expected = str_replace("\n", "\r\n", $expected);
-
-            $this->assertEquals($expected, $object->serialize());
-            $return .= $object->serialize();
-            $i++;
-
-        }
-
-        $this->assertEquals(array(), VObject\Reader::read($return)->validate());
-    }
-
-    function testICalendarImportWithOutVTIMEZONES() {
-
-        $data = <<<EOT
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Apple Inc.//Mac OS X 10.8//EN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-CREATED:20120605T072109Z
-UID:D6716295-C10F-4B20-82F9-E1A3026C7DCF
-DTEND;VALUE=DATE:20120717
-TRANSP:TRANSPARENT
-SUMMARY:Start Vorbereitung
-DTSTART;VALUE=DATE:20120716
-DTSTAMP:20120605T072115Z
-SEQUENCE:2
-BEGIN:VALARM
-X-WR-ALARMUID:A99EDA6A-35EB-4446-B8BC-CDA3C60C627D
-UID:A99EDA6A-35EB-4446-B8BC-CDA3C60C627D
-TRIGGER:-PT15H
-X-APPLE-DEFAULT-ALARM:TRUE
-ATTACH;VALUE=URI:Basso
-ACTION:AUDIO
-END:VALARM
-END:VEVENT
-END:VCALENDAR
-
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new ICalendar($tempFile);
-
-        $return = "";
-        while($object=$objects->getNext()) {
-            $return .= $object->serialize();
-        }
-
-        $messages = VObject\Reader::read($return)->validate();
-        $this->assertEquals(array(), $messages);
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/Splitter/VCardTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-<?php
-
-namespace Sabre\VObject\Splitter;
-
-use Sabre\VObject;
-
-class VCardTest extends \PHPUnit_Framework_TestCase {
-
-    function createStream($data) {
-
-        $stream = fopen('php://memory','r+');
-        fwrite($stream, $data);
-        rewind($stream);
-        return $stream;
-
-    }
-
-    function testVCardImportValidVCard() {
-        $data = <<<EOT
-BEGIN:VCARD
-UID:foo
-END:VCARD
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new VCard($tempFile);
-
-        $count = 0;
-        while($objects->getNext()) {
-            $count++;
-        }
-        $this->assertEquals(1, $count);
-
-    }
-
-    /**
-     * @expectedException Sabre\VObject\ParseException
-     */
-    function testVCardImportWrongType() {
-        $event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo1
-DTSTAMP:20140122T233226Z
-DTSTART:20140101T050000Z
-END:VEVENT
-EOT;
-
-$event[] = <<<EOT
-BEGIN:VEVENT
-UID:foo2
-DTSTAMP:20140122T233226Z
-DTSTART:20140101T060000Z
-END:VEVENT
-EOT;
-
-        $data = <<<EOT
-BEGIN:VCALENDAR
-$event[0]
-$event[1]
-END:VCALENDAR
-
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $splitter = new VCard($tempFile);
-
-        while($object=$splitter->getNext()) {
-        }
-
-    }
-
-    function testVCardImportValidVCardsWithCategories() {
-        $data = <<<EOT
-BEGIN:VCARD
-UID:card-in-foo1-and-foo2
-CATEGORIES:foo1,foo2
-END:VCARD
-BEGIN:VCARD
-UID:card-in-foo1
-CATEGORIES:foo1
-END:VCARD
-BEGIN:VCARD
-UID:card-in-foo3
-CATEGORIES:foo3
-END:VCARD
-BEGIN:VCARD
-UID:card-in-foo1-and-foo3
-CATEGORIES:foo1\,foo3
-END:VCARD
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $splitter = new VCard($tempFile);
-
-        $count = 0;
-        while($object=$splitter->getNext()) {
-            $count++;
-        }
-        $this->assertEquals(4, $count);
-
-    }
-
-    function testVCardImportEndOfData() {
-        $data = <<<EOT
-BEGIN:VCARD
-UID:foo
-END:VCARD
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new VCard($tempFile);
-        $object=$objects->getNext();
-
-        $this->assertNull($objects->getNext());
-
-
-    }
-
-    /**
-     * @expectedException \Sabre\VObject\ParseException
-     */
-    function testVCardImportCheckInvalidArgumentException() {
-        $data = <<<EOT
-BEGIN:FOO
-END:FOO
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new VCard($tempFile);
-        while($objects->getNext()) { }
-
-    }
-
-    function testVCardImportMultipleValidVCards() {
-        $data = <<<EOT
-BEGIN:VCARD
-UID:foo
-END:VCARD
-BEGIN:VCARD
-UID:foo
-END:VCARD
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new VCard($tempFile);
-
-        $count = 0;
-        while($objects->getNext()) {
-            $count++;
-        }
-        $this->assertEquals(2, $count);
-
-    }
-
-    function testImportMultipleSeparatedWithNewLines() {
-        $data = <<<EOT
-BEGIN:VCARD
-UID:foo
-END:VCARD
-
-
-BEGIN:VCARD
-UID:foo
-END:VCARD
-
-
-EOT;
-        $tempFile = $this->createStream($data);
-        $objects = new VCard($tempFile);
-
-        $count = 0;
-        while ($objects->getNext()) {
-            $count++;
-        }
-        $this->assertEquals(2, $count);
-    }
-
-    function testVCardImportVCardWithoutUID() {
-        $data = <<<EOT
-BEGIN:VCARD
-END:VCARD
-EOT;
-        $tempFile = $this->createStream($data);
-
-        $objects = new VCard($tempFile);
-
-        $count = 0;
-        while($objects->getNext()) {
-            $count++;
-        }
-
-        $this->assertEquals(1, $count);
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/StringUtilTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class StringUtilTest extends \PHPUnit_Framework_TestCase {
-
-    function testNonUTF8() {
-
-        $string = StringUtil::isUTF8(chr(0xbf));
-
-        $this->assertEquals(false, $string);
-
-    }
-
-    function testIsUTF8() {
-
-        $string = StringUtil::isUTF8('I 💚 SabreDAV');
-
-        $this->assertEquals(true, $string);
-
-    }
-
-    function testUTF8ControlChar() {
-
-        $string = StringUtil::isUTF8(chr(0x00));
-
-        $this->assertEquals(false, $string);
-
-    }
-
-    function testConvertToUTF8nonUTF8() {
-
-        $string = StringUtil::convertToUTF8(chr(0xbf));
-
-        $this->assertEquals(utf8_encode(chr(0xbf)), $string);
-
-    }
-
-    function testConvertToUTF8IsUTF8() {
-
-        $string = StringUtil::convertToUTF8('I 💚 SabreDAV');
-
-        $this->assertEquals('I 💚 SabreDAV', $string);
-
-    }
-
-    function testConvertToUTF8ControlChar() {
-
-        $string = StringUtil::convertToUTF8(chr(0x00));
-
-        $this->assertEquals('', $string);
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/TestCase.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class TestCase extends \PHPUnit_Framework_TestCase {
-
-    /**
-     * This method tests wether two vcards or icalendar objects are
-     * semantically identical.
-     *
-     * It supports objects being supplied as strings, streams or
-     * Sabre\VObject\Component instances.
-     *
-     * PRODID is removed from both objects as this is often variable.
-     *
-     * @param resource|string|Component $expected
-     * @param resource|string|Component $actual
-     * @param string $message
-     */
-    function assertVObjEquals($expected, $actual, $message = '') {
-
-        $self = $this;
-        $getObj = function($input) use ($self) {
-
-            if (is_resource($input)) {
-                $input = stream_get_contents($input);
-            }
-            if (is_string($input)) {
-                $input = Reader::read($input);
-            }
-            if (!$input instanceof Component) {
-                $this->fail('Input must be a string, stream or VObject component');
-            }
-            unset($input->PRODID);
-            return $input;
-
-        };
-
-        $expected = $getObj($expected);
-        $actual = $getObj($actual);
-
-        $this->assertEquals(
-            $expected->serialize(),
-            $actual->serialize(),
-            $message
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/TimeZoneUtilTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class TimezoneUtilTest extends \PHPUnit_Framework_TestCase {
-
-    function setUp() {
-
-        // clearning the tz cache
-        TimezoneUtil::$map = null;
-
-    }
-
-    /**
-     * @dataProvider getMapping
-     */
-    function testCorrectTZ($timezoneName) {
-
-        $tz = new \DateTimeZone($timezoneName);
-        $this->assertInstanceOf('DateTimeZone', $tz);
-
-    }
-
-    function getMapping() {
-
-        TimeZoneUtil::loadTzMaps();
-
-        // PHPUNit requires an array of arrays
-        return array_map(
-            function($value) {
-                return array($value);
-            },
-            TimeZoneUtil::$map
-        );
-
-    }
-
-    function testExchangeMap() {
-
-        $vobj = <<<HI
-BEGIN:VCALENDAR
-METHOD:REQUEST
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:foo
-X-MICROSOFT-CDO-TZID:2
-BEGIN:STANDARD
-DTSTART:16010101T030000
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:16010101T020000
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20120416T092149Z
-DTSTART;TZID="foo":20120418T1
- 00000
-SUMMARY:Begin Unterhaltsreinigung
-UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000
- 0100000008FECD2E607780649BE5A4C9EE6418CBC
- 000
-END:VEVENT
-END:VCALENDAR
-HI;
-
-        $tz = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj));
-        $ex = new \DateTimeZone('Europe/Lisbon');
-
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    function testWetherMicrosoftIsStillInsane() {
-
-        $vobj = <<<HI
-BEGIN:VCALENDAR
-METHOD:REQUEST
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:(GMT+01.00) Sarajevo/Warsaw/Zagreb
-X-MICROSOFT-CDO-TZID:2
-BEGIN:STANDARD
-DTSTART:16010101T030000
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
-END:STANDARD
-END:VTIMEZONE
-END:VCALENDAR
-HI;
-
-        $tz = TimeZoneUtil::getTimeZone('(GMT+01.00) Sarajevo/Warsaw/Zagreb', Reader::read($vobj));
-        $ex = new \DateTimeZone('Europe/Sarajevo');
-
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    function testUnknownExchangeId() {
-
-        $vobj = <<<HI
-BEGIN:VCALENDAR
-METHOD:REQUEST
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:foo
-X-MICROSOFT-CDO-TZID:2000
-BEGIN:STANDARD
-DTSTART:16010101T030000
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:16010101T020000
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20120416T092149Z
-DTSTART;TZID="foo":20120418T1
- 00000
-SUMMARY:Begin Unterhaltsreinigung
-UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000
- 0100000008FECD2E607780649BE5A4C9EE6418CBC
-DTEND;TZID="Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb":20120418T103
- 000
-END:VEVENT
-END:VCALENDAR
-HI;
-
-        $tz = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj));
-        $ex = new \DateTimeZone(date_default_timezone_get());
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    function testWindowsTimeZone() {
-
-        $tz = TimeZoneUtil::getTimeZone('Eastern Standard Time');
-        $ex = new \DateTimeZone('America/New_York');
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    /**
-     * @dataProvider getPHPTimeZoneIdentifiers
-     */
-    function testTimeZoneIdentifiers($tzid) {
-
-        $tz = TimeZoneUtil::getTimeZone($tzid);
-        $ex = new \DateTimeZone($tzid);
-
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    /**
-     * @dataProvider getPHPTimeZoneBCIdentifiers
-     */
-    function testTimeZoneBCIdentifiers($tzid) {
-
-        $tz = TimeZoneUtil::getTimeZone($tzid);
-        $ex = new \DateTimeZone($tzid);
-
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    function getPHPTimeZoneIdentifiers() {
-
-        // PHPUNit requires an array of arrays
-        return array_map(
-            function($value) {
-                return array($value);
-            },
-            \DateTimeZone::listIdentifiers()
-        );
-
-    }
-
-    function getPHPTimeZoneBCIdentifiers() {
-
-        // PHPUNit requires an array of arrays
-        return array_map(
-            function($value) {
-                return array($value);
-            },
-            TimeZoneUtil::getIdentifiersBC()
-        );
-
-    }
-
-    function testTimezoneOffset() {
-
-        $tz = TimeZoneUtil::getTimeZone('GMT-0400', null, true);
-
-        if (version_compare(PHP_VERSION, '5.5.10', '>=') && !defined('HHVM_VERSION')) {
-            $ex = new \DateTimeZone('-04:00');
-        } else {
-            $ex = new \DateTimeZone('Etc/GMT-4');
-        }
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testTimezoneFail() {
-
-        $tz = TimeZoneUtil::getTimeZone('FooBar', null, true);
-
-    }
-
-    function testFallBack() {
-
-        $vobj = <<<HI
-BEGIN:VCALENDAR
-METHOD:REQUEST
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:foo
-BEGIN:STANDARD
-DTSTART:16010101T030000
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:16010101T020000
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20120416T092149Z
-DTSTART;TZID="foo":20120418T1
- 00000
-SUMMARY:Begin Unterhaltsreinigung
-UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000
- 0100000008FECD2E607780649BE5A4C9EE6418CBC
- 000
-END:VEVENT
-END:VCALENDAR
-HI;
-
-        $tz = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj));
-        $ex = new \DateTimeZone(date_default_timezone_get());
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    function testLjubljanaBug() {
-
-        $vobj = <<<HI
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Ximian//NONSGML Evolution Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana
-X-LIC-LOCATION:Europe/Ljubljana
-BEGIN:STANDARD
-TZNAME:CET
-DTSTART:19701028T030000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:CEST
-DTSTART:19700325T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:foo
-DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana:
- 20121003T080000
-DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana:
- 20121003T083000
-TRANSP:OPAQUE
-SEQUENCE:2
-SUMMARY:testing
-CREATED:20121002T172613Z
-LAST-MODIFIED:20121002T172613Z
-END:VEVENT
-END:VCALENDAR
-
-HI;
-
-
-        $tz = TimeZoneUtil::getTimeZone('/freeassociation.sourceforge.net/Tzfile/Europe/Ljubljana', Reader::read($vobj));
-        $ex = new \DateTimeZone('Europe/Ljubljana');
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-    function testWeirdSystemVLICs() {
-
-$vobj = <<<HI
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Ximian//NONSGML Evolution Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT
-X-LIC-LOCATION:SystemV/EST5EDT
-BEGIN:STANDARD
-TZNAME:EST
-DTSTART:19701104T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-TZNAME:EDT
-DTSTART:19700311T020000
-RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:20121026T021107Z-6301-1000-1-0@chAir
-DTSTAMP:20120905T172126Z
-DTSTART;TZID=/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT:
- 20121026T153000
-DTEND;TZID=/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT:
- 20121026T160000
-TRANSP:OPAQUE
-SEQUENCE:5
-SUMMARY:pick up Ibby
-CLASS:PUBLIC
-CREATED:20121026T021108Z
-LAST-MODIFIED:20121026T021118Z
-X-EVOLUTION-MOVE-CALENDAR:1
-END:VEVENT
-END:VCALENDAR
-HI;
-
-        $tz = TimeZoneUtil::getTimeZone('/freeassociation.sourceforge.net/Tzfile/SystemV/EST5EDT', Reader::read($vobj), true);
-        $ex = new \DateTimeZone('America/New_York');
-        $this->assertEquals($ex->getName(), $tz->getName());
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/UUIDUtilTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class UUIDUtilTest extends \PHPUnit_Framework_TestCase {
-
-    function testValidateUUID() {
-
-        $this->assertTrue(
-            UUIDUtil::validateUUID('11111111-2222-3333-4444-555555555555')
-        );
-        $this->assertFalse(
-            UUIDUtil::validateUUID(' 11111111-2222-3333-4444-555555555555')
-        );
-        $this->assertTrue(
-            UUIDUtil::validateUUID('ffffffff-2222-3333-4444-555555555555')
-        );
-        $this->assertFalse(
-            UUIDUtil::validateUUID('fffffffg-2222-3333-4444-555555555555')
-        );
-
-    }
-
-    /**
-     * @depends testValidateUUID
-     */
-    function testGetUUID() {
-
-        $this->assertTrue(
-            UUIDUtil::validateUUID(
-                UUIDUtil::getUUID()
-            )
-        );
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/VCard21Test.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-/**
- * Assorted vcard 2.1 tests.
- */
-class VCard21Test extends \PHPUnit_Framework_TestCase {
-
-    function testPropertyWithNoName() {
-
-        $input = <<<VCF
-BEGIN:VCARD\r
-VERSION:2.1\r
-EMAIL;HOME;WORK:evert@fruux.com\r
-END:VCARD\r
-
-VCF;
-
-        $vobj = Reader::read($input);
-        $output = $vobj->serialize($input);
-
-        $this->assertEquals($input, $output);
-
-    }
-
-    function testPropertyPadValueCount() {
-
-        $input = <<<VCF
-BEGIN:VCARD
-VERSION:2.1
-N:Foo
-END:VCARD
-
-VCF;
-
-        $vobj = Reader::read($input);
-        $output = $vobj->serialize($input);
-
-        $expected = <<<VCF
-BEGIN:VCARD\r
-VERSION:2.1\r
-N:Foo;;;;\r
-END:VCARD\r
-
-VCF;
-
-
-        $this->assertEquals($expected, $output);
-
-    }
-}
--- a/vendor/sabre/vobject/tests/VObject/VCardConverterTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,531 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class VCardConverterTest extends TestCase {
-
-    function testConvert30to40() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:3.0
-PRODID:foo
-FN;CHARSET=UTF-8:Steve
-TEL;TYPE=PREF,HOME:+1 555 666 777
-ITEM1.TEL:+1 444 555 666
-ITEM1.X-ABLABEL:CustomLabel
-PHOTO;ENCODING=b;TYPE=JPEG,HOME:Zm9v
-PHOTO;ENCODING=b;TYPE=GIF:Zm9v
-PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
-PHOTO;VALUE=URI:http://example.org/foo.png
-X-ABShowAs:COMPANY
-END:VCARD
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:4.0
-FN:Steve
-TEL;PREF=1;TYPE=HOME:+1 555 666 777
-ITEM1.TEL:+1 444 555 666
-ITEM1.X-ABLABEL:CustomLabel
-PHOTO;TYPE=HOME:data:image/jpeg;base64,Zm9v
-PHOTO:data:image/gif;base64,Zm9v
-PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
-PHOTO:http://example.org/foo.png
-KIND:ORG
-END:VCARD
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testConvert40to40() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:4.0
-FN:Steve
-TEL;PREF=1;TYPE=HOME:+1 555 666 777
-PHOTO:data:image/jpeg;base64,Zm9v
-PHOTO:data:image/gif;base64,Zm9v
-PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
-PHOTO:http://example.org/foo.png
-END:VCARD
-
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:4.0
-FN:Steve
-TEL;PREF=1;TYPE=HOME:+1 555 666 777
-PHOTO:data:image/jpeg;base64,Zm9v
-PHOTO:data:image/gif;base64,Zm9v
-PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
-PHOTO:http://example.org/foo.png
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testConvert21to40() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:2.1
-N:Family;Johnson
-FN:Johnson Family
-TEL;HOME;VOICE:555-12345-345
-ADR;HOME:;;100 Street Lane;Saubel Beach;ON;H0H0H0
-LABEL;HOME;ENCODING=QUOTED-PRINTABLE:100 Street Lane=0D=0ASaubel Beach,
- ON H0H0H0
-REV:20110731T040251Z
-UID:12345678
-END:VCARD
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:4.0
-N:Family;Johnson;;;
-FN:Johnson Family
-TEL;TYPE=HOME,VOICE:555-12345-345
-ADR;TYPE=HOME:;;100 Street Lane;Saubel Beach;ON;H0H0H0;
-REV:20110731T040251Z
-UID:12345678
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testConvert30to30() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:3.0
-PRODID:foo
-FN;CHARSET=UTF-8:Steve
-TEL;TYPE=PREF,HOME:+1 555 666 777
-PHOTO;ENCODING=b;TYPE=JPEG:Zm9v
-PHOTO;ENCODING=b;TYPE=GIF:Zm9v
-PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
-PHOTO;VALUE=URI:http://example.org/foo.png
-END:VCARD
-
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:3.0
-PRODID:foo
-FN;CHARSET=UTF-8:Steve
-TEL;TYPE=PREF,HOME:+1 555 666 777
-PHOTO;ENCODING=b;TYPE=JPEG:Zm9v
-PHOTO;ENCODING=b;TYPE=GIF:Zm9v
-PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
-PHOTO;VALUE=URI:http://example.org/foo.png
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testConvert40to30() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:4.0
-PRODID:foo
-FN:Steve
-TEL;PREF=1;TYPE=HOME:+1 555 666 777
-PHOTO:data:image/jpeg;base64,Zm9v
-PHOTO:data:image/gif,foo
-PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
-PHOTO:http://example.org/foo.png
-KIND:ORG
-END:VCARD
-
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:3.0
-FN:Steve
-TEL;TYPE=PREF,HOME:+1 555 666 777
-PHOTO;ENCODING=b;TYPE=JPEG:Zm9v
-PHOTO;ENCODING=b;TYPE=GIF:Zm9v
-PHOTO;ENCODING=b;TYPE=PNG;X-PARAM=FOO:Zm9v
-PHOTO;VALUE=URI:http://example.org/foo.png
-X-ABSHOWAS:COMPANY
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testConvertGroupCard() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:3.0
-PRODID:foo
-X-ADDRESSBOOKSERVER-KIND:GROUP
-END:VCARD
-
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:4.0
-KIND:GROUP
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-        $input = $output;
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:3.0
-X-ADDRESSBOOKSERVER-KIND:GROUP
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testBDAYConversion() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:3.0
-PRODID:foo
-BDAY;X-APPLE-OMIT-YEAR=1604:1604-04-16
-END:VCARD
-
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:4.0
-BDAY:--04-16
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-        $input = $output;
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:3.0
-BDAY;X-APPLE-OMIT-YEAR=1604:1604-04-16
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testUnknownSourceVCardVersion() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:4.2
-PRODID:foo
-FN;CHARSET=UTF-8:Steve
-TEL;TYPE=PREF,HOME:+1 555 666 777
-ITEM1.TEL:+1 444 555 666
-ITEM1.X-ABLABEL:CustomLabel
-PHOTO;ENCODING=b;TYPE=JPEG,HOME:Zm9v
-PHOTO;ENCODING=b;TYPE=GIF:Zm9v
-PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
-PHOTO;VALUE=URI:http://example.org/foo.png
-X-ABShowAs:COMPANY
-END:VCARD
-
-IN;
-
-        $vcard = Reader::read($input);
-        $vcard->convert(Document::VCARD40);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testUnknownTargetVCardVersion() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:3.0
-PRODID:foo
-END:VCARD
-
-IN;
-
-        $vcard = Reader::read($input);
-        $vcard->convert(Document::VCARD21);
-
-    }
-
-    function testConvertIndividualCard() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:4.0
-PRODID:foo
-KIND:INDIVIDUAL
-END:VCARD
-
-IN;
-
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:3.0
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-        $input = $output;
-        $output = <<<OUT
-BEGIN:VCARD
-VERSION:4.0
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testAnniversary() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:4.0
-ITEM1.ANNIVERSARY:20081210
-END:VCARD
-
-IN;
-
-        $output = <<<'OUT'
-BEGIN:VCARD
-VERSION:3.0
-ITEM1.X-ABDATE;VALUE=DATE-AND-OR-TIME:20081210
-ITEM1.X-ABLABEL:_$!<Anniversary>!$_
-ITEM1.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20081210
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-        // Swapping input and output
-        list(
-            $input,
-            $output
-        ) = array(
-            $output,
-            $input
-        );
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testMultipleAnniversaries() {
-
-        $input = <<<IN
-BEGIN:VCARD
-VERSION:4.0
-ITEM1.ANNIVERSARY:20081210
-ITEM2.ANNIVERSARY:20091210
-ITEM3.ANNIVERSARY:20101210
-END:VCARD
-
-IN;
-
-        $output = <<<'OUT'
-BEGIN:VCARD
-VERSION:3.0
-ITEM1.X-ABDATE;VALUE=DATE-AND-OR-TIME:20081210
-ITEM1.X-ABLABEL:_$!<Anniversary>!$_
-ITEM1.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20081210
-ITEM2.X-ABDATE;VALUE=DATE-AND-OR-TIME:20091210
-ITEM2.X-ABLABEL:_$!<Anniversary>!$_
-ITEM2.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20091210
-ITEM3.X-ABDATE;VALUE=DATE-AND-OR-TIME:20101210
-ITEM3.X-ABLABEL:_$!<Anniversary>!$_
-ITEM3.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20101210
-END:VCARD
-
-OUT;
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD30);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-        // Swapping input and output
-        list(
-            $input,
-            $output
-        ) = array(
-            $output,
-            $input
-        );
-
-        $vcard = Reader::read($input);
-        $vcard = $vcard->convert(Document::VCARD40);
-
-        $this->assertVObjEquals(
-            $output,
-            $vcard
-        );
-
-    }
-
-    function testNoLabel() {
-
-      $input = <<<VCF
-BEGIN:VCARD
-VERSION:3.0
-UID:foo
-N:Doe;John;;;
-FN:John Doe
-item1.X-ABDATE;type=pref:2008-12-11
-END:VCARD
-
-VCF;
-
-      $vcard = Reader::read($input);
-
-      $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard);
-      $vcard = $vcard->convert(Document::VCARD40);
-      $vcard = $vcard->serialize();
-
-      $converted = Reader::read($vcard);
-      $converted->validate();
-
-      $version = Version::VERSION;
-
-      $expected = <<<VCF
-BEGIN:VCARD
-VERSION:4.0
-PRODID:-//Sabre//Sabre VObject $version//EN
-UID:foo
-N:Doe;John;;;
-FN:John Doe
-ITEM1.X-ABDATE;PREF=1:2008-12-11
-END:VCARD
-
-VCF;
-
-      $this->assertEquals($expected, str_replace("\r","", $vcard));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/VersionTest.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-<?php
-
-namespace Sabre\VObject;
-
-class VersionTest extends \PHPUnit_Framework_TestCase {
-
-    function testString() {
-
-        $v = Version::VERSION;
-        $this->assertEquals(-1, version_compare('2.0.0',$v));
-
-    }
-
-}
--- a/vendor/sabre/vobject/tests/VObject/issue153.vcf	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-BEGIN:VCARD
-VERSION:3.0
-N:Benutzer;Test;;;
-FN:Test Benutzer
-PHOTO;BASE64:
-  /9j/4AAQSkZJRgABAQAAAQABAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQA
-  AAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABQKADAAQAAAABAAABQAAAAAD/2wBD
-  AAIBAQIBAQICAQICAgICAwUDAwMDAwYEBAMFBwYHBwcGBgYHCAsJBwgKCAYGCQ0JCgsLDAwMBwkN
-  Dg0MDgsMDAv/2wBDAQICAgMCAwUDAwULCAYICwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsL
-  CwsLCwsLCwsLCwsLCwsLCwsLCwv/wAARCAFAAUADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAA
-  AAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKB
-  kaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZn
-  aGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT
-  1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI
-  CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
-  YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6
-  goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk
-  5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD8J7JbO8tYo1tIFCDLOVG5qfdaVZRwmSOFWzyA
-  F4H1rLt5WViMhdp6HgmtKK8O3B+4Rhx6fSgBI9FtjaNN5aErwRjilSys7lFAt41xyTtqc2yJCVlY
-  7eqgGqv2jyLcebjZnGPWncdzT0+w0u5eQXtrGiBcIyoPmNMXwpb/AGMTSRRbH6YAyPwqK21GKdfL
-  BAVfu+1SQX4jnjKFsp03dPypCKN9oEaKSkC7R0bGKpnSlSPdHErZOORXV3Ouy337sCLB6kpx+FY0
-  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
-  zbVbk4/OrNpefLsnyyg5UUAf/9k=
-END:VCARD
--- a/vendor/sabre/vobject/tests/VObject/issue64.vcf	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-BEGIN:VCARD
-VERSION:2.1
-PHOTO;ENCODING=BASE64;JPEG:
-  /9j/4AAQSkZJRgABAQAAAQABAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQA
-  AAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABQKADAAQAAAABAAABQAAAAAD/2wBD
-  AAIBAQIBAQICAQICAgICAwUDAwMDAwYEBAMFBwYHBwcGBgYHCAsJBwgKCAYGCQ0JCgsLDAwMBwkN
-  Dg0MDgsMDAv/2wBDAQICAgMCAwUDAwULCAYICwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsL
-  CwsLCwsLCwsLCwsLCwsLCwsLCwv/wAARCAFAAUADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAA
-  AAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKB
-  kaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZn
-  aGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT
-  1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI
-  CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
-  YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6
-  goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk
-  5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD8J7JbO8tYo1tIFCDLOVG5qfdaVZRwmSOFWzyA
-  F4H1rLt5WViMhdp6HgmtKK8O3B+4Rhx6fSgBI9FtjaNN5aErwRjilSys7lFAt41xyTtqc2yJCVlY
-  7eqgGqv2jyLcebjZnGPWncdzT0+w0u5eQXtrGiBcIyoPmNMXwpb/AGMTSRRbH6YAyPwqK21GKdfL
-  BAVfu+1SQX4jnjKFsp03dPypCKN9oEaKSkC7R0bGKpnSlSPdHErZOORXV3Ouy337sCLB6kpx+FY0
-  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
-  zbVbk4/OrNpefLsnyyg5UUAf/9k=
-
-END:VCARD
--- a/vendor/sabre/vobject/tests/bootstrap.php	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<?php
-
-date_default_timezone_set('UTC');
-
-$try = array(
-    __DIR__ . '/../vendor/autoload.php',
-    __DIR__ . '/../../../autoload.php',
-);
-
-foreach($try as $path) {
-    if (file_exists($path)) {
-        $autoLoader = include $path;
-        break;
-    }
-}
-
-$autoLoader->addPsr4('Sabre\\VObject\\',__DIR__ . '/VObject');
-
-if (!defined('SABRE_TEMPDIR')) {
-  define('SABRE_TEMPDIR', __DIR__ . '/temp/');
-}
-
-if (!file_exists(SABRE_TEMPDIR)) {
-  mkdir(SABRE_TEMPDIR);
-}
--- a/vendor/sabre/vobject/tests/phpcs/ruleset.xml	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-<?xml version="1.0"?>
-<ruleset name="sabre.php">
-    <description>sabre.io codesniffer ruleset</description>
-
-     <!-- Include the whole PSR-1 standard -->
-     <rule ref="PSR1" />
-
-     <!-- All PHP files MUST use the Unix LF (linefeed) line ending. -->
-     <rule ref="Generic.Files.LineEndings">
-      <properties>
-       <property name="eolChar" value="\n"/>
-      </properties>
-     </rule>
-
-     <!-- The closing ?> tag MUST be omitted from files containing only PHP. -->
-     <rule ref="Zend.Files.ClosingTag"/>
-
-     <!-- There MUST NOT be trailing whitespace at the end of non-blank lines. -->
-     <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
-      <properties>
-       <property name="ignoreBlankLines" value="true"/>
-       </properties>
-   </rule>
-
-   <!-- There MUST NOT be more than one statement per line. -->
-   <rule ref="Generic.Formatting.DisallowMultipleStatements"/>
-
-   <rule ref="Generic.WhiteSpace.ScopeIndent">
-      <properties>
-       <property name="ignoreIndentationTokens" type="array" value="T_COMMENT,T_DOC_COMMENT"/>
-      </properties>
-   </rule>
-   <rule ref="Generic.WhiteSpace.DisallowTabIndent"/>
-
-   <!-- PHP keywords MUST be in lower case. -->
-   <rule ref="Generic.PHP.LowerCaseKeyword"/>
-
-   <!-- The PHP constants true, false, and null MUST be in lower case. -->
-   <rule ref="Generic.PHP.LowerCaseConstant"/>
-
-   <!-- <rule ref="Squiz.Scope.MethodScope"/> -->
-   <rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing"/>
-
-   <!-- In the argument list, there MUST NOT be a space before each comma, and there MUST be one space after each comma. -->
-   <!--
-   <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
-    <properties>
-     <property name="equalsSpacing" value="1"/>
-    </properties>
-   </rule>
-   <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint">
-    <severity>0</severity>
-   </rule>
-    -->
-   <rule ref="PEAR.WhiteSpace.ScopeClosingBrace"/>
-
-</ruleset>
--- a/vendor/sabre/vobject/tests/phpunit.xml	Mon Oct 06 12:19:59 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-<phpunit
-  colors="true"
-  bootstrap="bootstrap.php"
-  convertErrorsToExceptions="true"
-  convertNoticesToExceptions="true"
-  convertWarningsToExceptions="true"
-  strict="true"
-  >
-  <testsuite name="Sabre\VObject">
-    <directory>VObject/</directory>
-  </testsuite>
-
-  <filter>
-    <whitelist addUncoveredFilesFromWhitelist="true">
-        <directory suffix=".php">../lib/</directory>
-        <exclude>
-            <file>../lib/Sabre/VObject/includes.php</file>
-        </exclude>
-   </whitelist>
-  </filter>
-</phpunit>