git subrepo commit (merge) mailcow/src/mailcow-dockerized

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "02ae5285"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "649a5c01"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: I870ad468fba026cc5abf3c5699ed1e12ff28b32b
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/.gitignore b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/CHANGELOG.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/CHANGELOG.md
new file mode 100644
index 0000000..7932e26
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/LICENSE
new file mode 100644
index 0000000..ad85e17
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020-2021 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/README.md
new file mode 100644
index 0000000..4957933
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/README.md
@@ -0,0 +1,26 @@
+Symfony Deprecation Contracts
+=============================
+
+A generic function and convention to trigger deprecation notices.
+
+This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices.
+
+By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component,
+the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments.
+
+The function requires at least 3 arguments:
+ - the name of the Composer package that is triggering the deprecation
+ - the version of the package that introduced the deprecation
+ - the message of the deprecation
+ - more arguments can be provided: they will be inserted in the message using `printf()` formatting
+
+Example:
+```php
+trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin');
+```
+
+This will generate the following message:
+`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.`
+
+While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty
+`function trigger_deprecation() {}` in your application.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/composer.json
new file mode 100644
index 0000000..3884889
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/composer.json
@@ -0,0 +1,35 @@
+{
+    "name": "symfony/deprecation-contracts",
+    "type": "library",
+    "description": "A generic function and convention to trigger deprecation notices",
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.1"
+    },
+    "autoload": {
+        "files": [
+            "function.php"
+        ]
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-main": "2.4-dev"
+        },
+        "thanks": {
+            "name": "symfony/contracts",
+            "url": "https://github.com/symfony/contracts"
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/function.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/function.php
new file mode 100644
index 0000000..d437150
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/deprecation-contracts/function.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (!function_exists('trigger_deprecation')) {
+    /**
+     * Triggers a silenced deprecation notice.
+     *
+     * @param string $package The name of the Composer package that is triggering the deprecation
+     * @param string $version The version of the package that introduced the deprecation
+     * @param string $message The message of the deprecation
+     * @param mixed  ...$args Values to insert in the message using printf() formatting
+     *
+     * @author Nicolas Grekas <p@tchwork.com>
+     */
+    function trigger_deprecation(string $package, string $version, string $message, ...$args): void
+    {
+        @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/LICENSE
new file mode 100644
index 0000000..4cd8bdd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2019 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Mbstring.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Mbstring.php
new file mode 100644
index 0000000..b599095
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Mbstring.php
@@ -0,0 +1,870 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Mbstring;
+
+/**
+ * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
+ *
+ * Implemented:
+ * - mb_chr                  - Returns a specific character from its Unicode code point
+ * - mb_convert_encoding     - Convert character encoding
+ * - mb_convert_variables    - Convert character code in variable(s)
+ * - mb_decode_mimeheader    - Decode string in MIME header field
+ * - mb_encode_mimeheader    - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
+ * - mb_decode_numericentity - Decode HTML numeric string reference to character
+ * - mb_encode_numericentity - Encode character to HTML numeric string reference
+ * - mb_convert_case         - Perform case folding on a string
+ * - mb_detect_encoding      - Detect character encoding
+ * - mb_get_info             - Get internal settings of mbstring
+ * - mb_http_input           - Detect HTTP input character encoding
+ * - mb_http_output          - Set/Get HTTP output character encoding
+ * - mb_internal_encoding    - Set/Get internal character encoding
+ * - mb_list_encodings       - Returns an array of all supported encodings
+ * - mb_ord                  - Returns the Unicode code point of a character
+ * - mb_output_handler       - Callback function converts character encoding in output buffer
+ * - mb_scrub                - Replaces ill-formed byte sequences with substitute characters
+ * - mb_strlen               - Get string length
+ * - mb_strpos               - Find position of first occurrence of string in a string
+ * - mb_strrpos              - Find position of last occurrence of a string in a string
+ * - mb_str_split            - Convert a string to an array
+ * - mb_strtolower           - Make a string lowercase
+ * - mb_strtoupper           - Make a string uppercase
+ * - mb_substitute_character - Set/Get substitution character
+ * - mb_substr               - Get part of string
+ * - mb_stripos              - Finds position of first occurrence of a string within another, case insensitive
+ * - mb_stristr              - Finds first occurrence of a string within another, case insensitive
+ * - mb_strrchr              - Finds the last occurrence of a character in a string within another
+ * - mb_strrichr             - Finds the last occurrence of a character in a string within another, case insensitive
+ * - mb_strripos             - Finds position of last occurrence of a string within another, case insensitive
+ * - mb_strstr               - Finds first occurrence of a string within another
+ * - mb_strwidth             - Return width of string
+ * - mb_substr_count         - Count the number of substring occurrences
+ *
+ * Not implemented:
+ * - mb_convert_kana         - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
+ * - mb_ereg_*               - Regular expression with multibyte support
+ * - mb_parse_str            - Parse GET/POST/COOKIE data and set global variable
+ * - mb_preferred_mime_name  - Get MIME charset string
+ * - mb_regex_encoding       - Returns current encoding for multibyte regex as string
+ * - mb_regex_set_options    - Set/Get the default options for mbregex functions
+ * - mb_send_mail            - Send encoded mail
+ * - mb_split                - Split multibyte string using regular expression
+ * - mb_strcut               - Get part of string
+ * - mb_strimwidth           - Get truncated string with specified width
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+final class Mbstring
+{
+    public const MB_CASE_FOLD = \PHP_INT_MAX;
+
+    private const CASE_FOLD = [
+        ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"],
+        ['μ', 's', 'ι',        'σ', 'β',        'θ',        'φ',        'π',        'κ',        'ρ',        'ε',        "\xE1\xB9\xA1", 'ι'],
+    ];
+
+    private static $encodingList = ['ASCII', 'UTF-8'];
+    private static $language = 'neutral';
+    private static $internalEncoding = 'UTF-8';
+
+    public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
+    {
+        if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
+            $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
+        } else {
+            $fromEncoding = self::getEncoding($fromEncoding);
+        }
+
+        $toEncoding = self::getEncoding($toEncoding);
+
+        if ('BASE64' === $fromEncoding) {
+            $s = base64_decode($s);
+            $fromEncoding = $toEncoding;
+        }
+
+        if ('BASE64' === $toEncoding) {
+            return base64_encode($s);
+        }
+
+        if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
+            if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
+                $fromEncoding = 'Windows-1252';
+            }
+            if ('UTF-8' !== $fromEncoding) {
+                $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s);
+            }
+
+            return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
+        }
+
+        if ('HTML-ENTITIES' === $fromEncoding) {
+            $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8');
+            $fromEncoding = 'UTF-8';
+        }
+
+        return \iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
+    }
+
+    public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
+    {
+        $ok = true;
+        array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
+            if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
+                $ok = false;
+            }
+        });
+
+        return $ok ? $fromEncoding : false;
+    }
+
+    public static function mb_decode_mimeheader($s)
+    {
+        return \iconv_mime_decode($s, 2, self::$internalEncoding);
+    }
+
+    public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
+    {
+        trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING);
+    }
+
+    public static function mb_decode_numericentity($s, $convmap, $encoding = null)
+    {
+        if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
+            trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
+
+            return null;
+        }
+
+        if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) {
+            return false;
+        }
+
+        if (null !== $encoding && !is_scalar($encoding)) {
+            trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
+
+            return '';  // Instead of null (cf. mb_encode_numericentity).
+        }
+
+        $s = (string) $s;
+        if ('' === $s) {
+            return '';
+        }
+
+        $encoding = self::getEncoding($encoding);
+
+        if ('UTF-8' === $encoding) {
+            $encoding = null;
+            if (!preg_match('//u', $s)) {
+                $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
+            }
+        } else {
+            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
+        }
+
+        $cnt = floor(\count($convmap) / 4) * 4;
+
+        for ($i = 0; $i < $cnt; $i += 4) {
+            // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
+            $convmap[$i] += $convmap[$i + 2];
+            $convmap[$i + 1] += $convmap[$i + 2];
+        }
+
+        $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
+            $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
+            for ($i = 0; $i < $cnt; $i += 4) {
+                if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
+                    return self::mb_chr($c - $convmap[$i + 2]);
+                }
+            }
+
+            return $m[0];
+        }, $s);
+
+        if (null === $encoding) {
+            return $s;
+        }
+
+        return \iconv('UTF-8', $encoding.'//IGNORE', $s);
+    }
+
+    public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
+    {
+        if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
+            trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
+
+            return null;
+        }
+
+        if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) {
+            return false;
+        }
+
+        if (null !== $encoding && !is_scalar($encoding)) {
+            trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
+
+            return null;  // Instead of '' (cf. mb_decode_numericentity).
+        }
+
+        if (null !== $is_hex && !is_scalar($is_hex)) {
+            trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING);
+
+            return null;
+        }
+
+        $s = (string) $s;
+        if ('' === $s) {
+            return '';
+        }
+
+        $encoding = self::getEncoding($encoding);
+
+        if ('UTF-8' === $encoding) {
+            $encoding = null;
+            if (!preg_match('//u', $s)) {
+                $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
+            }
+        } else {
+            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
+        }
+
+        static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
+
+        $cnt = floor(\count($convmap) / 4) * 4;
+        $i = 0;
+        $len = \strlen($s);
+        $result = '';
+
+        while ($i < $len) {
+            $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
+            $uchr = substr($s, $i, $ulen);
+            $i += $ulen;
+            $c = self::mb_ord($uchr);
+
+            for ($j = 0; $j < $cnt; $j += 4) {
+                if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
+                    $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
+                    $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
+                    continue 2;
+                }
+            }
+            $result .= $uchr;
+        }
+
+        if (null === $encoding) {
+            return $result;
+        }
+
+        return \iconv('UTF-8', $encoding.'//IGNORE', $result);
+    }
+
+    public static function mb_convert_case($s, $mode, $encoding = null)
+    {
+        $s = (string) $s;
+        if ('' === $s) {
+            return '';
+        }
+
+        $encoding = self::getEncoding($encoding);
+
+        if ('UTF-8' === $encoding) {
+            $encoding = null;
+            if (!preg_match('//u', $s)) {
+                $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
+            }
+        } else {
+            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
+        }
+
+        if (\MB_CASE_TITLE == $mode) {
+            static $titleRegexp = null;
+            if (null === $titleRegexp) {
+                $titleRegexp = self::getData('titleCaseRegexp');
+            }
+            $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s);
+        } else {
+            if (\MB_CASE_UPPER == $mode) {
+                static $upper = null;
+                if (null === $upper) {
+                    $upper = self::getData('upperCase');
+                }
+                $map = $upper;
+            } else {
+                if (self::MB_CASE_FOLD === $mode) {
+                    $s = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s);
+                }
+
+                static $lower = null;
+                if (null === $lower) {
+                    $lower = self::getData('lowerCase');
+                }
+                $map = $lower;
+            }
+
+            static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
+
+            $i = 0;
+            $len = \strlen($s);
+
+            while ($i < $len) {
+                $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
+                $uchr = substr($s, $i, $ulen);
+                $i += $ulen;
+
+                if (isset($map[$uchr])) {
+                    $uchr = $map[$uchr];
+                    $nlen = \strlen($uchr);
+
+                    if ($nlen == $ulen) {
+                        $nlen = $i;
+                        do {
+                            $s[--$nlen] = $uchr[--$ulen];
+                        } while ($ulen);
+                    } else {
+                        $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
+                        $len += $nlen - $ulen;
+                        $i += $nlen - $ulen;
+                    }
+                }
+            }
+        }
+
+        if (null === $encoding) {
+            return $s;
+        }
+
+        return \iconv('UTF-8', $encoding.'//IGNORE', $s);
+    }
+
+    public static function mb_internal_encoding($encoding = null)
+    {
+        if (null === $encoding) {
+            return self::$internalEncoding;
+        }
+
+        $normalizedEncoding = self::getEncoding($encoding);
+
+        if ('UTF-8' === $normalizedEncoding || false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
+            self::$internalEncoding = $normalizedEncoding;
+
+            return true;
+        }
+
+        if (80000 > \PHP_VERSION_ID) {
+            return false;
+        }
+
+        throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding));
+    }
+
+    public static function mb_language($lang = null)
+    {
+        if (null === $lang) {
+            return self::$language;
+        }
+
+        switch ($normalizedLang = strtolower($lang)) {
+            case 'uni':
+            case 'neutral':
+                self::$language = $normalizedLang;
+
+                return true;
+        }
+
+        if (80000 > \PHP_VERSION_ID) {
+            return false;
+        }
+
+        throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang));
+    }
+
+    public static function mb_list_encodings()
+    {
+        return ['UTF-8'];
+    }
+
+    public static function mb_encoding_aliases($encoding)
+    {
+        switch (strtoupper($encoding)) {
+            case 'UTF8':
+            case 'UTF-8':
+                return ['utf8'];
+        }
+
+        return false;
+    }
+
+    public static function mb_check_encoding($var = null, $encoding = null)
+    {
+        if (null === $encoding) {
+            if (null === $var) {
+                return false;
+            }
+            $encoding = self::$internalEncoding;
+        }
+
+        return self::mb_detect_encoding($var, [$encoding]) || false !== @\iconv($encoding, $encoding, $var);
+    }
+
+    public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
+    {
+        if (null === $encodingList) {
+            $encodingList = self::$encodingList;
+        } else {
+            if (!\is_array($encodingList)) {
+                $encodingList = array_map('trim', explode(',', $encodingList));
+            }
+            $encodingList = array_map('strtoupper', $encodingList);
+        }
+
+        foreach ($encodingList as $enc) {
+            switch ($enc) {
+                case 'ASCII':
+                    if (!preg_match('/[\x80-\xFF]/', $str)) {
+                        return $enc;
+                    }
+                    break;
+
+                case 'UTF8':
+                case 'UTF-8':
+                    if (preg_match('//u', $str)) {
+                        return 'UTF-8';
+                    }
+                    break;
+
+                default:
+                    if (0 === strncmp($enc, 'ISO-8859-', 9)) {
+                        return $enc;
+                    }
+            }
+        }
+
+        return false;
+    }
+
+    public static function mb_detect_order($encodingList = null)
+    {
+        if (null === $encodingList) {
+            return self::$encodingList;
+        }
+
+        if (!\is_array($encodingList)) {
+            $encodingList = array_map('trim', explode(',', $encodingList));
+        }
+        $encodingList = array_map('strtoupper', $encodingList);
+
+        foreach ($encodingList as $enc) {
+            switch ($enc) {
+                default:
+                    if (strncmp($enc, 'ISO-8859-', 9)) {
+                        return false;
+                    }
+                    // no break
+                case 'ASCII':
+                case 'UTF8':
+                case 'UTF-8':
+            }
+        }
+
+        self::$encodingList = $encodingList;
+
+        return true;
+    }
+
+    public static function mb_strlen($s, $encoding = null)
+    {
+        $encoding = self::getEncoding($encoding);
+        if ('CP850' === $encoding || 'ASCII' === $encoding) {
+            return \strlen($s);
+        }
+
+        return @\iconv_strlen($s, $encoding);
+    }
+
+    public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
+    {
+        $encoding = self::getEncoding($encoding);
+        if ('CP850' === $encoding || 'ASCII' === $encoding) {
+            return strpos($haystack, $needle, $offset);
+        }
+
+        $needle = (string) $needle;
+        if ('' === $needle) {
+            if (80000 > \PHP_VERSION_ID) {
+                trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING);
+
+                return false;
+            }
+
+            return 0;
+        }
+
+        return \iconv_strpos($haystack, $needle, $offset, $encoding);
+    }
+
+    public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
+    {
+        $encoding = self::getEncoding($encoding);
+        if ('CP850' === $encoding || 'ASCII' === $encoding) {
+            return strrpos($haystack, $needle, $offset);
+        }
+
+        if ($offset != (int) $offset) {
+            $offset = 0;
+        } elseif ($offset = (int) $offset) {
+            if ($offset < 0) {
+                if (0 > $offset += self::mb_strlen($needle)) {
+                    $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
+                }
+                $offset = 0;
+            } else {
+                $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
+            }
+        }
+
+        $pos = '' !== $needle || 80000 > \PHP_VERSION_ID
+            ? \iconv_strrpos($haystack, $needle, $encoding)
+            : self::mb_strlen($haystack, $encoding);
+
+        return false !== $pos ? $offset + $pos : false;
+    }
+
+    public static function mb_str_split($string, $split_length = 1, $encoding = null)
+    {
+        if (null !== $string && !is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
+            trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING);
+
+            return null;
+        }
+
+        if (1 > $split_length = (int) $split_length) {
+            if (80000 > \PHP_VERSION_ID) {
+                trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
+                return false;
+            }
+
+            throw new \ValueError('Argument #2 ($length) must be greater than 0');
+        }
+
+        if (null === $encoding) {
+            $encoding = mb_internal_encoding();
+        }
+
+        if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
+            $rx = '/(';
+            while (65535 < $split_length) {
+                $rx .= '.{65535}';
+                $split_length -= 65535;
+            }
+            $rx .= '.{'.$split_length.'})/us';
+
+            return preg_split($rx, $string, null, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
+        }
+
+        $result = [];
+        $length = mb_strlen($string, $encoding);
+
+        for ($i = 0; $i < $length; $i += $split_length) {
+            $result[] = mb_substr($string, $i, $split_length, $encoding);
+        }
+
+        return $result;
+    }
+
+    public static function mb_strtolower($s, $encoding = null)
+    {
+        return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding);
+    }
+
+    public static function mb_strtoupper($s, $encoding = null)
+    {
+        return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding);
+    }
+
+    public static function mb_substitute_character($c = null)
+    {
+        if (null === $c) {
+            return 'none';
+        }
+        if (0 === strcasecmp($c, 'none')) {
+            return true;
+        }
+        if (80000 > \PHP_VERSION_ID) {
+            return false;
+        }
+
+        throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint');
+    }
+
+    public static function mb_substr($s, $start, $length = null, $encoding = null)
+    {
+        $encoding = self::getEncoding($encoding);
+        if ('CP850' === $encoding || 'ASCII' === $encoding) {
+            return (string) substr($s, $start, null === $length ? 2147483647 : $length);
+        }
+
+        if ($start < 0) {
+            $start = \iconv_strlen($s, $encoding) + $start;
+            if ($start < 0) {
+                $start = 0;
+            }
+        }
+
+        if (null === $length) {
+            $length = 2147483647;
+        } elseif ($length < 0) {
+            $length = \iconv_strlen($s, $encoding) + $length - $start;
+            if ($length < 0) {
+                return '';
+            }
+        }
+
+        return (string) \iconv_substr($s, $start, $length, $encoding);
+    }
+
+    public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
+    {
+        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
+        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
+
+        return self::mb_strpos($haystack, $needle, $offset, $encoding);
+    }
+
+    public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
+    {
+        $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
+
+        return self::getSubpart($pos, $part, $haystack, $encoding);
+    }
+
+    public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
+    {
+        $encoding = self::getEncoding($encoding);
+        if ('CP850' === $encoding || 'ASCII' === $encoding) {
+            $pos = strrpos($haystack, $needle);
+        } else {
+            $needle = self::mb_substr($needle, 0, 1, $encoding);
+            $pos = \iconv_strrpos($haystack, $needle, $encoding);
+        }
+
+        return self::getSubpart($pos, $part, $haystack, $encoding);
+    }
+
+    public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
+    {
+        $needle = self::mb_substr($needle, 0, 1, $encoding);
+        $pos = self::mb_strripos($haystack, $needle, $encoding);
+
+        return self::getSubpart($pos, $part, $haystack, $encoding);
+    }
+
+    public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
+    {
+        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
+        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
+
+        return self::mb_strrpos($haystack, $needle, $offset, $encoding);
+    }
+
+    public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
+    {
+        $pos = strpos($haystack, $needle);
+        if (false === $pos) {
+            return false;
+        }
+        if ($part) {
+            return substr($haystack, 0, $pos);
+        }
+
+        return substr($haystack, $pos);
+    }
+
+    public static function mb_get_info($type = 'all')
+    {
+        $info = [
+            'internal_encoding' => self::$internalEncoding,
+            'http_output' => 'pass',
+            'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
+            'func_overload' => 0,
+            'func_overload_list' => 'no overload',
+            'mail_charset' => 'UTF-8',
+            'mail_header_encoding' => 'BASE64',
+            'mail_body_encoding' => 'BASE64',
+            'illegal_chars' => 0,
+            'encoding_translation' => 'Off',
+            'language' => self::$language,
+            'detect_order' => self::$encodingList,
+            'substitute_character' => 'none',
+            'strict_detection' => 'Off',
+        ];
+
+        if ('all' === $type) {
+            return $info;
+        }
+        if (isset($info[$type])) {
+            return $info[$type];
+        }
+
+        return false;
+    }
+
+    public static function mb_http_input($type = '')
+    {
+        return false;
+    }
+
+    public static function mb_http_output($encoding = null)
+    {
+        return null !== $encoding ? 'pass' === $encoding : 'pass';
+    }
+
+    public static function mb_strwidth($s, $encoding = null)
+    {
+        $encoding = self::getEncoding($encoding);
+
+        if ('UTF-8' !== $encoding) {
+            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
+        }
+
+        $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
+
+        return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
+    }
+
+    public static function mb_substr_count($haystack, $needle, $encoding = null)
+    {
+        return substr_count($haystack, $needle);
+    }
+
+    public static function mb_output_handler($contents, $status)
+    {
+        return $contents;
+    }
+
+    public static function mb_chr($code, $encoding = null)
+    {
+        if (0x80 > $code %= 0x200000) {
+            $s = \chr($code);
+        } elseif (0x800 > $code) {
+            $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
+        } elseif (0x10000 > $code) {
+            $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
+        } else {
+            $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
+        }
+
+        if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
+            $s = mb_convert_encoding($s, $encoding, 'UTF-8');
+        }
+
+        return $s;
+    }
+
+    public static function mb_ord($s, $encoding = null)
+    {
+        if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
+            $s = mb_convert_encoding($s, 'UTF-8', $encoding);
+        }
+
+        if (1 === \strlen($s)) {
+            return \ord($s);
+        }
+
+        $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
+        if (0xF0 <= $code) {
+            return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
+        }
+        if (0xE0 <= $code) {
+            return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
+        }
+        if (0xC0 <= $code) {
+            return (($code - 0xC0) << 6) + $s[2] - 0x80;
+        }
+
+        return $code;
+    }
+
+    private static function getSubpart($pos, $part, $haystack, $encoding)
+    {
+        if (false === $pos) {
+            return false;
+        }
+        if ($part) {
+            return self::mb_substr($haystack, 0, $pos, $encoding);
+        }
+
+        return self::mb_substr($haystack, $pos, null, $encoding);
+    }
+
+    private static function html_encoding_callback(array $m)
+    {
+        $i = 1;
+        $entities = '';
+        $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8'));
+
+        while (isset($m[$i])) {
+            if (0x80 > $m[$i]) {
+                $entities .= \chr($m[$i++]);
+                continue;
+            }
+            if (0xF0 <= $m[$i]) {
+                $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+            } elseif (0xE0 <= $m[$i]) {
+                $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+            } else {
+                $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
+            }
+
+            $entities .= '&#'.$c.';';
+        }
+
+        return $entities;
+    }
+
+    private static function title_case(array $s)
+    {
+        return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8');
+    }
+
+    private static function getData($file)
+    {
+        if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
+            return require $file;
+        }
+
+        return false;
+    }
+
+    private static function getEncoding($encoding)
+    {
+        if (null === $encoding) {
+            return self::$internalEncoding;
+        }
+
+        if ('UTF-8' === $encoding) {
+            return 'UTF-8';
+        }
+
+        $encoding = strtoupper($encoding);
+
+        if ('8BIT' === $encoding || 'BINARY' === $encoding) {
+            return 'CP850';
+        }
+
+        if ('UTF8' === $encoding) {
+            return 'UTF-8';
+        }
+
+        return $encoding;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/README.md
new file mode 100644
index 0000000..4efb599
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/README.md
@@ -0,0 +1,13 @@
+Symfony Polyfill / Mbstring
+===========================
+
+This component provides a partial, native PHP implementation for the
+[Mbstring](https://php.net/mbstring) extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
new file mode 100644
index 0000000..fac60b0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
@@ -0,0 +1,1397 @@
+<?php
+
+return array (
+  'A' => 'a',
+  'B' => 'b',
+  'C' => 'c',
+  'D' => 'd',
+  'E' => 'e',
+  'F' => 'f',
+  'G' => 'g',
+  'H' => 'h',
+  'I' => 'i',
+  'J' => 'j',
+  'K' => 'k',
+  'L' => 'l',
+  'M' => 'm',
+  'N' => 'n',
+  'O' => 'o',
+  'P' => 'p',
+  'Q' => 'q',
+  'R' => 'r',
+  'S' => 's',
+  'T' => 't',
+  'U' => 'u',
+  'V' => 'v',
+  'W' => 'w',
+  'X' => 'x',
+  'Y' => 'y',
+  'Z' => 'z',
+  'À' => 'à',
+  'Á' => 'á',
+  'Â' => 'â',
+  'Ã' => 'ã',
+  'Ä' => 'ä',
+  'Å' => 'å',
+  'Æ' => 'æ',
+  'Ç' => 'ç',
+  'È' => 'è',
+  'É' => 'é',
+  'Ê' => 'ê',
+  'Ë' => 'ë',
+  'Ì' => 'ì',
+  'Í' => 'í',
+  'Î' => 'î',
+  'Ï' => 'ï',
+  'Ð' => 'ð',
+  'Ñ' => 'ñ',
+  'Ò' => 'ò',
+  'Ó' => 'ó',
+  'Ô' => 'ô',
+  'Õ' => 'õ',
+  'Ö' => 'ö',
+  'Ø' => 'ø',
+  'Ù' => 'ù',
+  'Ú' => 'ú',
+  'Û' => 'û',
+  'Ü' => 'ü',
+  'Ý' => 'ý',
+  'Þ' => 'þ',
+  'Ā' => 'ā',
+  'Ă' => 'ă',
+  'Ą' => 'ą',
+  'Ć' => 'ć',
+  'Ĉ' => 'ĉ',
+  'Ċ' => 'ċ',
+  'Č' => 'č',
+  'Ď' => 'ď',
+  'Đ' => 'đ',
+  'Ē' => 'ē',
+  'Ĕ' => 'ĕ',
+  'Ė' => 'ė',
+  'Ę' => 'ę',
+  'Ě' => 'ě',
+  'Ĝ' => 'ĝ',
+  'Ğ' => 'ğ',
+  'Ġ' => 'ġ',
+  'Ģ' => 'ģ',
+  'Ĥ' => 'ĥ',
+  'Ħ' => 'ħ',
+  'Ĩ' => 'ĩ',
+  'Ī' => 'ī',
+  'Ĭ' => 'ĭ',
+  'Į' => 'į',
+  'İ' => 'i̇',
+  'IJ' => 'ij',
+  'Ĵ' => 'ĵ',
+  'Ķ' => 'ķ',
+  'Ĺ' => 'ĺ',
+  'Ļ' => 'ļ',
+  'Ľ' => 'ľ',
+  'Ŀ' => 'ŀ',
+  'Ł' => 'ł',
+  'Ń' => 'ń',
+  'Ņ' => 'ņ',
+  'Ň' => 'ň',
+  'Ŋ' => 'ŋ',
+  'Ō' => 'ō',
+  'Ŏ' => 'ŏ',
+  'Ő' => 'ő',
+  'Œ' => 'œ',
+  'Ŕ' => 'ŕ',
+  'Ŗ' => 'ŗ',
+  'Ř' => 'ř',
+  'Ś' => 'ś',
+  'Ŝ' => 'ŝ',
+  'Ş' => 'ş',
+  'Š' => 'š',
+  'Ţ' => 'ţ',
+  'Ť' => 'ť',
+  'Ŧ' => 'ŧ',
+  'Ũ' => 'ũ',
+  'Ū' => 'ū',
+  'Ŭ' => 'ŭ',
+  'Ů' => 'ů',
+  'Ű' => 'ű',
+  'Ų' => 'ų',
+  'Ŵ' => 'ŵ',
+  'Ŷ' => 'ŷ',
+  'Ÿ' => 'ÿ',
+  'Ź' => 'ź',
+  'Ż' => 'ż',
+  'Ž' => 'ž',
+  'Ɓ' => 'ɓ',
+  'Ƃ' => 'ƃ',
+  'Ƅ' => 'ƅ',
+  'Ɔ' => 'ɔ',
+  'Ƈ' => 'ƈ',
+  'Ɖ' => 'ɖ',
+  'Ɗ' => 'ɗ',
+  'Ƌ' => 'ƌ',
+  'Ǝ' => 'ǝ',
+  'Ə' => 'ə',
+  'Ɛ' => 'ɛ',
+  'Ƒ' => 'ƒ',
+  'Ɠ' => 'ɠ',
+  'Ɣ' => 'ɣ',
+  'Ɩ' => 'ɩ',
+  'Ɨ' => 'ɨ',
+  'Ƙ' => 'ƙ',
+  'Ɯ' => 'ɯ',
+  'Ɲ' => 'ɲ',
+  'Ɵ' => 'ɵ',
+  'Ơ' => 'ơ',
+  'Ƣ' => 'ƣ',
+  'Ƥ' => 'ƥ',
+  'Ʀ' => 'ʀ',
+  'Ƨ' => 'ƨ',
+  'Ʃ' => 'ʃ',
+  'Ƭ' => 'ƭ',
+  'Ʈ' => 'ʈ',
+  'Ư' => 'ư',
+  'Ʊ' => 'ʊ',
+  'Ʋ' => 'ʋ',
+  'Ƴ' => 'ƴ',
+  'Ƶ' => 'ƶ',
+  'Ʒ' => 'ʒ',
+  'Ƹ' => 'ƹ',
+  'Ƽ' => 'ƽ',
+  'DŽ' => 'dž',
+  'Dž' => 'dž',
+  'LJ' => 'lj',
+  'Lj' => 'lj',
+  'NJ' => 'nj',
+  'Nj' => 'nj',
+  'Ǎ' => 'ǎ',
+  'Ǐ' => 'ǐ',
+  'Ǒ' => 'ǒ',
+  'Ǔ' => 'ǔ',
+  'Ǖ' => 'ǖ',
+  'Ǘ' => 'ǘ',
+  'Ǚ' => 'ǚ',
+  'Ǜ' => 'ǜ',
+  'Ǟ' => 'ǟ',
+  'Ǡ' => 'ǡ',
+  'Ǣ' => 'ǣ',
+  'Ǥ' => 'ǥ',
+  'Ǧ' => 'ǧ',
+  'Ǩ' => 'ǩ',
+  'Ǫ' => 'ǫ',
+  'Ǭ' => 'ǭ',
+  'Ǯ' => 'ǯ',
+  'DZ' => 'dz',
+  'Dz' => 'dz',
+  'Ǵ' => 'ǵ',
+  'Ƕ' => 'ƕ',
+  'Ƿ' => 'ƿ',
+  'Ǹ' => 'ǹ',
+  'Ǻ' => 'ǻ',
+  'Ǽ' => 'ǽ',
+  'Ǿ' => 'ǿ',
+  'Ȁ' => 'ȁ',
+  'Ȃ' => 'ȃ',
+  'Ȅ' => 'ȅ',
+  'Ȇ' => 'ȇ',
+  'Ȉ' => 'ȉ',
+  'Ȋ' => 'ȋ',
+  'Ȍ' => 'ȍ',
+  'Ȏ' => 'ȏ',
+  'Ȑ' => 'ȑ',
+  'Ȓ' => 'ȓ',
+  'Ȕ' => 'ȕ',
+  'Ȗ' => 'ȗ',
+  'Ș' => 'ș',
+  'Ț' => 'ț',
+  'Ȝ' => 'ȝ',
+  'Ȟ' => 'ȟ',
+  'Ƞ' => 'ƞ',
+  'Ȣ' => 'ȣ',
+  'Ȥ' => 'ȥ',
+  'Ȧ' => 'ȧ',
+  'Ȩ' => 'ȩ',
+  'Ȫ' => 'ȫ',
+  'Ȭ' => 'ȭ',
+  'Ȯ' => 'ȯ',
+  'Ȱ' => 'ȱ',
+  'Ȳ' => 'ȳ',
+  'Ⱥ' => 'ⱥ',
+  'Ȼ' => 'ȼ',
+  'Ƚ' => 'ƚ',
+  'Ⱦ' => 'ⱦ',
+  'Ɂ' => 'ɂ',
+  'Ƀ' => 'ƀ',
+  'Ʉ' => 'ʉ',
+  'Ʌ' => 'ʌ',
+  'Ɇ' => 'ɇ',
+  'Ɉ' => 'ɉ',
+  'Ɋ' => 'ɋ',
+  'Ɍ' => 'ɍ',
+  'Ɏ' => 'ɏ',
+  'Ͱ' => 'ͱ',
+  'Ͳ' => 'ͳ',
+  'Ͷ' => 'ͷ',
+  'Ϳ' => 'ϳ',
+  'Ά' => 'ά',
+  'Έ' => 'έ',
+  'Ή' => 'ή',
+  'Ί' => 'ί',
+  'Ό' => 'ό',
+  'Ύ' => 'ύ',
+  'Ώ' => 'ώ',
+  'Α' => 'α',
+  'Β' => 'β',
+  'Γ' => 'γ',
+  'Δ' => 'δ',
+  'Ε' => 'ε',
+  'Ζ' => 'ζ',
+  'Η' => 'η',
+  'Θ' => 'θ',
+  'Ι' => 'ι',
+  'Κ' => 'κ',
+  'Λ' => 'λ',
+  'Μ' => 'μ',
+  'Ν' => 'ν',
+  'Ξ' => 'ξ',
+  'Ο' => 'ο',
+  'Π' => 'π',
+  'Ρ' => 'ρ',
+  'Σ' => 'σ',
+  'Τ' => 'τ',
+  'Υ' => 'υ',
+  'Φ' => 'φ',
+  'Χ' => 'χ',
+  'Ψ' => 'ψ',
+  'Ω' => 'ω',
+  'Ϊ' => 'ϊ',
+  'Ϋ' => 'ϋ',
+  'Ϗ' => 'ϗ',
+  'Ϙ' => 'ϙ',
+  'Ϛ' => 'ϛ',
+  'Ϝ' => 'ϝ',
+  'Ϟ' => 'ϟ',
+  'Ϡ' => 'ϡ',
+  'Ϣ' => 'ϣ',
+  'Ϥ' => 'ϥ',
+  'Ϧ' => 'ϧ',
+  'Ϩ' => 'ϩ',
+  'Ϫ' => 'ϫ',
+  'Ϭ' => 'ϭ',
+  'Ϯ' => 'ϯ',
+  'ϴ' => 'θ',
+  'Ϸ' => 'ϸ',
+  'Ϲ' => 'ϲ',
+  'Ϻ' => 'ϻ',
+  'Ͻ' => 'ͻ',
+  'Ͼ' => 'ͼ',
+  'Ͽ' => 'ͽ',
+  'Ѐ' => 'ѐ',
+  'Ё' => 'ё',
+  'Ђ' => 'ђ',
+  'Ѓ' => 'ѓ',
+  'Є' => 'є',
+  'Ѕ' => 'ѕ',
+  'І' => 'і',
+  'Ї' => 'ї',
+  'Ј' => 'ј',
+  'Љ' => 'љ',
+  'Њ' => 'њ',
+  'Ћ' => 'ћ',
+  'Ќ' => 'ќ',
+  'Ѝ' => 'ѝ',
+  'Ў' => 'ў',
+  'Џ' => 'џ',
+  'А' => 'а',
+  'Б' => 'б',
+  'В' => 'в',
+  'Г' => 'г',
+  'Д' => 'д',
+  'Е' => 'е',
+  'Ж' => 'ж',
+  'З' => 'з',
+  'И' => 'и',
+  'Й' => 'й',
+  'К' => 'к',
+  'Л' => 'л',
+  'М' => 'м',
+  'Н' => 'н',
+  'О' => 'о',
+  'П' => 'п',
+  'Р' => 'р',
+  'С' => 'с',
+  'Т' => 'т',
+  'У' => 'у',
+  'Ф' => 'ф',
+  'Х' => 'х',
+  'Ц' => 'ц',
+  'Ч' => 'ч',
+  'Ш' => 'ш',
+  'Щ' => 'щ',
+  'Ъ' => 'ъ',
+  'Ы' => 'ы',
+  'Ь' => 'ь',
+  'Э' => 'э',
+  'Ю' => 'ю',
+  'Я' => 'я',
+  'Ѡ' => 'ѡ',
+  'Ѣ' => 'ѣ',
+  'Ѥ' => 'ѥ',
+  'Ѧ' => 'ѧ',
+  'Ѩ' => 'ѩ',
+  'Ѫ' => 'ѫ',
+  'Ѭ' => 'ѭ',
+  'Ѯ' => 'ѯ',
+  'Ѱ' => 'ѱ',
+  'Ѳ' => 'ѳ',
+  'Ѵ' => 'ѵ',
+  'Ѷ' => 'ѷ',
+  'Ѹ' => 'ѹ',
+  'Ѻ' => 'ѻ',
+  'Ѽ' => 'ѽ',
+  'Ѿ' => 'ѿ',
+  'Ҁ' => 'ҁ',
+  'Ҋ' => 'ҋ',
+  'Ҍ' => 'ҍ',
+  'Ҏ' => 'ҏ',
+  'Ґ' => 'ґ',
+  'Ғ' => 'ғ',
+  'Ҕ' => 'ҕ',
+  'Җ' => 'җ',
+  'Ҙ' => 'ҙ',
+  'Қ' => 'қ',
+  'Ҝ' => 'ҝ',
+  'Ҟ' => 'ҟ',
+  'Ҡ' => 'ҡ',
+  'Ң' => 'ң',
+  'Ҥ' => 'ҥ',
+  'Ҧ' => 'ҧ',
+  'Ҩ' => 'ҩ',
+  'Ҫ' => 'ҫ',
+  'Ҭ' => 'ҭ',
+  'Ү' => 'ү',
+  'Ұ' => 'ұ',
+  'Ҳ' => 'ҳ',
+  'Ҵ' => 'ҵ',
+  'Ҷ' => 'ҷ',
+  'Ҹ' => 'ҹ',
+  'Һ' => 'һ',
+  'Ҽ' => 'ҽ',
+  'Ҿ' => 'ҿ',
+  'Ӏ' => 'ӏ',
+  'Ӂ' => 'ӂ',
+  'Ӄ' => 'ӄ',
+  'Ӆ' => 'ӆ',
+  'Ӈ' => 'ӈ',
+  'Ӊ' => 'ӊ',
+  'Ӌ' => 'ӌ',
+  'Ӎ' => 'ӎ',
+  'Ӑ' => 'ӑ',
+  'Ӓ' => 'ӓ',
+  'Ӕ' => 'ӕ',
+  'Ӗ' => 'ӗ',
+  'Ә' => 'ә',
+  'Ӛ' => 'ӛ',
+  'Ӝ' => 'ӝ',
+  'Ӟ' => 'ӟ',
+  'Ӡ' => 'ӡ',
+  'Ӣ' => 'ӣ',
+  'Ӥ' => 'ӥ',
+  'Ӧ' => 'ӧ',
+  'Ө' => 'ө',
+  'Ӫ' => 'ӫ',
+  'Ӭ' => 'ӭ',
+  'Ӯ' => 'ӯ',
+  'Ӱ' => 'ӱ',
+  'Ӳ' => 'ӳ',
+  'Ӵ' => 'ӵ',
+  'Ӷ' => 'ӷ',
+  'Ӹ' => 'ӹ',
+  'Ӻ' => 'ӻ',
+  'Ӽ' => 'ӽ',
+  'Ӿ' => 'ӿ',
+  'Ԁ' => 'ԁ',
+  'Ԃ' => 'ԃ',
+  'Ԅ' => 'ԅ',
+  'Ԇ' => 'ԇ',
+  'Ԉ' => 'ԉ',
+  'Ԋ' => 'ԋ',
+  'Ԍ' => 'ԍ',
+  'Ԏ' => 'ԏ',
+  'Ԑ' => 'ԑ',
+  'Ԓ' => 'ԓ',
+  'Ԕ' => 'ԕ',
+  'Ԗ' => 'ԗ',
+  'Ԙ' => 'ԙ',
+  'Ԛ' => 'ԛ',
+  'Ԝ' => 'ԝ',
+  'Ԟ' => 'ԟ',
+  'Ԡ' => 'ԡ',
+  'Ԣ' => 'ԣ',
+  'Ԥ' => 'ԥ',
+  'Ԧ' => 'ԧ',
+  'Ԩ' => 'ԩ',
+  'Ԫ' => 'ԫ',
+  'Ԭ' => 'ԭ',
+  'Ԯ' => 'ԯ',
+  'Ա' => 'ա',
+  'Բ' => 'բ',
+  'Գ' => 'գ',
+  'Դ' => 'դ',
+  'Ե' => 'ե',
+  'Զ' => 'զ',
+  'Է' => 'է',
+  'Ը' => 'ը',
+  'Թ' => 'թ',
+  'Ժ' => 'ժ',
+  'Ի' => 'ի',
+  'Լ' => 'լ',
+  'Խ' => 'խ',
+  'Ծ' => 'ծ',
+  'Կ' => 'կ',
+  'Հ' => 'հ',
+  'Ձ' => 'ձ',
+  'Ղ' => 'ղ',
+  'Ճ' => 'ճ',
+  'Մ' => 'մ',
+  'Յ' => 'յ',
+  'Ն' => 'ն',
+  'Շ' => 'շ',
+  'Ո' => 'ո',
+  'Չ' => 'չ',
+  'Պ' => 'պ',
+  'Ջ' => 'ջ',
+  'Ռ' => 'ռ',
+  'Ս' => 'ս',
+  'Վ' => 'վ',
+  'Տ' => 'տ',
+  'Ր' => 'ր',
+  'Ց' => 'ց',
+  'Ւ' => 'ւ',
+  'Փ' => 'փ',
+  'Ք' => 'ք',
+  'Օ' => 'օ',
+  'Ֆ' => 'ֆ',
+  'Ⴀ' => 'ⴀ',
+  'Ⴁ' => 'ⴁ',
+  'Ⴂ' => 'ⴂ',
+  'Ⴃ' => 'ⴃ',
+  'Ⴄ' => 'ⴄ',
+  'Ⴅ' => 'ⴅ',
+  'Ⴆ' => 'ⴆ',
+  'Ⴇ' => 'ⴇ',
+  'Ⴈ' => 'ⴈ',
+  'Ⴉ' => 'ⴉ',
+  'Ⴊ' => 'ⴊ',
+  'Ⴋ' => 'ⴋ',
+  'Ⴌ' => 'ⴌ',
+  'Ⴍ' => 'ⴍ',
+  'Ⴎ' => 'ⴎ',
+  'Ⴏ' => 'ⴏ',
+  'Ⴐ' => 'ⴐ',
+  'Ⴑ' => 'ⴑ',
+  'Ⴒ' => 'ⴒ',
+  'Ⴓ' => 'ⴓ',
+  'Ⴔ' => 'ⴔ',
+  'Ⴕ' => 'ⴕ',
+  'Ⴖ' => 'ⴖ',
+  'Ⴗ' => 'ⴗ',
+  'Ⴘ' => 'ⴘ',
+  'Ⴙ' => 'ⴙ',
+  'Ⴚ' => 'ⴚ',
+  'Ⴛ' => 'ⴛ',
+  'Ⴜ' => 'ⴜ',
+  'Ⴝ' => 'ⴝ',
+  'Ⴞ' => 'ⴞ',
+  'Ⴟ' => 'ⴟ',
+  'Ⴠ' => 'ⴠ',
+  'Ⴡ' => 'ⴡ',
+  'Ⴢ' => 'ⴢ',
+  'Ⴣ' => 'ⴣ',
+  'Ⴤ' => 'ⴤ',
+  'Ⴥ' => 'ⴥ',
+  'Ⴧ' => 'ⴧ',
+  'Ⴭ' => 'ⴭ',
+  'Ꭰ' => 'ꭰ',
+  'Ꭱ' => 'ꭱ',
+  'Ꭲ' => 'ꭲ',
+  'Ꭳ' => 'ꭳ',
+  'Ꭴ' => 'ꭴ',
+  'Ꭵ' => 'ꭵ',
+  'Ꭶ' => 'ꭶ',
+  'Ꭷ' => 'ꭷ',
+  'Ꭸ' => 'ꭸ',
+  'Ꭹ' => 'ꭹ',
+  'Ꭺ' => 'ꭺ',
+  'Ꭻ' => 'ꭻ',
+  'Ꭼ' => 'ꭼ',
+  'Ꭽ' => 'ꭽ',
+  'Ꭾ' => 'ꭾ',
+  'Ꭿ' => 'ꭿ',
+  'Ꮀ' => 'ꮀ',
+  'Ꮁ' => 'ꮁ',
+  'Ꮂ' => 'ꮂ',
+  'Ꮃ' => 'ꮃ',
+  'Ꮄ' => 'ꮄ',
+  'Ꮅ' => 'ꮅ',
+  'Ꮆ' => 'ꮆ',
+  'Ꮇ' => 'ꮇ',
+  'Ꮈ' => 'ꮈ',
+  'Ꮉ' => 'ꮉ',
+  'Ꮊ' => 'ꮊ',
+  'Ꮋ' => 'ꮋ',
+  'Ꮌ' => 'ꮌ',
+  'Ꮍ' => 'ꮍ',
+  'Ꮎ' => 'ꮎ',
+  'Ꮏ' => 'ꮏ',
+  'Ꮐ' => 'ꮐ',
+  'Ꮑ' => 'ꮑ',
+  'Ꮒ' => 'ꮒ',
+  'Ꮓ' => 'ꮓ',
+  'Ꮔ' => 'ꮔ',
+  'Ꮕ' => 'ꮕ',
+  'Ꮖ' => 'ꮖ',
+  'Ꮗ' => 'ꮗ',
+  'Ꮘ' => 'ꮘ',
+  'Ꮙ' => 'ꮙ',
+  'Ꮚ' => 'ꮚ',
+  'Ꮛ' => 'ꮛ',
+  'Ꮜ' => 'ꮜ',
+  'Ꮝ' => 'ꮝ',
+  'Ꮞ' => 'ꮞ',
+  'Ꮟ' => 'ꮟ',
+  'Ꮠ' => 'ꮠ',
+  'Ꮡ' => 'ꮡ',
+  'Ꮢ' => 'ꮢ',
+  'Ꮣ' => 'ꮣ',
+  'Ꮤ' => 'ꮤ',
+  'Ꮥ' => 'ꮥ',
+  'Ꮦ' => 'ꮦ',
+  'Ꮧ' => 'ꮧ',
+  'Ꮨ' => 'ꮨ',
+  'Ꮩ' => 'ꮩ',
+  'Ꮪ' => 'ꮪ',
+  'Ꮫ' => 'ꮫ',
+  'Ꮬ' => 'ꮬ',
+  'Ꮭ' => 'ꮭ',
+  'Ꮮ' => 'ꮮ',
+  'Ꮯ' => 'ꮯ',
+  'Ꮰ' => 'ꮰ',
+  'Ꮱ' => 'ꮱ',
+  'Ꮲ' => 'ꮲ',
+  'Ꮳ' => 'ꮳ',
+  'Ꮴ' => 'ꮴ',
+  'Ꮵ' => 'ꮵ',
+  'Ꮶ' => 'ꮶ',
+  'Ꮷ' => 'ꮷ',
+  'Ꮸ' => 'ꮸ',
+  'Ꮹ' => 'ꮹ',
+  'Ꮺ' => 'ꮺ',
+  'Ꮻ' => 'ꮻ',
+  'Ꮼ' => 'ꮼ',
+  'Ꮽ' => 'ꮽ',
+  'Ꮾ' => 'ꮾ',
+  'Ꮿ' => 'ꮿ',
+  'Ᏸ' => 'ᏸ',
+  'Ᏹ' => 'ᏹ',
+  'Ᏺ' => 'ᏺ',
+  'Ᏻ' => 'ᏻ',
+  'Ᏼ' => 'ᏼ',
+  'Ᏽ' => 'ᏽ',
+  'Ა' => 'ა',
+  'Ბ' => 'ბ',
+  'Გ' => 'გ',
+  'Დ' => 'დ',
+  'Ე' => 'ე',
+  'Ვ' => 'ვ',
+  'Ზ' => 'ზ',
+  'Თ' => 'თ',
+  'Ი' => 'ი',
+  'Კ' => 'კ',
+  'Ლ' => 'ლ',
+  'Მ' => 'მ',
+  'Ნ' => 'ნ',
+  'Ო' => 'ო',
+  'Პ' => 'პ',
+  'Ჟ' => 'ჟ',
+  'Რ' => 'რ',
+  'Ს' => 'ს',
+  'Ტ' => 'ტ',
+  'Უ' => 'უ',
+  'Ფ' => 'ფ',
+  'Ქ' => 'ქ',
+  'Ღ' => 'ღ',
+  'Ყ' => 'ყ',
+  'Შ' => 'შ',
+  'Ჩ' => 'ჩ',
+  'Ც' => 'ც',
+  'Ძ' => 'ძ',
+  'Წ' => 'წ',
+  'Ჭ' => 'ჭ',
+  'Ხ' => 'ხ',
+  'Ჯ' => 'ჯ',
+  'Ჰ' => 'ჰ',
+  'Ჱ' => 'ჱ',
+  'Ჲ' => 'ჲ',
+  'Ჳ' => 'ჳ',
+  'Ჴ' => 'ჴ',
+  'Ჵ' => 'ჵ',
+  'Ჶ' => 'ჶ',
+  'Ჷ' => 'ჷ',
+  'Ჸ' => 'ჸ',
+  'Ჹ' => 'ჹ',
+  'Ჺ' => 'ჺ',
+  'Ჽ' => 'ჽ',
+  'Ჾ' => 'ჾ',
+  'Ჿ' => 'ჿ',
+  'Ḁ' => 'ḁ',
+  'Ḃ' => 'ḃ',
+  'Ḅ' => 'ḅ',
+  'Ḇ' => 'ḇ',
+  'Ḉ' => 'ḉ',
+  'Ḋ' => 'ḋ',
+  'Ḍ' => 'ḍ',
+  'Ḏ' => 'ḏ',
+  'Ḑ' => 'ḑ',
+  'Ḓ' => 'ḓ',
+  'Ḕ' => 'ḕ',
+  'Ḗ' => 'ḗ',
+  'Ḙ' => 'ḙ',
+  'Ḛ' => 'ḛ',
+  'Ḝ' => 'ḝ',
+  'Ḟ' => 'ḟ',
+  'Ḡ' => 'ḡ',
+  'Ḣ' => 'ḣ',
+  'Ḥ' => 'ḥ',
+  'Ḧ' => 'ḧ',
+  'Ḩ' => 'ḩ',
+  'Ḫ' => 'ḫ',
+  'Ḭ' => 'ḭ',
+  'Ḯ' => 'ḯ',
+  'Ḱ' => 'ḱ',
+  'Ḳ' => 'ḳ',
+  'Ḵ' => 'ḵ',
+  'Ḷ' => 'ḷ',
+  'Ḹ' => 'ḹ',
+  'Ḻ' => 'ḻ',
+  'Ḽ' => 'ḽ',
+  'Ḿ' => 'ḿ',
+  'Ṁ' => 'ṁ',
+  'Ṃ' => 'ṃ',
+  'Ṅ' => 'ṅ',
+  'Ṇ' => 'ṇ',
+  'Ṉ' => 'ṉ',
+  'Ṋ' => 'ṋ',
+  'Ṍ' => 'ṍ',
+  'Ṏ' => 'ṏ',
+  'Ṑ' => 'ṑ',
+  'Ṓ' => 'ṓ',
+  'Ṕ' => 'ṕ',
+  'Ṗ' => 'ṗ',
+  'Ṙ' => 'ṙ',
+  'Ṛ' => 'ṛ',
+  'Ṝ' => 'ṝ',
+  'Ṟ' => 'ṟ',
+  'Ṡ' => 'ṡ',
+  'Ṣ' => 'ṣ',
+  'Ṥ' => 'ṥ',
+  'Ṧ' => 'ṧ',
+  'Ṩ' => 'ṩ',
+  'Ṫ' => 'ṫ',
+  'Ṭ' => 'ṭ',
+  'Ṯ' => 'ṯ',
+  'Ṱ' => 'ṱ',
+  'Ṳ' => 'ṳ',
+  'Ṵ' => 'ṵ',
+  'Ṷ' => 'ṷ',
+  'Ṹ' => 'ṹ',
+  'Ṻ' => 'ṻ',
+  'Ṽ' => 'ṽ',
+  'Ṿ' => 'ṿ',
+  'Ẁ' => 'ẁ',
+  'Ẃ' => 'ẃ',
+  'Ẅ' => 'ẅ',
+  'Ẇ' => 'ẇ',
+  'Ẉ' => 'ẉ',
+  'Ẋ' => 'ẋ',
+  'Ẍ' => 'ẍ',
+  'Ẏ' => 'ẏ',
+  'Ẑ' => 'ẑ',
+  'Ẓ' => 'ẓ',
+  'Ẕ' => 'ẕ',
+  'ẞ' => 'ß',
+  'Ạ' => 'ạ',
+  'Ả' => 'ả',
+  'Ấ' => 'ấ',
+  'Ầ' => 'ầ',
+  'Ẩ' => 'ẩ',
+  'Ẫ' => 'ẫ',
+  'Ậ' => 'ậ',
+  'Ắ' => 'ắ',
+  'Ằ' => 'ằ',
+  'Ẳ' => 'ẳ',
+  'Ẵ' => 'ẵ',
+  'Ặ' => 'ặ',
+  'Ẹ' => 'ẹ',
+  'Ẻ' => 'ẻ',
+  'Ẽ' => 'ẽ',
+  'Ế' => 'ế',
+  'Ề' => 'ề',
+  'Ể' => 'ể',
+  'Ễ' => 'ễ',
+  'Ệ' => 'ệ',
+  'Ỉ' => 'ỉ',
+  'Ị' => 'ị',
+  'Ọ' => 'ọ',
+  'Ỏ' => 'ỏ',
+  'Ố' => 'ố',
+  'Ồ' => 'ồ',
+  'Ổ' => 'ổ',
+  'Ỗ' => 'ỗ',
+  'Ộ' => 'ộ',
+  'Ớ' => 'ớ',
+  'Ờ' => 'ờ',
+  'Ở' => 'ở',
+  'Ỡ' => 'ỡ',
+  'Ợ' => 'ợ',
+  'Ụ' => 'ụ',
+  'Ủ' => 'ủ',
+  'Ứ' => 'ứ',
+  'Ừ' => 'ừ',
+  'Ử' => 'ử',
+  'Ữ' => 'ữ',
+  'Ự' => 'ự',
+  'Ỳ' => 'ỳ',
+  'Ỵ' => 'ỵ',
+  'Ỷ' => 'ỷ',
+  'Ỹ' => 'ỹ',
+  'Ỻ' => 'ỻ',
+  'Ỽ' => 'ỽ',
+  'Ỿ' => 'ỿ',
+  'Ἀ' => 'ἀ',
+  'Ἁ' => 'ἁ',
+  'Ἂ' => 'ἂ',
+  'Ἃ' => 'ἃ',
+  'Ἄ' => 'ἄ',
+  'Ἅ' => 'ἅ',
+  'Ἆ' => 'ἆ',
+  'Ἇ' => 'ἇ',
+  'Ἐ' => 'ἐ',
+  'Ἑ' => 'ἑ',
+  'Ἒ' => 'ἒ',
+  'Ἓ' => 'ἓ',
+  'Ἔ' => 'ἔ',
+  'Ἕ' => 'ἕ',
+  'Ἠ' => 'ἠ',
+  'Ἡ' => 'ἡ',
+  'Ἢ' => 'ἢ',
+  'Ἣ' => 'ἣ',
+  'Ἤ' => 'ἤ',
+  'Ἥ' => 'ἥ',
+  'Ἦ' => 'ἦ',
+  'Ἧ' => 'ἧ',
+  'Ἰ' => 'ἰ',
+  'Ἱ' => 'ἱ',
+  'Ἲ' => 'ἲ',
+  'Ἳ' => 'ἳ',
+  'Ἴ' => 'ἴ',
+  'Ἵ' => 'ἵ',
+  'Ἶ' => 'ἶ',
+  'Ἷ' => 'ἷ',
+  'Ὀ' => 'ὀ',
+  'Ὁ' => 'ὁ',
+  'Ὂ' => 'ὂ',
+  'Ὃ' => 'ὃ',
+  'Ὄ' => 'ὄ',
+  'Ὅ' => 'ὅ',
+  'Ὑ' => 'ὑ',
+  'Ὓ' => 'ὓ',
+  'Ὕ' => 'ὕ',
+  'Ὗ' => 'ὗ',
+  'Ὠ' => 'ὠ',
+  'Ὡ' => 'ὡ',
+  'Ὢ' => 'ὢ',
+  'Ὣ' => 'ὣ',
+  'Ὤ' => 'ὤ',
+  'Ὥ' => 'ὥ',
+  'Ὦ' => 'ὦ',
+  'Ὧ' => 'ὧ',
+  'ᾈ' => 'ᾀ',
+  'ᾉ' => 'ᾁ',
+  'ᾊ' => 'ᾂ',
+  'ᾋ' => 'ᾃ',
+  'ᾌ' => 'ᾄ',
+  'ᾍ' => 'ᾅ',
+  'ᾎ' => 'ᾆ',
+  'ᾏ' => 'ᾇ',
+  'ᾘ' => 'ᾐ',
+  'ᾙ' => 'ᾑ',
+  'ᾚ' => 'ᾒ',
+  'ᾛ' => 'ᾓ',
+  'ᾜ' => 'ᾔ',
+  'ᾝ' => 'ᾕ',
+  'ᾞ' => 'ᾖ',
+  'ᾟ' => 'ᾗ',
+  'ᾨ' => 'ᾠ',
+  'ᾩ' => 'ᾡ',
+  'ᾪ' => 'ᾢ',
+  'ᾫ' => 'ᾣ',
+  'ᾬ' => 'ᾤ',
+  'ᾭ' => 'ᾥ',
+  'ᾮ' => 'ᾦ',
+  'ᾯ' => 'ᾧ',
+  'Ᾰ' => 'ᾰ',
+  'Ᾱ' => 'ᾱ',
+  'Ὰ' => 'ὰ',
+  'Ά' => 'ά',
+  'ᾼ' => 'ᾳ',
+  'Ὲ' => 'ὲ',
+  'Έ' => 'έ',
+  'Ὴ' => 'ὴ',
+  'Ή' => 'ή',
+  'ῌ' => 'ῃ',
+  'Ῐ' => 'ῐ',
+  'Ῑ' => 'ῑ',
+  'Ὶ' => 'ὶ',
+  'Ί' => 'ί',
+  'Ῠ' => 'ῠ',
+  'Ῡ' => 'ῡ',
+  'Ὺ' => 'ὺ',
+  'Ύ' => 'ύ',
+  'Ῥ' => 'ῥ',
+  'Ὸ' => 'ὸ',
+  'Ό' => 'ό',
+  'Ὼ' => 'ὼ',
+  'Ώ' => 'ώ',
+  'ῼ' => 'ῳ',
+  'Ω' => 'ω',
+  'K' => 'k',
+  'Å' => 'å',
+  'Ⅎ' => 'ⅎ',
+  'Ⅰ' => 'ⅰ',
+  'Ⅱ' => 'ⅱ',
+  'Ⅲ' => 'ⅲ',
+  'Ⅳ' => 'ⅳ',
+  'Ⅴ' => 'ⅴ',
+  'Ⅵ' => 'ⅵ',
+  'Ⅶ' => 'ⅶ',
+  'Ⅷ' => 'ⅷ',
+  'Ⅸ' => 'ⅸ',
+  'Ⅹ' => 'ⅹ',
+  'Ⅺ' => 'ⅺ',
+  'Ⅻ' => 'ⅻ',
+  'Ⅼ' => 'ⅼ',
+  'Ⅽ' => 'ⅽ',
+  'Ⅾ' => 'ⅾ',
+  'Ⅿ' => 'ⅿ',
+  'Ↄ' => 'ↄ',
+  'Ⓐ' => 'ⓐ',
+  'Ⓑ' => 'ⓑ',
+  'Ⓒ' => 'ⓒ',
+  'Ⓓ' => 'ⓓ',
+  'Ⓔ' => 'ⓔ',
+  'Ⓕ' => 'ⓕ',
+  'Ⓖ' => 'ⓖ',
+  'Ⓗ' => 'ⓗ',
+  'Ⓘ' => 'ⓘ',
+  'Ⓙ' => 'ⓙ',
+  'Ⓚ' => 'ⓚ',
+  'Ⓛ' => 'ⓛ',
+  'Ⓜ' => 'ⓜ',
+  'Ⓝ' => 'ⓝ',
+  'Ⓞ' => 'ⓞ',
+  'Ⓟ' => 'ⓟ',
+  'Ⓠ' => 'ⓠ',
+  'Ⓡ' => 'ⓡ',
+  'Ⓢ' => 'ⓢ',
+  'Ⓣ' => 'ⓣ',
+  'Ⓤ' => 'ⓤ',
+  'Ⓥ' => 'ⓥ',
+  'Ⓦ' => 'ⓦ',
+  'Ⓧ' => 'ⓧ',
+  'Ⓨ' => 'ⓨ',
+  'Ⓩ' => 'ⓩ',
+  'Ⰰ' => 'ⰰ',
+  'Ⰱ' => 'ⰱ',
+  'Ⰲ' => 'ⰲ',
+  'Ⰳ' => 'ⰳ',
+  'Ⰴ' => 'ⰴ',
+  'Ⰵ' => 'ⰵ',
+  'Ⰶ' => 'ⰶ',
+  'Ⰷ' => 'ⰷ',
+  'Ⰸ' => 'ⰸ',
+  'Ⰹ' => 'ⰹ',
+  'Ⰺ' => 'ⰺ',
+  'Ⰻ' => 'ⰻ',
+  'Ⰼ' => 'ⰼ',
+  'Ⰽ' => 'ⰽ',
+  'Ⰾ' => 'ⰾ',
+  'Ⰿ' => 'ⰿ',
+  'Ⱀ' => 'ⱀ',
+  'Ⱁ' => 'ⱁ',
+  'Ⱂ' => 'ⱂ',
+  'Ⱃ' => 'ⱃ',
+  'Ⱄ' => 'ⱄ',
+  'Ⱅ' => 'ⱅ',
+  'Ⱆ' => 'ⱆ',
+  'Ⱇ' => 'ⱇ',
+  'Ⱈ' => 'ⱈ',
+  'Ⱉ' => 'ⱉ',
+  'Ⱊ' => 'ⱊ',
+  'Ⱋ' => 'ⱋ',
+  'Ⱌ' => 'ⱌ',
+  'Ⱍ' => 'ⱍ',
+  'Ⱎ' => 'ⱎ',
+  'Ⱏ' => 'ⱏ',
+  'Ⱐ' => 'ⱐ',
+  'Ⱑ' => 'ⱑ',
+  'Ⱒ' => 'ⱒ',
+  'Ⱓ' => 'ⱓ',
+  'Ⱔ' => 'ⱔ',
+  'Ⱕ' => 'ⱕ',
+  'Ⱖ' => 'ⱖ',
+  'Ⱗ' => 'ⱗ',
+  'Ⱘ' => 'ⱘ',
+  'Ⱙ' => 'ⱙ',
+  'Ⱚ' => 'ⱚ',
+  'Ⱛ' => 'ⱛ',
+  'Ⱜ' => 'ⱜ',
+  'Ⱝ' => 'ⱝ',
+  'Ⱞ' => 'ⱞ',
+  'Ⱡ' => 'ⱡ',
+  'Ɫ' => 'ɫ',
+  'Ᵽ' => 'ᵽ',
+  'Ɽ' => 'ɽ',
+  'Ⱨ' => 'ⱨ',
+  'Ⱪ' => 'ⱪ',
+  'Ⱬ' => 'ⱬ',
+  'Ɑ' => 'ɑ',
+  'Ɱ' => 'ɱ',
+  'Ɐ' => 'ɐ',
+  'Ɒ' => 'ɒ',
+  'Ⱳ' => 'ⱳ',
+  'Ⱶ' => 'ⱶ',
+  'Ȿ' => 'ȿ',
+  'Ɀ' => 'ɀ',
+  'Ⲁ' => 'ⲁ',
+  'Ⲃ' => 'ⲃ',
+  'Ⲅ' => 'ⲅ',
+  'Ⲇ' => 'ⲇ',
+  'Ⲉ' => 'ⲉ',
+  'Ⲋ' => 'ⲋ',
+  'Ⲍ' => 'ⲍ',
+  'Ⲏ' => 'ⲏ',
+  'Ⲑ' => 'ⲑ',
+  'Ⲓ' => 'ⲓ',
+  'Ⲕ' => 'ⲕ',
+  'Ⲗ' => 'ⲗ',
+  'Ⲙ' => 'ⲙ',
+  'Ⲛ' => 'ⲛ',
+  'Ⲝ' => 'ⲝ',
+  'Ⲟ' => 'ⲟ',
+  'Ⲡ' => 'ⲡ',
+  'Ⲣ' => 'ⲣ',
+  'Ⲥ' => 'ⲥ',
+  'Ⲧ' => 'ⲧ',
+  'Ⲩ' => 'ⲩ',
+  'Ⲫ' => 'ⲫ',
+  'Ⲭ' => 'ⲭ',
+  'Ⲯ' => 'ⲯ',
+  'Ⲱ' => 'ⲱ',
+  'Ⲳ' => 'ⲳ',
+  'Ⲵ' => 'ⲵ',
+  'Ⲷ' => 'ⲷ',
+  'Ⲹ' => 'ⲹ',
+  'Ⲻ' => 'ⲻ',
+  'Ⲽ' => 'ⲽ',
+  'Ⲿ' => 'ⲿ',
+  'Ⳁ' => 'ⳁ',
+  'Ⳃ' => 'ⳃ',
+  'Ⳅ' => 'ⳅ',
+  'Ⳇ' => 'ⳇ',
+  'Ⳉ' => 'ⳉ',
+  'Ⳋ' => 'ⳋ',
+  'Ⳍ' => 'ⳍ',
+  'Ⳏ' => 'ⳏ',
+  'Ⳑ' => 'ⳑ',
+  'Ⳓ' => 'ⳓ',
+  'Ⳕ' => 'ⳕ',
+  'Ⳗ' => 'ⳗ',
+  'Ⳙ' => 'ⳙ',
+  'Ⳛ' => 'ⳛ',
+  'Ⳝ' => 'ⳝ',
+  'Ⳟ' => 'ⳟ',
+  'Ⳡ' => 'ⳡ',
+  'Ⳣ' => 'ⳣ',
+  'Ⳬ' => 'ⳬ',
+  'Ⳮ' => 'ⳮ',
+  'Ⳳ' => 'ⳳ',
+  'Ꙁ' => 'ꙁ',
+  'Ꙃ' => 'ꙃ',
+  'Ꙅ' => 'ꙅ',
+  'Ꙇ' => 'ꙇ',
+  'Ꙉ' => 'ꙉ',
+  'Ꙋ' => 'ꙋ',
+  'Ꙍ' => 'ꙍ',
+  'Ꙏ' => 'ꙏ',
+  'Ꙑ' => 'ꙑ',
+  'Ꙓ' => 'ꙓ',
+  'Ꙕ' => 'ꙕ',
+  'Ꙗ' => 'ꙗ',
+  'Ꙙ' => 'ꙙ',
+  'Ꙛ' => 'ꙛ',
+  'Ꙝ' => 'ꙝ',
+  'Ꙟ' => 'ꙟ',
+  'Ꙡ' => 'ꙡ',
+  'Ꙣ' => 'ꙣ',
+  'Ꙥ' => 'ꙥ',
+  'Ꙧ' => 'ꙧ',
+  'Ꙩ' => 'ꙩ',
+  'Ꙫ' => 'ꙫ',
+  'Ꙭ' => 'ꙭ',
+  'Ꚁ' => 'ꚁ',
+  'Ꚃ' => 'ꚃ',
+  'Ꚅ' => 'ꚅ',
+  'Ꚇ' => 'ꚇ',
+  'Ꚉ' => 'ꚉ',
+  'Ꚋ' => 'ꚋ',
+  'Ꚍ' => 'ꚍ',
+  'Ꚏ' => 'ꚏ',
+  'Ꚑ' => 'ꚑ',
+  'Ꚓ' => 'ꚓ',
+  'Ꚕ' => 'ꚕ',
+  'Ꚗ' => 'ꚗ',
+  'Ꚙ' => 'ꚙ',
+  'Ꚛ' => 'ꚛ',
+  'Ꜣ' => 'ꜣ',
+  'Ꜥ' => 'ꜥ',
+  'Ꜧ' => 'ꜧ',
+  'Ꜩ' => 'ꜩ',
+  'Ꜫ' => 'ꜫ',
+  'Ꜭ' => 'ꜭ',
+  'Ꜯ' => 'ꜯ',
+  'Ꜳ' => 'ꜳ',
+  'Ꜵ' => 'ꜵ',
+  'Ꜷ' => 'ꜷ',
+  'Ꜹ' => 'ꜹ',
+  'Ꜻ' => 'ꜻ',
+  'Ꜽ' => 'ꜽ',
+  'Ꜿ' => 'ꜿ',
+  'Ꝁ' => 'ꝁ',
+  'Ꝃ' => 'ꝃ',
+  'Ꝅ' => 'ꝅ',
+  'Ꝇ' => 'ꝇ',
+  'Ꝉ' => 'ꝉ',
+  'Ꝋ' => 'ꝋ',
+  'Ꝍ' => 'ꝍ',
+  'Ꝏ' => 'ꝏ',
+  'Ꝑ' => 'ꝑ',
+  'Ꝓ' => 'ꝓ',
+  'Ꝕ' => 'ꝕ',
+  'Ꝗ' => 'ꝗ',
+  'Ꝙ' => 'ꝙ',
+  'Ꝛ' => 'ꝛ',
+  'Ꝝ' => 'ꝝ',
+  'Ꝟ' => 'ꝟ',
+  'Ꝡ' => 'ꝡ',
+  'Ꝣ' => 'ꝣ',
+  'Ꝥ' => 'ꝥ',
+  'Ꝧ' => 'ꝧ',
+  'Ꝩ' => 'ꝩ',
+  'Ꝫ' => 'ꝫ',
+  'Ꝭ' => 'ꝭ',
+  'Ꝯ' => 'ꝯ',
+  'Ꝺ' => 'ꝺ',
+  'Ꝼ' => 'ꝼ',
+  'Ᵹ' => 'ᵹ',
+  'Ꝿ' => 'ꝿ',
+  'Ꞁ' => 'ꞁ',
+  'Ꞃ' => 'ꞃ',
+  'Ꞅ' => 'ꞅ',
+  'Ꞇ' => 'ꞇ',
+  'Ꞌ' => 'ꞌ',
+  'Ɥ' => 'ɥ',
+  'Ꞑ' => 'ꞑ',
+  'Ꞓ' => 'ꞓ',
+  'Ꞗ' => 'ꞗ',
+  'Ꞙ' => 'ꞙ',
+  'Ꞛ' => 'ꞛ',
+  'Ꞝ' => 'ꞝ',
+  'Ꞟ' => 'ꞟ',
+  'Ꞡ' => 'ꞡ',
+  'Ꞣ' => 'ꞣ',
+  'Ꞥ' => 'ꞥ',
+  'Ꞧ' => 'ꞧ',
+  'Ꞩ' => 'ꞩ',
+  'Ɦ' => 'ɦ',
+  'Ɜ' => 'ɜ',
+  'Ɡ' => 'ɡ',
+  'Ɬ' => 'ɬ',
+  'Ɪ' => 'ɪ',
+  'Ʞ' => 'ʞ',
+  'Ʇ' => 'ʇ',
+  'Ʝ' => 'ʝ',
+  'Ꭓ' => 'ꭓ',
+  'Ꞵ' => 'ꞵ',
+  'Ꞷ' => 'ꞷ',
+  'Ꞹ' => 'ꞹ',
+  'Ꞻ' => 'ꞻ',
+  'Ꞽ' => 'ꞽ',
+  'Ꞿ' => 'ꞿ',
+  'Ꟃ' => 'ꟃ',
+  'Ꞔ' => 'ꞔ',
+  'Ʂ' => 'ʂ',
+  'Ᶎ' => 'ᶎ',
+  'Ꟈ' => 'ꟈ',
+  'Ꟊ' => 'ꟊ',
+  'Ꟶ' => 'ꟶ',
+  'A' => 'a',
+  'B' => 'b',
+  'C' => 'c',
+  'D' => 'd',
+  'E' => 'e',
+  'F' => 'f',
+  'G' => 'g',
+  'H' => 'h',
+  'I' => 'i',
+  'J' => 'j',
+  'K' => 'k',
+  'L' => 'l',
+  'M' => 'm',
+  'N' => 'n',
+  'O' => 'o',
+  'P' => 'p',
+  'Q' => 'q',
+  'R' => 'r',
+  'S' => 's',
+  'T' => 't',
+  'U' => 'u',
+  'V' => 'v',
+  'W' => 'w',
+  'X' => 'x',
+  'Y' => 'y',
+  'Z' => 'z',
+  '𐐀' => '𐐨',
+  '𐐁' => '𐐩',
+  '𐐂' => '𐐪',
+  '𐐃' => '𐐫',
+  '𐐄' => '𐐬',
+  '𐐅' => '𐐭',
+  '𐐆' => '𐐮',
+  '𐐇' => '𐐯',
+  '𐐈' => '𐐰',
+  '𐐉' => '𐐱',
+  '𐐊' => '𐐲',
+  '𐐋' => '𐐳',
+  '𐐌' => '𐐴',
+  '𐐍' => '𐐵',
+  '𐐎' => '𐐶',
+  '𐐏' => '𐐷',
+  '𐐐' => '𐐸',
+  '𐐑' => '𐐹',
+  '𐐒' => '𐐺',
+  '𐐓' => '𐐻',
+  '𐐔' => '𐐼',
+  '𐐕' => '𐐽',
+  '𐐖' => '𐐾',
+  '𐐗' => '𐐿',
+  '𐐘' => '𐑀',
+  '𐐙' => '𐑁',
+  '𐐚' => '𐑂',
+  '𐐛' => '𐑃',
+  '𐐜' => '𐑄',
+  '𐐝' => '𐑅',
+  '𐐞' => '𐑆',
+  '𐐟' => '𐑇',
+  '𐐠' => '𐑈',
+  '𐐡' => '𐑉',
+  '𐐢' => '𐑊',
+  '𐐣' => '𐑋',
+  '𐐤' => '𐑌',
+  '𐐥' => '𐑍',
+  '𐐦' => '𐑎',
+  '𐐧' => '𐑏',
+  '𐒰' => '𐓘',
+  '𐒱' => '𐓙',
+  '𐒲' => '𐓚',
+  '𐒳' => '𐓛',
+  '𐒴' => '𐓜',
+  '𐒵' => '𐓝',
+  '𐒶' => '𐓞',
+  '𐒷' => '𐓟',
+  '𐒸' => '𐓠',
+  '𐒹' => '𐓡',
+  '𐒺' => '𐓢',
+  '𐒻' => '𐓣',
+  '𐒼' => '𐓤',
+  '𐒽' => '𐓥',
+  '𐒾' => '𐓦',
+  '𐒿' => '𐓧',
+  '𐓀' => '𐓨',
+  '𐓁' => '𐓩',
+  '𐓂' => '𐓪',
+  '𐓃' => '𐓫',
+  '𐓄' => '𐓬',
+  '𐓅' => '𐓭',
+  '𐓆' => '𐓮',
+  '𐓇' => '𐓯',
+  '𐓈' => '𐓰',
+  '𐓉' => '𐓱',
+  '𐓊' => '𐓲',
+  '𐓋' => '𐓳',
+  '𐓌' => '𐓴',
+  '𐓍' => '𐓵',
+  '𐓎' => '𐓶',
+  '𐓏' => '𐓷',
+  '𐓐' => '𐓸',
+  '𐓑' => '𐓹',
+  '𐓒' => '𐓺',
+  '𐓓' => '𐓻',
+  '𐲀' => '𐳀',
+  '𐲁' => '𐳁',
+  '𐲂' => '𐳂',
+  '𐲃' => '𐳃',
+  '𐲄' => '𐳄',
+  '𐲅' => '𐳅',
+  '𐲆' => '𐳆',
+  '𐲇' => '𐳇',
+  '𐲈' => '𐳈',
+  '𐲉' => '𐳉',
+  '𐲊' => '𐳊',
+  '𐲋' => '𐳋',
+  '𐲌' => '𐳌',
+  '𐲍' => '𐳍',
+  '𐲎' => '𐳎',
+  '𐲏' => '𐳏',
+  '𐲐' => '𐳐',
+  '𐲑' => '𐳑',
+  '𐲒' => '𐳒',
+  '𐲓' => '𐳓',
+  '𐲔' => '𐳔',
+  '𐲕' => '𐳕',
+  '𐲖' => '𐳖',
+  '𐲗' => '𐳗',
+  '𐲘' => '𐳘',
+  '𐲙' => '𐳙',
+  '𐲚' => '𐳚',
+  '𐲛' => '𐳛',
+  '𐲜' => '𐳜',
+  '𐲝' => '𐳝',
+  '𐲞' => '𐳞',
+  '𐲟' => '𐳟',
+  '𐲠' => '𐳠',
+  '𐲡' => '𐳡',
+  '𐲢' => '𐳢',
+  '𐲣' => '𐳣',
+  '𐲤' => '𐳤',
+  '𐲥' => '𐳥',
+  '𐲦' => '𐳦',
+  '𐲧' => '𐳧',
+  '𐲨' => '𐳨',
+  '𐲩' => '𐳩',
+  '𐲪' => '𐳪',
+  '𐲫' => '𐳫',
+  '𐲬' => '𐳬',
+  '𐲭' => '𐳭',
+  '𐲮' => '𐳮',
+  '𐲯' => '𐳯',
+  '𐲰' => '𐳰',
+  '𐲱' => '𐳱',
+  '𐲲' => '𐳲',
+  '𑢠' => '𑣀',
+  '𑢡' => '𑣁',
+  '𑢢' => '𑣂',
+  '𑢣' => '𑣃',
+  '𑢤' => '𑣄',
+  '𑢥' => '𑣅',
+  '𑢦' => '𑣆',
+  '𑢧' => '𑣇',
+  '𑢨' => '𑣈',
+  '𑢩' => '𑣉',
+  '𑢪' => '𑣊',
+  '𑢫' => '𑣋',
+  '𑢬' => '𑣌',
+  '𑢭' => '𑣍',
+  '𑢮' => '𑣎',
+  '𑢯' => '𑣏',
+  '𑢰' => '𑣐',
+  '𑢱' => '𑣑',
+  '𑢲' => '𑣒',
+  '𑢳' => '𑣓',
+  '𑢴' => '𑣔',
+  '𑢵' => '𑣕',
+  '𑢶' => '𑣖',
+  '𑢷' => '𑣗',
+  '𑢸' => '𑣘',
+  '𑢹' => '𑣙',
+  '𑢺' => '𑣚',
+  '𑢻' => '𑣛',
+  '𑢼' => '𑣜',
+  '𑢽' => '𑣝',
+  '𑢾' => '𑣞',
+  '𑢿' => '𑣟',
+  '𖹀' => '𖹠',
+  '𖹁' => '𖹡',
+  '𖹂' => '𖹢',
+  '𖹃' => '𖹣',
+  '𖹄' => '𖹤',
+  '𖹅' => '𖹥',
+  '𖹆' => '𖹦',
+  '𖹇' => '𖹧',
+  '𖹈' => '𖹨',
+  '𖹉' => '𖹩',
+  '𖹊' => '𖹪',
+  '𖹋' => '𖹫',
+  '𖹌' => '𖹬',
+  '𖹍' => '𖹭',
+  '𖹎' => '𖹮',
+  '𖹏' => '𖹯',
+  '𖹐' => '𖹰',
+  '𖹑' => '𖹱',
+  '𖹒' => '𖹲',
+  '𖹓' => '𖹳',
+  '𖹔' => '𖹴',
+  '𖹕' => '𖹵',
+  '𖹖' => '𖹶',
+  '𖹗' => '𖹷',
+  '𖹘' => '𖹸',
+  '𖹙' => '𖹹',
+  '𖹚' => '𖹺',
+  '𖹛' => '𖹻',
+  '𖹜' => '𖹼',
+  '𖹝' => '𖹽',
+  '𖹞' => '𖹾',
+  '𖹟' => '𖹿',
+  '𞤀' => '𞤢',
+  '𞤁' => '𞤣',
+  '𞤂' => '𞤤',
+  '𞤃' => '𞤥',
+  '𞤄' => '𞤦',
+  '𞤅' => '𞤧',
+  '𞤆' => '𞤨',
+  '𞤇' => '𞤩',
+  '𞤈' => '𞤪',
+  '𞤉' => '𞤫',
+  '𞤊' => '𞤬',
+  '𞤋' => '𞤭',
+  '𞤌' => '𞤮',
+  '𞤍' => '𞤯',
+  '𞤎' => '𞤰',
+  '𞤏' => '𞤱',
+  '𞤐' => '𞤲',
+  '𞤑' => '𞤳',
+  '𞤒' => '𞤴',
+  '𞤓' => '𞤵',
+  '𞤔' => '𞤶',
+  '𞤕' => '𞤷',
+  '𞤖' => '𞤸',
+  '𞤗' => '𞤹',
+  '𞤘' => '𞤺',
+  '𞤙' => '𞤻',
+  '𞤚' => '𞤼',
+  '𞤛' => '𞤽',
+  '𞤜' => '𞤾',
+  '𞤝' => '𞤿',
+  '𞤞' => '𞥀',
+  '𞤟' => '𞥁',
+  '𞤠' => '𞥂',
+  '𞤡' => '𞥃',
+);
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
new file mode 100644
index 0000000..2a8f6e7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
@@ -0,0 +1,5 @@
+<?php
+
+// from Case_Ignorable in https://unicode.org/Public/UNIDATA/DerivedCoreProperties.txt
+
+return '/(?<![\x{0027}\x{002E}\x{003A}\x{005E}\x{0060}\x{00A8}\x{00AD}\x{00AF}\x{00B4}\x{00B7}\x{00B8}\x{02B0}-\x{02C1}\x{02C2}-\x{02C5}\x{02C6}-\x{02D1}\x{02D2}-\x{02DF}\x{02E0}-\x{02E4}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EE}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037A}\x{0384}-\x{0385}\x{0387}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0559}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{05F4}\x{0600}-\x{0605}\x{0610}-\x{061A}\x{061C}\x{0640}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DD}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07FA}\x{07FD}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0971}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E46}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EB9}\x{0EBB}-\x{0EBC}\x{0EC6}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{10FC}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17D7}\x{17DD}\x{180B}-\x{180D}\x{180E}\x{1843}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AA7}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1C78}-\x{1C7D}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1D2C}-\x{1D6A}\x{1D78}\x{1D9B}-\x{1DBF}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200F}\x{2018}\x{2019}\x{2024}\x{2027}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{2066}-\x{206F}\x{2071}\x{207F}\x{2090}-\x{209C}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2C7C}-\x{2C7D}\x{2CEF}-\x{2CF1}\x{2D6F}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E2F}\x{3005}\x{302A}-\x{302D}\x{3031}-\x{3035}\x{303B}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{309D}-\x{309E}\x{30FC}-\x{30FE}\x{A015}\x{A4F8}-\x{A4FD}\x{A60C}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A67F}\x{A69C}-\x{A69D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A770}\x{A788}\x{A789}-\x{A78A}\x{A7F8}-\x{A7F9}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}\x{A9CF}\x{A9E5}\x{A9E6}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA70}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AADD}\x{AAEC}-\x{AAED}\x{AAF3}-\x{AAF4}\x{AAF6}\x{AB5B}\x{AB5C}-\x{AB5F}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FBB2}-\x{FBC1}\x{FE00}-\x{FE0F}\x{FE13}\x{FE20}-\x{FE2F}\x{FE52}\x{FE55}\x{FEFF}\x{FF07}\x{FF0E}\x{FF1A}\x{FF3E}\x{FF40}\x{FF70}\x{FF9E}-\x{FF9F}\x{FFE3}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{110BD}\x{110CD}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16B40}-\x{16B43}\x{16F8F}-\x{16F92}\x{16F93}-\x{16F9F}\x{16FE0}-\x{16FE1}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1F3FB}-\x{1F3FF}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}])(\pL)(\pL*+)/u';
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
new file mode 100644
index 0000000..56b9cb8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php
@@ -0,0 +1,1489 @@
+<?php
+
+return array (
+  'a' => 'A',
+  'b' => 'B',
+  'c' => 'C',
+  'd' => 'D',
+  'e' => 'E',
+  'f' => 'F',
+  'g' => 'G',
+  'h' => 'H',
+  'i' => 'I',
+  'j' => 'J',
+  'k' => 'K',
+  'l' => 'L',
+  'm' => 'M',
+  'n' => 'N',
+  'o' => 'O',
+  'p' => 'P',
+  'q' => 'Q',
+  'r' => 'R',
+  's' => 'S',
+  't' => 'T',
+  'u' => 'U',
+  'v' => 'V',
+  'w' => 'W',
+  'x' => 'X',
+  'y' => 'Y',
+  'z' => 'Z',
+  'µ' => 'Μ',
+  'à' => 'À',
+  'á' => 'Á',
+  'â' => 'Â',
+  'ã' => 'Ã',
+  'ä' => 'Ä',
+  'å' => 'Å',
+  'æ' => 'Æ',
+  'ç' => 'Ç',
+  'è' => 'È',
+  'é' => 'É',
+  'ê' => 'Ê',
+  'ë' => 'Ë',
+  'ì' => 'Ì',
+  'í' => 'Í',
+  'î' => 'Î',
+  'ï' => 'Ï',
+  'ð' => 'Ð',
+  'ñ' => 'Ñ',
+  'ò' => 'Ò',
+  'ó' => 'Ó',
+  'ô' => 'Ô',
+  'õ' => 'Õ',
+  'ö' => 'Ö',
+  'ø' => 'Ø',
+  'ù' => 'Ù',
+  'ú' => 'Ú',
+  'û' => 'Û',
+  'ü' => 'Ü',
+  'ý' => 'Ý',
+  'þ' => 'Þ',
+  'ÿ' => 'Ÿ',
+  'ā' => 'Ā',
+  'ă' => 'Ă',
+  'ą' => 'Ą',
+  'ć' => 'Ć',
+  'ĉ' => 'Ĉ',
+  'ċ' => 'Ċ',
+  'č' => 'Č',
+  'ď' => 'Ď',
+  'đ' => 'Đ',
+  'ē' => 'Ē',
+  'ĕ' => 'Ĕ',
+  'ė' => 'Ė',
+  'ę' => 'Ę',
+  'ě' => 'Ě',
+  'ĝ' => 'Ĝ',
+  'ğ' => 'Ğ',
+  'ġ' => 'Ġ',
+  'ģ' => 'Ģ',
+  'ĥ' => 'Ĥ',
+  'ħ' => 'Ħ',
+  'ĩ' => 'Ĩ',
+  'ī' => 'Ī',
+  'ĭ' => 'Ĭ',
+  'į' => 'Į',
+  'ı' => 'I',
+  'ij' => 'IJ',
+  'ĵ' => 'Ĵ',
+  'ķ' => 'Ķ',
+  'ĺ' => 'Ĺ',
+  'ļ' => 'Ļ',
+  'ľ' => 'Ľ',
+  'ŀ' => 'Ŀ',
+  'ł' => 'Ł',
+  'ń' => 'Ń',
+  'ņ' => 'Ņ',
+  'ň' => 'Ň',
+  'ŋ' => 'Ŋ',
+  'ō' => 'Ō',
+  'ŏ' => 'Ŏ',
+  'ő' => 'Ő',
+  'œ' => 'Œ',
+  'ŕ' => 'Ŕ',
+  'ŗ' => 'Ŗ',
+  'ř' => 'Ř',
+  'ś' => 'Ś',
+  'ŝ' => 'Ŝ',
+  'ş' => 'Ş',
+  'š' => 'Š',
+  'ţ' => 'Ţ',
+  'ť' => 'Ť',
+  'ŧ' => 'Ŧ',
+  'ũ' => 'Ũ',
+  'ū' => 'Ū',
+  'ŭ' => 'Ŭ',
+  'ů' => 'Ů',
+  'ű' => 'Ű',
+  'ų' => 'Ų',
+  'ŵ' => 'Ŵ',
+  'ŷ' => 'Ŷ',
+  'ź' => 'Ź',
+  'ż' => 'Ż',
+  'ž' => 'Ž',
+  'ſ' => 'S',
+  'ƀ' => 'Ƀ',
+  'ƃ' => 'Ƃ',
+  'ƅ' => 'Ƅ',
+  'ƈ' => 'Ƈ',
+  'ƌ' => 'Ƌ',
+  'ƒ' => 'Ƒ',
+  'ƕ' => 'Ƕ',
+  'ƙ' => 'Ƙ',
+  'ƚ' => 'Ƚ',
+  'ƞ' => 'Ƞ',
+  'ơ' => 'Ơ',
+  'ƣ' => 'Ƣ',
+  'ƥ' => 'Ƥ',
+  'ƨ' => 'Ƨ',
+  'ƭ' => 'Ƭ',
+  'ư' => 'Ư',
+  'ƴ' => 'Ƴ',
+  'ƶ' => 'Ƶ',
+  'ƹ' => 'Ƹ',
+  'ƽ' => 'Ƽ',
+  'ƿ' => 'Ƿ',
+  'Dž' => 'DŽ',
+  'dž' => 'DŽ',
+  'Lj' => 'LJ',
+  'lj' => 'LJ',
+  'Nj' => 'NJ',
+  'nj' => 'NJ',
+  'ǎ' => 'Ǎ',
+  'ǐ' => 'Ǐ',
+  'ǒ' => 'Ǒ',
+  'ǔ' => 'Ǔ',
+  'ǖ' => 'Ǖ',
+  'ǘ' => 'Ǘ',
+  'ǚ' => 'Ǚ',
+  'ǜ' => 'Ǜ',
+  'ǝ' => 'Ǝ',
+  'ǟ' => 'Ǟ',
+  'ǡ' => 'Ǡ',
+  'ǣ' => 'Ǣ',
+  'ǥ' => 'Ǥ',
+  'ǧ' => 'Ǧ',
+  'ǩ' => 'Ǩ',
+  'ǫ' => 'Ǫ',
+  'ǭ' => 'Ǭ',
+  'ǯ' => 'Ǯ',
+  'Dz' => 'DZ',
+  'dz' => 'DZ',
+  'ǵ' => 'Ǵ',
+  'ǹ' => 'Ǹ',
+  'ǻ' => 'Ǻ',
+  'ǽ' => 'Ǽ',
+  'ǿ' => 'Ǿ',
+  'ȁ' => 'Ȁ',
+  'ȃ' => 'Ȃ',
+  'ȅ' => 'Ȅ',
+  'ȇ' => 'Ȇ',
+  'ȉ' => 'Ȉ',
+  'ȋ' => 'Ȋ',
+  'ȍ' => 'Ȍ',
+  'ȏ' => 'Ȏ',
+  'ȑ' => 'Ȑ',
+  'ȓ' => 'Ȓ',
+  'ȕ' => 'Ȕ',
+  'ȗ' => 'Ȗ',
+  'ș' => 'Ș',
+  'ț' => 'Ț',
+  'ȝ' => 'Ȝ',
+  'ȟ' => 'Ȟ',
+  'ȣ' => 'Ȣ',
+  'ȥ' => 'Ȥ',
+  'ȧ' => 'Ȧ',
+  'ȩ' => 'Ȩ',
+  'ȫ' => 'Ȫ',
+  'ȭ' => 'Ȭ',
+  'ȯ' => 'Ȯ',
+  'ȱ' => 'Ȱ',
+  'ȳ' => 'Ȳ',
+  'ȼ' => 'Ȼ',
+  'ȿ' => 'Ȿ',
+  'ɀ' => 'Ɀ',
+  'ɂ' => 'Ɂ',
+  'ɇ' => 'Ɇ',
+  'ɉ' => 'Ɉ',
+  'ɋ' => 'Ɋ',
+  'ɍ' => 'Ɍ',
+  'ɏ' => 'Ɏ',
+  'ɐ' => 'Ɐ',
+  'ɑ' => 'Ɑ',
+  'ɒ' => 'Ɒ',
+  'ɓ' => 'Ɓ',
+  'ɔ' => 'Ɔ',
+  'ɖ' => 'Ɖ',
+  'ɗ' => 'Ɗ',
+  'ə' => 'Ə',
+  'ɛ' => 'Ɛ',
+  'ɜ' => 'Ɜ',
+  'ɠ' => 'Ɠ',
+  'ɡ' => 'Ɡ',
+  'ɣ' => 'Ɣ',
+  'ɥ' => 'Ɥ',
+  'ɦ' => 'Ɦ',
+  'ɨ' => 'Ɨ',
+  'ɩ' => 'Ɩ',
+  'ɪ' => 'Ɪ',
+  'ɫ' => 'Ɫ',
+  'ɬ' => 'Ɬ',
+  'ɯ' => 'Ɯ',
+  'ɱ' => 'Ɱ',
+  'ɲ' => 'Ɲ',
+  'ɵ' => 'Ɵ',
+  'ɽ' => 'Ɽ',
+  'ʀ' => 'Ʀ',
+  'ʂ' => 'Ʂ',
+  'ʃ' => 'Ʃ',
+  'ʇ' => 'Ʇ',
+  'ʈ' => 'Ʈ',
+  'ʉ' => 'Ʉ',
+  'ʊ' => 'Ʊ',
+  'ʋ' => 'Ʋ',
+  'ʌ' => 'Ʌ',
+  'ʒ' => 'Ʒ',
+  'ʝ' => 'Ʝ',
+  'ʞ' => 'Ʞ',
+  'ͅ' => 'Ι',
+  'ͱ' => 'Ͱ',
+  'ͳ' => 'Ͳ',
+  'ͷ' => 'Ͷ',
+  'ͻ' => 'Ͻ',
+  'ͼ' => 'Ͼ',
+  'ͽ' => 'Ͽ',
+  'ά' => 'Ά',
+  'έ' => 'Έ',
+  'ή' => 'Ή',
+  'ί' => 'Ί',
+  'α' => 'Α',
+  'β' => 'Β',
+  'γ' => 'Γ',
+  'δ' => 'Δ',
+  'ε' => 'Ε',
+  'ζ' => 'Ζ',
+  'η' => 'Η',
+  'θ' => 'Θ',
+  'ι' => 'Ι',
+  'κ' => 'Κ',
+  'λ' => 'Λ',
+  'μ' => 'Μ',
+  'ν' => 'Ν',
+  'ξ' => 'Ξ',
+  'ο' => 'Ο',
+  'π' => 'Π',
+  'ρ' => 'Ρ',
+  'ς' => 'Σ',
+  'σ' => 'Σ',
+  'τ' => 'Τ',
+  'υ' => 'Υ',
+  'φ' => 'Φ',
+  'χ' => 'Χ',
+  'ψ' => 'Ψ',
+  'ω' => 'Ω',
+  'ϊ' => 'Ϊ',
+  'ϋ' => 'Ϋ',
+  'ό' => 'Ό',
+  'ύ' => 'Ύ',
+  'ώ' => 'Ώ',
+  'ϐ' => 'Β',
+  'ϑ' => 'Θ',
+  'ϕ' => 'Φ',
+  'ϖ' => 'Π',
+  'ϗ' => 'Ϗ',
+  'ϙ' => 'Ϙ',
+  'ϛ' => 'Ϛ',
+  'ϝ' => 'Ϝ',
+  'ϟ' => 'Ϟ',
+  'ϡ' => 'Ϡ',
+  'ϣ' => 'Ϣ',
+  'ϥ' => 'Ϥ',
+  'ϧ' => 'Ϧ',
+  'ϩ' => 'Ϩ',
+  'ϫ' => 'Ϫ',
+  'ϭ' => 'Ϭ',
+  'ϯ' => 'Ϯ',
+  'ϰ' => 'Κ',
+  'ϱ' => 'Ρ',
+  'ϲ' => 'Ϲ',
+  'ϳ' => 'Ϳ',
+  'ϵ' => 'Ε',
+  'ϸ' => 'Ϸ',
+  'ϻ' => 'Ϻ',
+  'а' => 'А',
+  'б' => 'Б',
+  'в' => 'В',
+  'г' => 'Г',
+  'д' => 'Д',
+  'е' => 'Е',
+  'ж' => 'Ж',
+  'з' => 'З',
+  'и' => 'И',
+  'й' => 'Й',
+  'к' => 'К',
+  'л' => 'Л',
+  'м' => 'М',
+  'н' => 'Н',
+  'о' => 'О',
+  'п' => 'П',
+  'р' => 'Р',
+  'с' => 'С',
+  'т' => 'Т',
+  'у' => 'У',
+  'ф' => 'Ф',
+  'х' => 'Х',
+  'ц' => 'Ц',
+  'ч' => 'Ч',
+  'ш' => 'Ш',
+  'щ' => 'Щ',
+  'ъ' => 'Ъ',
+  'ы' => 'Ы',
+  'ь' => 'Ь',
+  'э' => 'Э',
+  'ю' => 'Ю',
+  'я' => 'Я',
+  'ѐ' => 'Ѐ',
+  'ё' => 'Ё',
+  'ђ' => 'Ђ',
+  'ѓ' => 'Ѓ',
+  'є' => 'Є',
+  'ѕ' => 'Ѕ',
+  'і' => 'І',
+  'ї' => 'Ї',
+  'ј' => 'Ј',
+  'љ' => 'Љ',
+  'њ' => 'Њ',
+  'ћ' => 'Ћ',
+  'ќ' => 'Ќ',
+  'ѝ' => 'Ѝ',
+  'ў' => 'Ў',
+  'џ' => 'Џ',
+  'ѡ' => 'Ѡ',
+  'ѣ' => 'Ѣ',
+  'ѥ' => 'Ѥ',
+  'ѧ' => 'Ѧ',
+  'ѩ' => 'Ѩ',
+  'ѫ' => 'Ѫ',
+  'ѭ' => 'Ѭ',
+  'ѯ' => 'Ѯ',
+  'ѱ' => 'Ѱ',
+  'ѳ' => 'Ѳ',
+  'ѵ' => 'Ѵ',
+  'ѷ' => 'Ѷ',
+  'ѹ' => 'Ѹ',
+  'ѻ' => 'Ѻ',
+  'ѽ' => 'Ѽ',
+  'ѿ' => 'Ѿ',
+  'ҁ' => 'Ҁ',
+  'ҋ' => 'Ҋ',
+  'ҍ' => 'Ҍ',
+  'ҏ' => 'Ҏ',
+  'ґ' => 'Ґ',
+  'ғ' => 'Ғ',
+  'ҕ' => 'Ҕ',
+  'җ' => 'Җ',
+  'ҙ' => 'Ҙ',
+  'қ' => 'Қ',
+  'ҝ' => 'Ҝ',
+  'ҟ' => 'Ҟ',
+  'ҡ' => 'Ҡ',
+  'ң' => 'Ң',
+  'ҥ' => 'Ҥ',
+  'ҧ' => 'Ҧ',
+  'ҩ' => 'Ҩ',
+  'ҫ' => 'Ҫ',
+  'ҭ' => 'Ҭ',
+  'ү' => 'Ү',
+  'ұ' => 'Ұ',
+  'ҳ' => 'Ҳ',
+  'ҵ' => 'Ҵ',
+  'ҷ' => 'Ҷ',
+  'ҹ' => 'Ҹ',
+  'һ' => 'Һ',
+  'ҽ' => 'Ҽ',
+  'ҿ' => 'Ҿ',
+  'ӂ' => 'Ӂ',
+  'ӄ' => 'Ӄ',
+  'ӆ' => 'Ӆ',
+  'ӈ' => 'Ӈ',
+  'ӊ' => 'Ӊ',
+  'ӌ' => 'Ӌ',
+  'ӎ' => 'Ӎ',
+  'ӏ' => 'Ӏ',
+  'ӑ' => 'Ӑ',
+  'ӓ' => 'Ӓ',
+  'ӕ' => 'Ӕ',
+  'ӗ' => 'Ӗ',
+  'ә' => 'Ә',
+  'ӛ' => 'Ӛ',
+  'ӝ' => 'Ӝ',
+  'ӟ' => 'Ӟ',
+  'ӡ' => 'Ӡ',
+  'ӣ' => 'Ӣ',
+  'ӥ' => 'Ӥ',
+  'ӧ' => 'Ӧ',
+  'ө' => 'Ө',
+  'ӫ' => 'Ӫ',
+  'ӭ' => 'Ӭ',
+  'ӯ' => 'Ӯ',
+  'ӱ' => 'Ӱ',
+  'ӳ' => 'Ӳ',
+  'ӵ' => 'Ӵ',
+  'ӷ' => 'Ӷ',
+  'ӹ' => 'Ӹ',
+  'ӻ' => 'Ӻ',
+  'ӽ' => 'Ӽ',
+  'ӿ' => 'Ӿ',
+  'ԁ' => 'Ԁ',
+  'ԃ' => 'Ԃ',
+  'ԅ' => 'Ԅ',
+  'ԇ' => 'Ԇ',
+  'ԉ' => 'Ԉ',
+  'ԋ' => 'Ԋ',
+  'ԍ' => 'Ԍ',
+  'ԏ' => 'Ԏ',
+  'ԑ' => 'Ԑ',
+  'ԓ' => 'Ԓ',
+  'ԕ' => 'Ԕ',
+  'ԗ' => 'Ԗ',
+  'ԙ' => 'Ԙ',
+  'ԛ' => 'Ԛ',
+  'ԝ' => 'Ԝ',
+  'ԟ' => 'Ԟ',
+  'ԡ' => 'Ԡ',
+  'ԣ' => 'Ԣ',
+  'ԥ' => 'Ԥ',
+  'ԧ' => 'Ԧ',
+  'ԩ' => 'Ԩ',
+  'ԫ' => 'Ԫ',
+  'ԭ' => 'Ԭ',
+  'ԯ' => 'Ԯ',
+  'ա' => 'Ա',
+  'բ' => 'Բ',
+  'գ' => 'Գ',
+  'դ' => 'Դ',
+  'ե' => 'Ե',
+  'զ' => 'Զ',
+  'է' => 'Է',
+  'ը' => 'Ը',
+  'թ' => 'Թ',
+  'ժ' => 'Ժ',
+  'ի' => 'Ի',
+  'լ' => 'Լ',
+  'խ' => 'Խ',
+  'ծ' => 'Ծ',
+  'կ' => 'Կ',
+  'հ' => 'Հ',
+  'ձ' => 'Ձ',
+  'ղ' => 'Ղ',
+  'ճ' => 'Ճ',
+  'մ' => 'Մ',
+  'յ' => 'Յ',
+  'ն' => 'Ն',
+  'շ' => 'Շ',
+  'ո' => 'Ո',
+  'չ' => 'Չ',
+  'պ' => 'Պ',
+  'ջ' => 'Ջ',
+  'ռ' => 'Ռ',
+  'ս' => 'Ս',
+  'վ' => 'Վ',
+  'տ' => 'Տ',
+  'ր' => 'Ր',
+  'ց' => 'Ց',
+  'ւ' => 'Ւ',
+  'փ' => 'Փ',
+  'ք' => 'Ք',
+  'օ' => 'Օ',
+  'ֆ' => 'Ֆ',
+  'ა' => 'Ა',
+  'ბ' => 'Ბ',
+  'გ' => 'Გ',
+  'დ' => 'Დ',
+  'ე' => 'Ე',
+  'ვ' => 'Ვ',
+  'ზ' => 'Ზ',
+  'თ' => 'Თ',
+  'ი' => 'Ი',
+  'კ' => 'Კ',
+  'ლ' => 'Ლ',
+  'მ' => 'Მ',
+  'ნ' => 'Ნ',
+  'ო' => 'Ო',
+  'პ' => 'Პ',
+  'ჟ' => 'Ჟ',
+  'რ' => 'Რ',
+  'ს' => 'Ს',
+  'ტ' => 'Ტ',
+  'უ' => 'Უ',
+  'ფ' => 'Ფ',
+  'ქ' => 'Ქ',
+  'ღ' => 'Ღ',
+  'ყ' => 'Ყ',
+  'შ' => 'Შ',
+  'ჩ' => 'Ჩ',
+  'ც' => 'Ც',
+  'ძ' => 'Ძ',
+  'წ' => 'Წ',
+  'ჭ' => 'Ჭ',
+  'ხ' => 'Ხ',
+  'ჯ' => 'Ჯ',
+  'ჰ' => 'Ჰ',
+  'ჱ' => 'Ჱ',
+  'ჲ' => 'Ჲ',
+  'ჳ' => 'Ჳ',
+  'ჴ' => 'Ჴ',
+  'ჵ' => 'Ჵ',
+  'ჶ' => 'Ჶ',
+  'ჷ' => 'Ჷ',
+  'ჸ' => 'Ჸ',
+  'ჹ' => 'Ჹ',
+  'ჺ' => 'Ჺ',
+  'ჽ' => 'Ჽ',
+  'ჾ' => 'Ჾ',
+  'ჿ' => 'Ჿ',
+  'ᏸ' => 'Ᏸ',
+  'ᏹ' => 'Ᏹ',
+  'ᏺ' => 'Ᏺ',
+  'ᏻ' => 'Ᏻ',
+  'ᏼ' => 'Ᏼ',
+  'ᏽ' => 'Ᏽ',
+  'ᲀ' => 'В',
+  'ᲁ' => 'Д',
+  'ᲂ' => 'О',
+  'ᲃ' => 'С',
+  'ᲄ' => 'Т',
+  'ᲅ' => 'Т',
+  'ᲆ' => 'Ъ',
+  'ᲇ' => 'Ѣ',
+  'ᲈ' => 'Ꙋ',
+  'ᵹ' => 'Ᵹ',
+  'ᵽ' => 'Ᵽ',
+  'ᶎ' => 'Ᶎ',
+  'ḁ' => 'Ḁ',
+  'ḃ' => 'Ḃ',
+  'ḅ' => 'Ḅ',
+  'ḇ' => 'Ḇ',
+  'ḉ' => 'Ḉ',
+  'ḋ' => 'Ḋ',
+  'ḍ' => 'Ḍ',
+  'ḏ' => 'Ḏ',
+  'ḑ' => 'Ḑ',
+  'ḓ' => 'Ḓ',
+  'ḕ' => 'Ḕ',
+  'ḗ' => 'Ḗ',
+  'ḙ' => 'Ḙ',
+  'ḛ' => 'Ḛ',
+  'ḝ' => 'Ḝ',
+  'ḟ' => 'Ḟ',
+  'ḡ' => 'Ḡ',
+  'ḣ' => 'Ḣ',
+  'ḥ' => 'Ḥ',
+  'ḧ' => 'Ḧ',
+  'ḩ' => 'Ḩ',
+  'ḫ' => 'Ḫ',
+  'ḭ' => 'Ḭ',
+  'ḯ' => 'Ḯ',
+  'ḱ' => 'Ḱ',
+  'ḳ' => 'Ḳ',
+  'ḵ' => 'Ḵ',
+  'ḷ' => 'Ḷ',
+  'ḹ' => 'Ḹ',
+  'ḻ' => 'Ḻ',
+  'ḽ' => 'Ḽ',
+  'ḿ' => 'Ḿ',
+  'ṁ' => 'Ṁ',
+  'ṃ' => 'Ṃ',
+  'ṅ' => 'Ṅ',
+  'ṇ' => 'Ṇ',
+  'ṉ' => 'Ṉ',
+  'ṋ' => 'Ṋ',
+  'ṍ' => 'Ṍ',
+  'ṏ' => 'Ṏ',
+  'ṑ' => 'Ṑ',
+  'ṓ' => 'Ṓ',
+  'ṕ' => 'Ṕ',
+  'ṗ' => 'Ṗ',
+  'ṙ' => 'Ṙ',
+  'ṛ' => 'Ṛ',
+  'ṝ' => 'Ṝ',
+  'ṟ' => 'Ṟ',
+  'ṡ' => 'Ṡ',
+  'ṣ' => 'Ṣ',
+  'ṥ' => 'Ṥ',
+  'ṧ' => 'Ṧ',
+  'ṩ' => 'Ṩ',
+  'ṫ' => 'Ṫ',
+  'ṭ' => 'Ṭ',
+  'ṯ' => 'Ṯ',
+  'ṱ' => 'Ṱ',
+  'ṳ' => 'Ṳ',
+  'ṵ' => 'Ṵ',
+  'ṷ' => 'Ṷ',
+  'ṹ' => 'Ṹ',
+  'ṻ' => 'Ṻ',
+  'ṽ' => 'Ṽ',
+  'ṿ' => 'Ṿ',
+  'ẁ' => 'Ẁ',
+  'ẃ' => 'Ẃ',
+  'ẅ' => 'Ẅ',
+  'ẇ' => 'Ẇ',
+  'ẉ' => 'Ẉ',
+  'ẋ' => 'Ẋ',
+  'ẍ' => 'Ẍ',
+  'ẏ' => 'Ẏ',
+  'ẑ' => 'Ẑ',
+  'ẓ' => 'Ẓ',
+  'ẕ' => 'Ẕ',
+  'ẛ' => 'Ṡ',
+  'ạ' => 'Ạ',
+  'ả' => 'Ả',
+  'ấ' => 'Ấ',
+  'ầ' => 'Ầ',
+  'ẩ' => 'Ẩ',
+  'ẫ' => 'Ẫ',
+  'ậ' => 'Ậ',
+  'ắ' => 'Ắ',
+  'ằ' => 'Ằ',
+  'ẳ' => 'Ẳ',
+  'ẵ' => 'Ẵ',
+  'ặ' => 'Ặ',
+  'ẹ' => 'Ẹ',
+  'ẻ' => 'Ẻ',
+  'ẽ' => 'Ẽ',
+  'ế' => 'Ế',
+  'ề' => 'Ề',
+  'ể' => 'Ể',
+  'ễ' => 'Ễ',
+  'ệ' => 'Ệ',
+  'ỉ' => 'Ỉ',
+  'ị' => 'Ị',
+  'ọ' => 'Ọ',
+  'ỏ' => 'Ỏ',
+  'ố' => 'Ố',
+  'ồ' => 'Ồ',
+  'ổ' => 'Ổ',
+  'ỗ' => 'Ỗ',
+  'ộ' => 'Ộ',
+  'ớ' => 'Ớ',
+  'ờ' => 'Ờ',
+  'ở' => 'Ở',
+  'ỡ' => 'Ỡ',
+  'ợ' => 'Ợ',
+  'ụ' => 'Ụ',
+  'ủ' => 'Ủ',
+  'ứ' => 'Ứ',
+  'ừ' => 'Ừ',
+  'ử' => 'Ử',
+  'ữ' => 'Ữ',
+  'ự' => 'Ự',
+  'ỳ' => 'Ỳ',
+  'ỵ' => 'Ỵ',
+  'ỷ' => 'Ỷ',
+  'ỹ' => 'Ỹ',
+  'ỻ' => 'Ỻ',
+  'ỽ' => 'Ỽ',
+  'ỿ' => 'Ỿ',
+  'ἀ' => 'Ἀ',
+  'ἁ' => 'Ἁ',
+  'ἂ' => 'Ἂ',
+  'ἃ' => 'Ἃ',
+  'ἄ' => 'Ἄ',
+  'ἅ' => 'Ἅ',
+  'ἆ' => 'Ἆ',
+  'ἇ' => 'Ἇ',
+  'ἐ' => 'Ἐ',
+  'ἑ' => 'Ἑ',
+  'ἒ' => 'Ἒ',
+  'ἓ' => 'Ἓ',
+  'ἔ' => 'Ἔ',
+  'ἕ' => 'Ἕ',
+  'ἠ' => 'Ἠ',
+  'ἡ' => 'Ἡ',
+  'ἢ' => 'Ἢ',
+  'ἣ' => 'Ἣ',
+  'ἤ' => 'Ἤ',
+  'ἥ' => 'Ἥ',
+  'ἦ' => 'Ἦ',
+  'ἧ' => 'Ἧ',
+  'ἰ' => 'Ἰ',
+  'ἱ' => 'Ἱ',
+  'ἲ' => 'Ἲ',
+  'ἳ' => 'Ἳ',
+  'ἴ' => 'Ἴ',
+  'ἵ' => 'Ἵ',
+  'ἶ' => 'Ἶ',
+  'ἷ' => 'Ἷ',
+  'ὀ' => 'Ὀ',
+  'ὁ' => 'Ὁ',
+  'ὂ' => 'Ὂ',
+  'ὃ' => 'Ὃ',
+  'ὄ' => 'Ὄ',
+  'ὅ' => 'Ὅ',
+  'ὑ' => 'Ὑ',
+  'ὓ' => 'Ὓ',
+  'ὕ' => 'Ὕ',
+  'ὗ' => 'Ὗ',
+  'ὠ' => 'Ὠ',
+  'ὡ' => 'Ὡ',
+  'ὢ' => 'Ὢ',
+  'ὣ' => 'Ὣ',
+  'ὤ' => 'Ὤ',
+  'ὥ' => 'Ὥ',
+  'ὦ' => 'Ὦ',
+  'ὧ' => 'Ὧ',
+  'ὰ' => 'Ὰ',
+  'ά' => 'Ά',
+  'ὲ' => 'Ὲ',
+  'έ' => 'Έ',
+  'ὴ' => 'Ὴ',
+  'ή' => 'Ή',
+  'ὶ' => 'Ὶ',
+  'ί' => 'Ί',
+  'ὸ' => 'Ὸ',
+  'ό' => 'Ό',
+  'ὺ' => 'Ὺ',
+  'ύ' => 'Ύ',
+  'ὼ' => 'Ὼ',
+  'ώ' => 'Ώ',
+  'ᾀ' => 'ἈΙ',
+  'ᾁ' => 'ἉΙ',
+  'ᾂ' => 'ἊΙ',
+  'ᾃ' => 'ἋΙ',
+  'ᾄ' => 'ἌΙ',
+  'ᾅ' => 'ἍΙ',
+  'ᾆ' => 'ἎΙ',
+  'ᾇ' => 'ἏΙ',
+  'ᾐ' => 'ἨΙ',
+  'ᾑ' => 'ἩΙ',
+  'ᾒ' => 'ἪΙ',
+  'ᾓ' => 'ἫΙ',
+  'ᾔ' => 'ἬΙ',
+  'ᾕ' => 'ἭΙ',
+  'ᾖ' => 'ἮΙ',
+  'ᾗ' => 'ἯΙ',
+  'ᾠ' => 'ὨΙ',
+  'ᾡ' => 'ὩΙ',
+  'ᾢ' => 'ὪΙ',
+  'ᾣ' => 'ὫΙ',
+  'ᾤ' => 'ὬΙ',
+  'ᾥ' => 'ὭΙ',
+  'ᾦ' => 'ὮΙ',
+  'ᾧ' => 'ὯΙ',
+  'ᾰ' => 'Ᾰ',
+  'ᾱ' => 'Ᾱ',
+  'ᾳ' => 'ΑΙ',
+  'ι' => 'Ι',
+  'ῃ' => 'ΗΙ',
+  'ῐ' => 'Ῐ',
+  'ῑ' => 'Ῑ',
+  'ῠ' => 'Ῠ',
+  'ῡ' => 'Ῡ',
+  'ῥ' => 'Ῥ',
+  'ῳ' => 'ΩΙ',
+  'ⅎ' => 'Ⅎ',
+  'ⅰ' => 'Ⅰ',
+  'ⅱ' => 'Ⅱ',
+  'ⅲ' => 'Ⅲ',
+  'ⅳ' => 'Ⅳ',
+  'ⅴ' => 'Ⅴ',
+  'ⅵ' => 'Ⅵ',
+  'ⅶ' => 'Ⅶ',
+  'ⅷ' => 'Ⅷ',
+  'ⅸ' => 'Ⅸ',
+  'ⅹ' => 'Ⅹ',
+  'ⅺ' => 'Ⅺ',
+  'ⅻ' => 'Ⅻ',
+  'ⅼ' => 'Ⅼ',
+  'ⅽ' => 'Ⅽ',
+  'ⅾ' => 'Ⅾ',
+  'ⅿ' => 'Ⅿ',
+  'ↄ' => 'Ↄ',
+  'ⓐ' => 'Ⓐ',
+  'ⓑ' => 'Ⓑ',
+  'ⓒ' => 'Ⓒ',
+  'ⓓ' => 'Ⓓ',
+  'ⓔ' => 'Ⓔ',
+  'ⓕ' => 'Ⓕ',
+  'ⓖ' => 'Ⓖ',
+  'ⓗ' => 'Ⓗ',
+  'ⓘ' => 'Ⓘ',
+  'ⓙ' => 'Ⓙ',
+  'ⓚ' => 'Ⓚ',
+  'ⓛ' => 'Ⓛ',
+  'ⓜ' => 'Ⓜ',
+  'ⓝ' => 'Ⓝ',
+  'ⓞ' => 'Ⓞ',
+  'ⓟ' => 'Ⓟ',
+  'ⓠ' => 'Ⓠ',
+  'ⓡ' => 'Ⓡ',
+  'ⓢ' => 'Ⓢ',
+  'ⓣ' => 'Ⓣ',
+  'ⓤ' => 'Ⓤ',
+  'ⓥ' => 'Ⓥ',
+  'ⓦ' => 'Ⓦ',
+  'ⓧ' => 'Ⓧ',
+  'ⓨ' => 'Ⓨ',
+  'ⓩ' => 'Ⓩ',
+  'ⰰ' => 'Ⰰ',
+  'ⰱ' => 'Ⰱ',
+  'ⰲ' => 'Ⰲ',
+  'ⰳ' => 'Ⰳ',
+  'ⰴ' => 'Ⰴ',
+  'ⰵ' => 'Ⰵ',
+  'ⰶ' => 'Ⰶ',
+  'ⰷ' => 'Ⰷ',
+  'ⰸ' => 'Ⰸ',
+  'ⰹ' => 'Ⰹ',
+  'ⰺ' => 'Ⰺ',
+  'ⰻ' => 'Ⰻ',
+  'ⰼ' => 'Ⰼ',
+  'ⰽ' => 'Ⰽ',
+  'ⰾ' => 'Ⰾ',
+  'ⰿ' => 'Ⰿ',
+  'ⱀ' => 'Ⱀ',
+  'ⱁ' => 'Ⱁ',
+  'ⱂ' => 'Ⱂ',
+  'ⱃ' => 'Ⱃ',
+  'ⱄ' => 'Ⱄ',
+  'ⱅ' => 'Ⱅ',
+  'ⱆ' => 'Ⱆ',
+  'ⱇ' => 'Ⱇ',
+  'ⱈ' => 'Ⱈ',
+  'ⱉ' => 'Ⱉ',
+  'ⱊ' => 'Ⱊ',
+  'ⱋ' => 'Ⱋ',
+  'ⱌ' => 'Ⱌ',
+  'ⱍ' => 'Ⱍ',
+  'ⱎ' => 'Ⱎ',
+  'ⱏ' => 'Ⱏ',
+  'ⱐ' => 'Ⱐ',
+  'ⱑ' => 'Ⱑ',
+  'ⱒ' => 'Ⱒ',
+  'ⱓ' => 'Ⱓ',
+  'ⱔ' => 'Ⱔ',
+  'ⱕ' => 'Ⱕ',
+  'ⱖ' => 'Ⱖ',
+  'ⱗ' => 'Ⱗ',
+  'ⱘ' => 'Ⱘ',
+  'ⱙ' => 'Ⱙ',
+  'ⱚ' => 'Ⱚ',
+  'ⱛ' => 'Ⱛ',
+  'ⱜ' => 'Ⱜ',
+  'ⱝ' => 'Ⱝ',
+  'ⱞ' => 'Ⱞ',
+  'ⱡ' => 'Ⱡ',
+  'ⱥ' => 'Ⱥ',
+  'ⱦ' => 'Ⱦ',
+  'ⱨ' => 'Ⱨ',
+  'ⱪ' => 'Ⱪ',
+  'ⱬ' => 'Ⱬ',
+  'ⱳ' => 'Ⱳ',
+  'ⱶ' => 'Ⱶ',
+  'ⲁ' => 'Ⲁ',
+  'ⲃ' => 'Ⲃ',
+  'ⲅ' => 'Ⲅ',
+  'ⲇ' => 'Ⲇ',
+  'ⲉ' => 'Ⲉ',
+  'ⲋ' => 'Ⲋ',
+  'ⲍ' => 'Ⲍ',
+  'ⲏ' => 'Ⲏ',
+  'ⲑ' => 'Ⲑ',
+  'ⲓ' => 'Ⲓ',
+  'ⲕ' => 'Ⲕ',
+  'ⲗ' => 'Ⲗ',
+  'ⲙ' => 'Ⲙ',
+  'ⲛ' => 'Ⲛ',
+  'ⲝ' => 'Ⲝ',
+  'ⲟ' => 'Ⲟ',
+  'ⲡ' => 'Ⲡ',
+  'ⲣ' => 'Ⲣ',
+  'ⲥ' => 'Ⲥ',
+  'ⲧ' => 'Ⲧ',
+  'ⲩ' => 'Ⲩ',
+  'ⲫ' => 'Ⲫ',
+  'ⲭ' => 'Ⲭ',
+  'ⲯ' => 'Ⲯ',
+  'ⲱ' => 'Ⲱ',
+  'ⲳ' => 'Ⲳ',
+  'ⲵ' => 'Ⲵ',
+  'ⲷ' => 'Ⲷ',
+  'ⲹ' => 'Ⲹ',
+  'ⲻ' => 'Ⲻ',
+  'ⲽ' => 'Ⲽ',
+  'ⲿ' => 'Ⲿ',
+  'ⳁ' => 'Ⳁ',
+  'ⳃ' => 'Ⳃ',
+  'ⳅ' => 'Ⳅ',
+  'ⳇ' => 'Ⳇ',
+  'ⳉ' => 'Ⳉ',
+  'ⳋ' => 'Ⳋ',
+  'ⳍ' => 'Ⳍ',
+  'ⳏ' => 'Ⳏ',
+  'ⳑ' => 'Ⳑ',
+  'ⳓ' => 'Ⳓ',
+  'ⳕ' => 'Ⳕ',
+  'ⳗ' => 'Ⳗ',
+  'ⳙ' => 'Ⳙ',
+  'ⳛ' => 'Ⳛ',
+  'ⳝ' => 'Ⳝ',
+  'ⳟ' => 'Ⳟ',
+  'ⳡ' => 'Ⳡ',
+  'ⳣ' => 'Ⳣ',
+  'ⳬ' => 'Ⳬ',
+  'ⳮ' => 'Ⳮ',
+  'ⳳ' => 'Ⳳ',
+  'ⴀ' => 'Ⴀ',
+  'ⴁ' => 'Ⴁ',
+  'ⴂ' => 'Ⴂ',
+  'ⴃ' => 'Ⴃ',
+  'ⴄ' => 'Ⴄ',
+  'ⴅ' => 'Ⴅ',
+  'ⴆ' => 'Ⴆ',
+  'ⴇ' => 'Ⴇ',
+  'ⴈ' => 'Ⴈ',
+  'ⴉ' => 'Ⴉ',
+  'ⴊ' => 'Ⴊ',
+  'ⴋ' => 'Ⴋ',
+  'ⴌ' => 'Ⴌ',
+  'ⴍ' => 'Ⴍ',
+  'ⴎ' => 'Ⴎ',
+  'ⴏ' => 'Ⴏ',
+  'ⴐ' => 'Ⴐ',
+  'ⴑ' => 'Ⴑ',
+  'ⴒ' => 'Ⴒ',
+  'ⴓ' => 'Ⴓ',
+  'ⴔ' => 'Ⴔ',
+  'ⴕ' => 'Ⴕ',
+  'ⴖ' => 'Ⴖ',
+  'ⴗ' => 'Ⴗ',
+  'ⴘ' => 'Ⴘ',
+  'ⴙ' => 'Ⴙ',
+  'ⴚ' => 'Ⴚ',
+  'ⴛ' => 'Ⴛ',
+  'ⴜ' => 'Ⴜ',
+  'ⴝ' => 'Ⴝ',
+  'ⴞ' => 'Ⴞ',
+  'ⴟ' => 'Ⴟ',
+  'ⴠ' => 'Ⴠ',
+  'ⴡ' => 'Ⴡ',
+  'ⴢ' => 'Ⴢ',
+  'ⴣ' => 'Ⴣ',
+  'ⴤ' => 'Ⴤ',
+  'ⴥ' => 'Ⴥ',
+  'ⴧ' => 'Ⴧ',
+  'ⴭ' => 'Ⴭ',
+  'ꙁ' => 'Ꙁ',
+  'ꙃ' => 'Ꙃ',
+  'ꙅ' => 'Ꙅ',
+  'ꙇ' => 'Ꙇ',
+  'ꙉ' => 'Ꙉ',
+  'ꙋ' => 'Ꙋ',
+  'ꙍ' => 'Ꙍ',
+  'ꙏ' => 'Ꙏ',
+  'ꙑ' => 'Ꙑ',
+  'ꙓ' => 'Ꙓ',
+  'ꙕ' => 'Ꙕ',
+  'ꙗ' => 'Ꙗ',
+  'ꙙ' => 'Ꙙ',
+  'ꙛ' => 'Ꙛ',
+  'ꙝ' => 'Ꙝ',
+  'ꙟ' => 'Ꙟ',
+  'ꙡ' => 'Ꙡ',
+  'ꙣ' => 'Ꙣ',
+  'ꙥ' => 'Ꙥ',
+  'ꙧ' => 'Ꙧ',
+  'ꙩ' => 'Ꙩ',
+  'ꙫ' => 'Ꙫ',
+  'ꙭ' => 'Ꙭ',
+  'ꚁ' => 'Ꚁ',
+  'ꚃ' => 'Ꚃ',
+  'ꚅ' => 'Ꚅ',
+  'ꚇ' => 'Ꚇ',
+  'ꚉ' => 'Ꚉ',
+  'ꚋ' => 'Ꚋ',
+  'ꚍ' => 'Ꚍ',
+  'ꚏ' => 'Ꚏ',
+  'ꚑ' => 'Ꚑ',
+  'ꚓ' => 'Ꚓ',
+  'ꚕ' => 'Ꚕ',
+  'ꚗ' => 'Ꚗ',
+  'ꚙ' => 'Ꚙ',
+  'ꚛ' => 'Ꚛ',
+  'ꜣ' => 'Ꜣ',
+  'ꜥ' => 'Ꜥ',
+  'ꜧ' => 'Ꜧ',
+  'ꜩ' => 'Ꜩ',
+  'ꜫ' => 'Ꜫ',
+  'ꜭ' => 'Ꜭ',
+  'ꜯ' => 'Ꜯ',
+  'ꜳ' => 'Ꜳ',
+  'ꜵ' => 'Ꜵ',
+  'ꜷ' => 'Ꜷ',
+  'ꜹ' => 'Ꜹ',
+  'ꜻ' => 'Ꜻ',
+  'ꜽ' => 'Ꜽ',
+  'ꜿ' => 'Ꜿ',
+  'ꝁ' => 'Ꝁ',
+  'ꝃ' => 'Ꝃ',
+  'ꝅ' => 'Ꝅ',
+  'ꝇ' => 'Ꝇ',
+  'ꝉ' => 'Ꝉ',
+  'ꝋ' => 'Ꝋ',
+  'ꝍ' => 'Ꝍ',
+  'ꝏ' => 'Ꝏ',
+  'ꝑ' => 'Ꝑ',
+  'ꝓ' => 'Ꝓ',
+  'ꝕ' => 'Ꝕ',
+  'ꝗ' => 'Ꝗ',
+  'ꝙ' => 'Ꝙ',
+  'ꝛ' => 'Ꝛ',
+  'ꝝ' => 'Ꝝ',
+  'ꝟ' => 'Ꝟ',
+  'ꝡ' => 'Ꝡ',
+  'ꝣ' => 'Ꝣ',
+  'ꝥ' => 'Ꝥ',
+  'ꝧ' => 'Ꝧ',
+  'ꝩ' => 'Ꝩ',
+  'ꝫ' => 'Ꝫ',
+  'ꝭ' => 'Ꝭ',
+  'ꝯ' => 'Ꝯ',
+  'ꝺ' => 'Ꝺ',
+  'ꝼ' => 'Ꝼ',
+  'ꝿ' => 'Ꝿ',
+  'ꞁ' => 'Ꞁ',
+  'ꞃ' => 'Ꞃ',
+  'ꞅ' => 'Ꞅ',
+  'ꞇ' => 'Ꞇ',
+  'ꞌ' => 'Ꞌ',
+  'ꞑ' => 'Ꞑ',
+  'ꞓ' => 'Ꞓ',
+  'ꞔ' => 'Ꞔ',
+  'ꞗ' => 'Ꞗ',
+  'ꞙ' => 'Ꞙ',
+  'ꞛ' => 'Ꞛ',
+  'ꞝ' => 'Ꞝ',
+  'ꞟ' => 'Ꞟ',
+  'ꞡ' => 'Ꞡ',
+  'ꞣ' => 'Ꞣ',
+  'ꞥ' => 'Ꞥ',
+  'ꞧ' => 'Ꞧ',
+  'ꞩ' => 'Ꞩ',
+  'ꞵ' => 'Ꞵ',
+  'ꞷ' => 'Ꞷ',
+  'ꞹ' => 'Ꞹ',
+  'ꞻ' => 'Ꞻ',
+  'ꞽ' => 'Ꞽ',
+  'ꞿ' => 'Ꞿ',
+  'ꟃ' => 'Ꟃ',
+  'ꟈ' => 'Ꟈ',
+  'ꟊ' => 'Ꟊ',
+  'ꟶ' => 'Ꟶ',
+  'ꭓ' => 'Ꭓ',
+  'ꭰ' => 'Ꭰ',
+  'ꭱ' => 'Ꭱ',
+  'ꭲ' => 'Ꭲ',
+  'ꭳ' => 'Ꭳ',
+  'ꭴ' => 'Ꭴ',
+  'ꭵ' => 'Ꭵ',
+  'ꭶ' => 'Ꭶ',
+  'ꭷ' => 'Ꭷ',
+  'ꭸ' => 'Ꭸ',
+  'ꭹ' => 'Ꭹ',
+  'ꭺ' => 'Ꭺ',
+  'ꭻ' => 'Ꭻ',
+  'ꭼ' => 'Ꭼ',
+  'ꭽ' => 'Ꭽ',
+  'ꭾ' => 'Ꭾ',
+  'ꭿ' => 'Ꭿ',
+  'ꮀ' => 'Ꮀ',
+  'ꮁ' => 'Ꮁ',
+  'ꮂ' => 'Ꮂ',
+  'ꮃ' => 'Ꮃ',
+  'ꮄ' => 'Ꮄ',
+  'ꮅ' => 'Ꮅ',
+  'ꮆ' => 'Ꮆ',
+  'ꮇ' => 'Ꮇ',
+  'ꮈ' => 'Ꮈ',
+  'ꮉ' => 'Ꮉ',
+  'ꮊ' => 'Ꮊ',
+  'ꮋ' => 'Ꮋ',
+  'ꮌ' => 'Ꮌ',
+  'ꮍ' => 'Ꮍ',
+  'ꮎ' => 'Ꮎ',
+  'ꮏ' => 'Ꮏ',
+  'ꮐ' => 'Ꮐ',
+  'ꮑ' => 'Ꮑ',
+  'ꮒ' => 'Ꮒ',
+  'ꮓ' => 'Ꮓ',
+  'ꮔ' => 'Ꮔ',
+  'ꮕ' => 'Ꮕ',
+  'ꮖ' => 'Ꮖ',
+  'ꮗ' => 'Ꮗ',
+  'ꮘ' => 'Ꮘ',
+  'ꮙ' => 'Ꮙ',
+  'ꮚ' => 'Ꮚ',
+  'ꮛ' => 'Ꮛ',
+  'ꮜ' => 'Ꮜ',
+  'ꮝ' => 'Ꮝ',
+  'ꮞ' => 'Ꮞ',
+  'ꮟ' => 'Ꮟ',
+  'ꮠ' => 'Ꮠ',
+  'ꮡ' => 'Ꮡ',
+  'ꮢ' => 'Ꮢ',
+  'ꮣ' => 'Ꮣ',
+  'ꮤ' => 'Ꮤ',
+  'ꮥ' => 'Ꮥ',
+  'ꮦ' => 'Ꮦ',
+  'ꮧ' => 'Ꮧ',
+  'ꮨ' => 'Ꮨ',
+  'ꮩ' => 'Ꮩ',
+  'ꮪ' => 'Ꮪ',
+  'ꮫ' => 'Ꮫ',
+  'ꮬ' => 'Ꮬ',
+  'ꮭ' => 'Ꮭ',
+  'ꮮ' => 'Ꮮ',
+  'ꮯ' => 'Ꮯ',
+  'ꮰ' => 'Ꮰ',
+  'ꮱ' => 'Ꮱ',
+  'ꮲ' => 'Ꮲ',
+  'ꮳ' => 'Ꮳ',
+  'ꮴ' => 'Ꮴ',
+  'ꮵ' => 'Ꮵ',
+  'ꮶ' => 'Ꮶ',
+  'ꮷ' => 'Ꮷ',
+  'ꮸ' => 'Ꮸ',
+  'ꮹ' => 'Ꮹ',
+  'ꮺ' => 'Ꮺ',
+  'ꮻ' => 'Ꮻ',
+  'ꮼ' => 'Ꮼ',
+  'ꮽ' => 'Ꮽ',
+  'ꮾ' => 'Ꮾ',
+  'ꮿ' => 'Ꮿ',
+  'a' => 'A',
+  'b' => 'B',
+  'c' => 'C',
+  'd' => 'D',
+  'e' => 'E',
+  'f' => 'F',
+  'g' => 'G',
+  'h' => 'H',
+  'i' => 'I',
+  'j' => 'J',
+  'k' => 'K',
+  'l' => 'L',
+  'm' => 'M',
+  'n' => 'N',
+  'o' => 'O',
+  'p' => 'P',
+  'q' => 'Q',
+  'r' => 'R',
+  's' => 'S',
+  't' => 'T',
+  'u' => 'U',
+  'v' => 'V',
+  'w' => 'W',
+  'x' => 'X',
+  'y' => 'Y',
+  'z' => 'Z',
+  '𐐨' => '𐐀',
+  '𐐩' => '𐐁',
+  '𐐪' => '𐐂',
+  '𐐫' => '𐐃',
+  '𐐬' => '𐐄',
+  '𐐭' => '𐐅',
+  '𐐮' => '𐐆',
+  '𐐯' => '𐐇',
+  '𐐰' => '𐐈',
+  '𐐱' => '𐐉',
+  '𐐲' => '𐐊',
+  '𐐳' => '𐐋',
+  '𐐴' => '𐐌',
+  '𐐵' => '𐐍',
+  '𐐶' => '𐐎',
+  '𐐷' => '𐐏',
+  '𐐸' => '𐐐',
+  '𐐹' => '𐐑',
+  '𐐺' => '𐐒',
+  '𐐻' => '𐐓',
+  '𐐼' => '𐐔',
+  '𐐽' => '𐐕',
+  '𐐾' => '𐐖',
+  '𐐿' => '𐐗',
+  '𐑀' => '𐐘',
+  '𐑁' => '𐐙',
+  '𐑂' => '𐐚',
+  '𐑃' => '𐐛',
+  '𐑄' => '𐐜',
+  '𐑅' => '𐐝',
+  '𐑆' => '𐐞',
+  '𐑇' => '𐐟',
+  '𐑈' => '𐐠',
+  '𐑉' => '𐐡',
+  '𐑊' => '𐐢',
+  '𐑋' => '𐐣',
+  '𐑌' => '𐐤',
+  '𐑍' => '𐐥',
+  '𐑎' => '𐐦',
+  '𐑏' => '𐐧',
+  '𐓘' => '𐒰',
+  '𐓙' => '𐒱',
+  '𐓚' => '𐒲',
+  '𐓛' => '𐒳',
+  '𐓜' => '𐒴',
+  '𐓝' => '𐒵',
+  '𐓞' => '𐒶',
+  '𐓟' => '𐒷',
+  '𐓠' => '𐒸',
+  '𐓡' => '𐒹',
+  '𐓢' => '𐒺',
+  '𐓣' => '𐒻',
+  '𐓤' => '𐒼',
+  '𐓥' => '𐒽',
+  '𐓦' => '𐒾',
+  '𐓧' => '𐒿',
+  '𐓨' => '𐓀',
+  '𐓩' => '𐓁',
+  '𐓪' => '𐓂',
+  '𐓫' => '𐓃',
+  '𐓬' => '𐓄',
+  '𐓭' => '𐓅',
+  '𐓮' => '𐓆',
+  '𐓯' => '𐓇',
+  '𐓰' => '𐓈',
+  '𐓱' => '𐓉',
+  '𐓲' => '𐓊',
+  '𐓳' => '𐓋',
+  '𐓴' => '𐓌',
+  '𐓵' => '𐓍',
+  '𐓶' => '𐓎',
+  '𐓷' => '𐓏',
+  '𐓸' => '𐓐',
+  '𐓹' => '𐓑',
+  '𐓺' => '𐓒',
+  '𐓻' => '𐓓',
+  '𐳀' => '𐲀',
+  '𐳁' => '𐲁',
+  '𐳂' => '𐲂',
+  '𐳃' => '𐲃',
+  '𐳄' => '𐲄',
+  '𐳅' => '𐲅',
+  '𐳆' => '𐲆',
+  '𐳇' => '𐲇',
+  '𐳈' => '𐲈',
+  '𐳉' => '𐲉',
+  '𐳊' => '𐲊',
+  '𐳋' => '𐲋',
+  '𐳌' => '𐲌',
+  '𐳍' => '𐲍',
+  '𐳎' => '𐲎',
+  '𐳏' => '𐲏',
+  '𐳐' => '𐲐',
+  '𐳑' => '𐲑',
+  '𐳒' => '𐲒',
+  '𐳓' => '𐲓',
+  '𐳔' => '𐲔',
+  '𐳕' => '𐲕',
+  '𐳖' => '𐲖',
+  '𐳗' => '𐲗',
+  '𐳘' => '𐲘',
+  '𐳙' => '𐲙',
+  '𐳚' => '𐲚',
+  '𐳛' => '𐲛',
+  '𐳜' => '𐲜',
+  '𐳝' => '𐲝',
+  '𐳞' => '𐲞',
+  '𐳟' => '𐲟',
+  '𐳠' => '𐲠',
+  '𐳡' => '𐲡',
+  '𐳢' => '𐲢',
+  '𐳣' => '𐲣',
+  '𐳤' => '𐲤',
+  '𐳥' => '𐲥',
+  '𐳦' => '𐲦',
+  '𐳧' => '𐲧',
+  '𐳨' => '𐲨',
+  '𐳩' => '𐲩',
+  '𐳪' => '𐲪',
+  '𐳫' => '𐲫',
+  '𐳬' => '𐲬',
+  '𐳭' => '𐲭',
+  '𐳮' => '𐲮',
+  '𐳯' => '𐲯',
+  '𐳰' => '𐲰',
+  '𐳱' => '𐲱',
+  '𐳲' => '𐲲',
+  '𑣀' => '𑢠',
+  '𑣁' => '𑢡',
+  '𑣂' => '𑢢',
+  '𑣃' => '𑢣',
+  '𑣄' => '𑢤',
+  '𑣅' => '𑢥',
+  '𑣆' => '𑢦',
+  '𑣇' => '𑢧',
+  '𑣈' => '𑢨',
+  '𑣉' => '𑢩',
+  '𑣊' => '𑢪',
+  '𑣋' => '𑢫',
+  '𑣌' => '𑢬',
+  '𑣍' => '𑢭',
+  '𑣎' => '𑢮',
+  '𑣏' => '𑢯',
+  '𑣐' => '𑢰',
+  '𑣑' => '𑢱',
+  '𑣒' => '𑢲',
+  '𑣓' => '𑢳',
+  '𑣔' => '𑢴',
+  '𑣕' => '𑢵',
+  '𑣖' => '𑢶',
+  '𑣗' => '𑢷',
+  '𑣘' => '𑢸',
+  '𑣙' => '𑢹',
+  '𑣚' => '𑢺',
+  '𑣛' => '𑢻',
+  '𑣜' => '𑢼',
+  '𑣝' => '𑢽',
+  '𑣞' => '𑢾',
+  '𑣟' => '𑢿',
+  '𖹠' => '𖹀',
+  '𖹡' => '𖹁',
+  '𖹢' => '𖹂',
+  '𖹣' => '𖹃',
+  '𖹤' => '𖹄',
+  '𖹥' => '𖹅',
+  '𖹦' => '𖹆',
+  '𖹧' => '𖹇',
+  '𖹨' => '𖹈',
+  '𖹩' => '𖹉',
+  '𖹪' => '𖹊',
+  '𖹫' => '𖹋',
+  '𖹬' => '𖹌',
+  '𖹭' => '𖹍',
+  '𖹮' => '𖹎',
+  '𖹯' => '𖹏',
+  '𖹰' => '𖹐',
+  '𖹱' => '𖹑',
+  '𖹲' => '𖹒',
+  '𖹳' => '𖹓',
+  '𖹴' => '𖹔',
+  '𖹵' => '𖹕',
+  '𖹶' => '𖹖',
+  '𖹷' => '𖹗',
+  '𖹸' => '𖹘',
+  '𖹹' => '𖹙',
+  '𖹺' => '𖹚',
+  '𖹻' => '𖹛',
+  '𖹼' => '𖹜',
+  '𖹽' => '𖹝',
+  '𖹾' => '𖹞',
+  '𖹿' => '𖹟',
+  '𞤢' => '𞤀',
+  '𞤣' => '𞤁',
+  '𞤤' => '𞤂',
+  '𞤥' => '𞤃',
+  '𞤦' => '𞤄',
+  '𞤧' => '𞤅',
+  '𞤨' => '𞤆',
+  '𞤩' => '𞤇',
+  '𞤪' => '𞤈',
+  '𞤫' => '𞤉',
+  '𞤬' => '𞤊',
+  '𞤭' => '𞤋',
+  '𞤮' => '𞤌',
+  '𞤯' => '𞤍',
+  '𞤰' => '𞤎',
+  '𞤱' => '𞤏',
+  '𞤲' => '𞤐',
+  '𞤳' => '𞤑',
+  '𞤴' => '𞤒',
+  '𞤵' => '𞤓',
+  '𞤶' => '𞤔',
+  '𞤷' => '𞤕',
+  '𞤸' => '𞤖',
+  '𞤹' => '𞤗',
+  '𞤺' => '𞤘',
+  '𞤻' => '𞤙',
+  '𞤼' => '𞤚',
+  '𞤽' => '𞤛',
+  '𞤾' => '𞤜',
+  '𞤿' => '𞤝',
+  '𞥀' => '𞤞',
+  '𞥁' => '𞤟',
+  '𞥂' => '𞤠',
+  '𞥃' => '𞤡',
+  'ß' => 'SS',
+  'ff' => 'FF',
+  'fi' => 'FI',
+  'fl' => 'FL',
+  'ffi' => 'FFI',
+  'ffl' => 'FFL',
+  'ſt' => 'ST',
+  'st' => 'ST',
+  'և' => 'ԵՒ',
+  'ﬓ' => 'ՄՆ',
+  'ﬔ' => 'ՄԵ',
+  'ﬕ' => 'ՄԻ',
+  'ﬖ' => 'ՎՆ',
+  'ﬗ' => 'ՄԽ',
+  'ʼn' => 'ʼN',
+  'ΐ' => 'Ϊ́',
+  'ΰ' => 'Ϋ́',
+  'ǰ' => 'J̌',
+  'ẖ' => 'H̱',
+  'ẗ' => 'T̈',
+  'ẘ' => 'W̊',
+  'ẙ' => 'Y̊',
+  'ẚ' => 'Aʾ',
+  'ὐ' => 'Υ̓',
+  'ὒ' => 'Υ̓̀',
+  'ὔ' => 'Υ̓́',
+  'ὖ' => 'Υ̓͂',
+  'ᾶ' => 'Α͂',
+  'ῆ' => 'Η͂',
+  'ῒ' => 'Ϊ̀',
+  'ΐ' => 'Ϊ́',
+  'ῖ' => 'Ι͂',
+  'ῗ' => 'Ϊ͂',
+  'ῢ' => 'Ϋ̀',
+  'ΰ' => 'Ϋ́',
+  'ῤ' => 'Ρ̓',
+  'ῦ' => 'Υ͂',
+  'ῧ' => 'Ϋ͂',
+  'ῶ' => 'Ω͂',
+  'ᾈ' => 'ἈΙ',
+  'ᾉ' => 'ἉΙ',
+  'ᾊ' => 'ἊΙ',
+  'ᾋ' => 'ἋΙ',
+  'ᾌ' => 'ἌΙ',
+  'ᾍ' => 'ἍΙ',
+  'ᾎ' => 'ἎΙ',
+  'ᾏ' => 'ἏΙ',
+  'ᾘ' => 'ἨΙ',
+  'ᾙ' => 'ἩΙ',
+  'ᾚ' => 'ἪΙ',
+  'ᾛ' => 'ἫΙ',
+  'ᾜ' => 'ἬΙ',
+  'ᾝ' => 'ἭΙ',
+  'ᾞ' => 'ἮΙ',
+  'ᾟ' => 'ἯΙ',
+  'ᾨ' => 'ὨΙ',
+  'ᾩ' => 'ὩΙ',
+  'ᾪ' => 'ὪΙ',
+  'ᾫ' => 'ὫΙ',
+  'ᾬ' => 'ὬΙ',
+  'ᾭ' => 'ὭΙ',
+  'ᾮ' => 'ὮΙ',
+  'ᾯ' => 'ὯΙ',
+  'ᾼ' => 'ΑΙ',
+  'ῌ' => 'ΗΙ',
+  'ῼ' => 'ΩΙ',
+  'ᾲ' => 'ᾺΙ',
+  'ᾴ' => 'ΆΙ',
+  'ῂ' => 'ῊΙ',
+  'ῄ' => 'ΉΙ',
+  'ῲ' => 'ῺΙ',
+  'ῴ' => 'ΏΙ',
+  'ᾷ' => 'Α͂Ι',
+  'ῇ' => 'Η͂Ι',
+  'ῷ' => 'Ω͂Ι',
+);
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/bootstrap.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/bootstrap.php
new file mode 100644
index 0000000..1fedd1f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/bootstrap.php
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Mbstring as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+    return require __DIR__.'/bootstrap80.php';
+}
+
+if (!function_exists('mb_convert_encoding')) {
+    function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); }
+}
+if (!function_exists('mb_decode_mimeheader')) {
+    function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); }
+}
+if (!function_exists('mb_encode_mimeheader')) {
+    function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); }
+}
+if (!function_exists('mb_decode_numericentity')) {
+    function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); }
+}
+if (!function_exists('mb_encode_numericentity')) {
+    function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); }
+}
+if (!function_exists('mb_convert_case')) {
+    function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); }
+}
+if (!function_exists('mb_internal_encoding')) {
+    function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); }
+}
+if (!function_exists('mb_language')) {
+    function mb_language($language = null) { return p\Mbstring::mb_language($language); }
+}
+if (!function_exists('mb_list_encodings')) {
+    function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
+}
+if (!function_exists('mb_encoding_aliases')) {
+    function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
+}
+if (!function_exists('mb_check_encoding')) {
+    function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); }
+}
+if (!function_exists('mb_detect_encoding')) {
+    function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); }
+}
+if (!function_exists('mb_detect_order')) {
+    function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); }
+}
+if (!function_exists('mb_parse_str')) {
+    function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; }
+}
+if (!function_exists('mb_strlen')) {
+    function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); }
+}
+if (!function_exists('mb_strpos')) {
+    function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_strtolower')) {
+    function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); }
+}
+if (!function_exists('mb_strtoupper')) {
+    function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); }
+}
+if (!function_exists('mb_substitute_character')) {
+    function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); }
+}
+if (!function_exists('mb_substr')) {
+    function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); }
+}
+if (!function_exists('mb_stripos')) {
+    function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_stristr')) {
+    function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_strrchr')) {
+    function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_strrichr')) {
+    function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_strripos')) {
+    function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_strrpos')) {
+    function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_strstr')) {
+    function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_get_info')) {
+    function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
+}
+if (!function_exists('mb_http_output')) {
+    function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); }
+}
+if (!function_exists('mb_strwidth')) {
+    function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); }
+}
+if (!function_exists('mb_substr_count')) {
+    function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); }
+}
+if (!function_exists('mb_output_handler')) {
+    function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); }
+}
+if (!function_exists('mb_http_input')) {
+    function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); }
+}
+
+if (!function_exists('mb_convert_variables')) {
+    function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); }
+}
+
+if (!function_exists('mb_ord')) {
+    function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); }
+}
+if (!function_exists('mb_chr')) {
+    function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); }
+}
+if (!function_exists('mb_scrub')) {
+    function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
+}
+if (!function_exists('mb_str_split')) {
+    function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); }
+}
+
+if (extension_loaded('mbstring')) {
+    return;
+}
+
+if (!defined('MB_CASE_UPPER')) {
+    define('MB_CASE_UPPER', 0);
+}
+if (!defined('MB_CASE_LOWER')) {
+    define('MB_CASE_LOWER', 1);
+}
+if (!defined('MB_CASE_TITLE')) {
+    define('MB_CASE_TITLE', 2);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/bootstrap80.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/bootstrap80.php
new file mode 100644
index 0000000..82f5ac4
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/bootstrap80.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Mbstring as p;
+
+if (!function_exists('mb_convert_encoding')) {
+    function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); }
+}
+if (!function_exists('mb_decode_mimeheader')) {
+    function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); }
+}
+if (!function_exists('mb_encode_mimeheader')) {
+    function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); }
+}
+if (!function_exists('mb_decode_numericentity')) {
+    function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); }
+}
+if (!function_exists('mb_encode_numericentity')) {
+    function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); }
+}
+if (!function_exists('mb_convert_case')) {
+    function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); }
+}
+if (!function_exists('mb_internal_encoding')) {
+    function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); }
+}
+if (!function_exists('mb_language')) {
+    function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); }
+}
+if (!function_exists('mb_list_encodings')) {
+    function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); }
+}
+if (!function_exists('mb_encoding_aliases')) {
+    function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); }
+}
+if (!function_exists('mb_check_encoding')) {
+    function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); }
+}
+if (!function_exists('mb_detect_encoding')) {
+    function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); }
+}
+if (!function_exists('mb_detect_order')) {
+    function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); }
+}
+if (!function_exists('mb_parse_str')) {
+    function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; }
+}
+if (!function_exists('mb_strlen')) {
+    function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); }
+}
+if (!function_exists('mb_strpos')) {
+    function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
+}
+if (!function_exists('mb_strtolower')) {
+    function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); }
+}
+if (!function_exists('mb_strtoupper')) {
+    function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); }
+}
+if (!function_exists('mb_substitute_character')) {
+    function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); }
+}
+if (!function_exists('mb_substr')) {
+    function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); }
+}
+if (!function_exists('mb_stripos')) {
+    function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
+}
+if (!function_exists('mb_stristr')) {
+    function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
+}
+if (!function_exists('mb_strrchr')) {
+    function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
+}
+if (!function_exists('mb_strrichr')) {
+    function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
+}
+if (!function_exists('mb_strripos')) {
+    function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
+}
+if (!function_exists('mb_strrpos')) {
+    function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
+}
+if (!function_exists('mb_strstr')) {
+    function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
+}
+if (!function_exists('mb_get_info')) {
+    function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); }
+}
+if (!function_exists('mb_http_output')) {
+    function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); }
+}
+if (!function_exists('mb_strwidth')) {
+    function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); }
+}
+if (!function_exists('mb_substr_count')) {
+    function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); }
+}
+if (!function_exists('mb_output_handler')) {
+    function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); }
+}
+if (!function_exists('mb_http_input')) {
+    function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); }
+}
+
+if (!function_exists('mb_convert_variables')) {
+    function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); }
+}
+
+if (!function_exists('mb_ord')) {
+    function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); }
+}
+if (!function_exists('mb_chr')) {
+    function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); }
+}
+if (!function_exists('mb_scrub')) {
+    function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); }
+}
+if (!function_exists('mb_str_split')) {
+    function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); }
+}
+
+if (extension_loaded('mbstring')) {
+    return;
+}
+
+if (!defined('MB_CASE_UPPER')) {
+    define('MB_CASE_UPPER', 0);
+}
+if (!defined('MB_CASE_LOWER')) {
+    define('MB_CASE_LOWER', 1);
+}
+if (!defined('MB_CASE_TITLE')) {
+    define('MB_CASE_TITLE', 2);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/composer.json
new file mode 100644
index 0000000..2ed7a74
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-mbstring/composer.json
@@ -0,0 +1,38 @@
+{
+    "name": "symfony/polyfill-mbstring",
+    "type": "library",
+    "description": "Symfony polyfill for the Mbstring extension",
+    "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.1"
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
+        "files": [ "bootstrap.php" ]
+    },
+    "suggest": {
+        "ext-mbstring": "For best performance"
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-main": "1.23-dev"
+        },
+        "thanks": {
+            "name": "symfony/polyfill",
+            "url": "https://github.com/symfony/polyfill"
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/LICENSE
new file mode 100644
index 0000000..5593b1d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Php80.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Php80.php
new file mode 100644
index 0000000..5fef511
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Php80.php
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php80;
+
+/**
+ * @author Ion Bazan <ion.bazan@gmail.com>
+ * @author Nico Oelgart <nicoswd@gmail.com>
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+final class Php80
+{
+    public static function fdiv(float $dividend, float $divisor): float
+    {
+        return @($dividend / $divisor);
+    }
+
+    public static function get_debug_type($value): string
+    {
+        switch (true) {
+            case null === $value: return 'null';
+            case \is_bool($value): return 'bool';
+            case \is_string($value): return 'string';
+            case \is_array($value): return 'array';
+            case \is_int($value): return 'int';
+            case \is_float($value): return 'float';
+            case \is_object($value): break;
+            case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
+            default:
+                if (null === $type = @get_resource_type($value)) {
+                    return 'unknown';
+                }
+
+                if ('Unknown' === $type) {
+                    $type = 'closed';
+                }
+
+                return "resource ($type)";
+        }
+
+        $class = \get_class($value);
+
+        if (false === strpos($class, '@')) {
+            return $class;
+        }
+
+        return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
+    }
+
+    public static function get_resource_id($res): int
+    {
+        if (!\is_resource($res) && null === @get_resource_type($res)) {
+            throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
+        }
+
+        return (int) $res;
+    }
+
+    public static function preg_last_error_msg(): string
+    {
+        switch (preg_last_error()) {
+            case \PREG_INTERNAL_ERROR:
+                return 'Internal error';
+            case \PREG_BAD_UTF8_ERROR:
+                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+            case \PREG_BAD_UTF8_OFFSET_ERROR:
+                return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
+            case \PREG_BACKTRACK_LIMIT_ERROR:
+                return 'Backtrack limit exhausted';
+            case \PREG_RECURSION_LIMIT_ERROR:
+                return 'Recursion limit exhausted';
+            case \PREG_JIT_STACKLIMIT_ERROR:
+                return 'JIT stack limit exhausted';
+            case \PREG_NO_ERROR:
+                return 'No error';
+            default:
+                return 'Unknown error';
+        }
+    }
+
+    public static function str_contains(string $haystack, string $needle): bool
+    {
+        return '' === $needle || false !== strpos($haystack, $needle);
+    }
+
+    public static function str_starts_with(string $haystack, string $needle): bool
+    {
+        return 0 === strncmp($haystack, $needle, \strlen($needle));
+    }
+
+    public static function str_ends_with(string $haystack, string $needle): bool
+    {
+        return '' === $needle || ('' !== $haystack && 0 === substr_compare($haystack, $needle, -\strlen($needle)));
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/README.md
new file mode 100644
index 0000000..10b8ee4
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/README.md
@@ -0,0 +1,24 @@
+Symfony Polyfill / Php80
+========================
+
+This component provides features added to PHP 8.0 core:
+
+- `Stringable` interface
+- [`fdiv`](https://php.net/fdiv)
+- `ValueError` class
+- `UnhandledMatchError` class
+- `FILTER_VALIDATE_BOOL` constant
+- [`get_debug_type`](https://php.net/get_debug_type)
+- [`preg_last_error_msg`](https://php.net/preg_last_error_msg)
+- [`str_contains`](https://php.net/str_contains)
+- [`str_starts_with`](https://php.net/str_starts_with)
+- [`str_ends_with`](https://php.net/str_ends_with)
+- [`get_resource_id`](https://php.net/get_resource_id)
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
new file mode 100644
index 0000000..7ea6d27
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
@@ -0,0 +1,22 @@
+<?php
+
+#[Attribute(Attribute::TARGET_CLASS)]
+final class Attribute
+{
+    public const TARGET_CLASS = 1;
+    public const TARGET_FUNCTION = 2;
+    public const TARGET_METHOD = 4;
+    public const TARGET_PROPERTY = 8;
+    public const TARGET_CLASS_CONSTANT = 16;
+    public const TARGET_PARAMETER = 32;
+    public const TARGET_ALL = 63;
+    public const IS_REPEATABLE = 64;
+
+    /** @var int */
+    public $flags;
+
+    public function __construct(int $flags = self::TARGET_ALL)
+    {
+        $this->flags = $flags;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php
new file mode 100644
index 0000000..77e037c
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php
@@ -0,0 +1,11 @@
+<?php
+
+if (\PHP_VERSION_ID < 80000) {
+    interface Stringable
+    {
+        /**
+         * @return string
+         */
+        public function __toString();
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php
new file mode 100644
index 0000000..7fb2000
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php
@@ -0,0 +1,5 @@
+<?php
+
+class UnhandledMatchError extends Error
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php
new file mode 100644
index 0000000..99843ca
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php
@@ -0,0 +1,5 @@
+<?php
+
+class ValueError extends Error
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/bootstrap.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/bootstrap.php
new file mode 100644
index 0000000..e5f7dbc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/bootstrap.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Php80 as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+    return;
+}
+
+if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
+    define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN);
+}
+
+if (!function_exists('fdiv')) {
+    function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); }
+}
+if (!function_exists('preg_last_error_msg')) {
+    function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
+}
+if (!function_exists('str_contains')) {
+    function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('str_starts_with')) {
+    function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('str_ends_with')) {
+    function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('get_debug_type')) {
+    function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
+}
+if (!function_exists('get_resource_id')) {
+    function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/composer.json
new file mode 100644
index 0000000..5fe679d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/polyfill-php80/composer.json
@@ -0,0 +1,40 @@
+{
+    "name": "symfony/polyfill-php80",
+    "type": "library",
+    "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+    "keywords": ["polyfill", "shim", "compatibility", "portable"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Ion Bazan",
+            "email": "ion.bazan@gmail.com"
+        },
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.1"
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Polyfill\\Php80\\": "" },
+        "files": [ "bootstrap.php" ],
+        "classmap": [ "Resources/stubs" ]
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-main": "1.23-dev"
+        },
+        "thanks": {
+            "name": "symfony/polyfill",
+            "url": "https://github.com/symfony/polyfill"
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/.gitignore b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/CHANGELOG.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/CHANGELOG.md
new file mode 100644
index 0000000..7932e26
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/LICENSE
new file mode 100644
index 0000000..2358414
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2018-2021 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/LocaleAwareInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/LocaleAwareInterface.php
new file mode 100644
index 0000000..922ec1d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/LocaleAwareInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Translation;
+
+interface LocaleAwareInterface
+{
+    /**
+     * Sets the current locale.
+     *
+     * @param string $locale The locale
+     *
+     * @throws \InvalidArgumentException If the locale contains invalid characters
+     */
+    public function setLocale(string $locale);
+
+    /**
+     * Returns the current locale.
+     *
+     * @return string The locale
+     */
+    public function getLocale();
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/README.md
new file mode 100644
index 0000000..42e5c51
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/README.md
@@ -0,0 +1,9 @@
+Symfony Translation Contracts
+=============================
+
+A set of abstractions extracted out of the Symfony components.
+
+Can be used to build on semantics that the Symfony components proved useful - and
+that already have battle tested implementations.
+
+See https://github.com/symfony/contracts/blob/main/README.md for more information.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/Test/TranslatorTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/Test/TranslatorTest.php
new file mode 100644
index 0000000..aac9d68
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/Test/TranslatorTest.php
@@ -0,0 +1,367 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Translation\Test;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Contracts\Translation\TranslatorInterface;
+use Symfony\Contracts\Translation\TranslatorTrait;
+
+/**
+ * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
+ * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
+ *
+ * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
+ * The mozilla code is also interesting to check for.
+ *
+ * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
+ *
+ * The goal to cover all languages is to far fetched so this test case is smaller.
+ *
+ * @author Clemens Tolboom clemens@build2be.nl
+ */
+class TranslatorTest extends TestCase
+{
+    public function getTranslator()
+    {
+        return new class() implements TranslatorInterface {
+            use TranslatorTrait;
+        };
+    }
+
+    /**
+     * @dataProvider getTransTests
+     */
+    public function testTrans($expected, $id, $parameters)
+    {
+        $translator = $this->getTranslator();
+
+        $this->assertEquals($expected, $translator->trans($id, $parameters));
+    }
+
+    /**
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoiceWithExplicitLocale($expected, $id, $number)
+    {
+        $translator = $this->getTranslator();
+        $translator->setLocale('en');
+
+        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
+    }
+
+    /**
+     * @requires extension intl
+     *
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoiceWithDefaultLocale($expected, $id, $number)
+    {
+        \Locale::setDefault('en');
+
+        $translator = $this->getTranslator();
+
+        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
+    }
+
+    public function testGetSetLocale()
+    {
+        $translator = $this->getTranslator();
+        $translator->setLocale('en');
+
+        $this->assertEquals('en', $translator->getLocale());
+    }
+
+    /**
+     * @requires extension intl
+     */
+    public function testGetLocaleReturnsDefaultLocaleIfNotSet()
+    {
+        $translator = $this->getTranslator();
+
+        \Locale::setDefault('pt_BR');
+        $this->assertEquals('pt_BR', $translator->getLocale());
+
+        \Locale::setDefault('en');
+        $this->assertEquals('en', $translator->getLocale());
+    }
+
+    public function getTransTests()
+    {
+        return [
+            ['Symfony is great!', 'Symfony is great!', []],
+            ['Symfony is awesome!', 'Symfony is %what%!', ['%what%' => 'awesome']],
+        ];
+    }
+
+    public function getTransChoiceTests()
+    {
+        return [
+            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
+            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
+            ['There are 0 apples', 'There is 1 apple|There are %count% apples', 0],
+            ['There is 1 apple', 'There is 1 apple|There are %count% apples', 1],
+            ['There are 10 apples', 'There is 1 apple|There are %count% apples', 10],
+            // custom validation messages may be coded with a fixed value
+            ['There are 2 apples', 'There are 2 apples', 2],
+        ];
+    }
+
+    /**
+     * @dataProvider getInternal
+     */
+    public function testInterval($expected, $number, $interval)
+    {
+        $translator = $this->getTranslator();
+
+        $this->assertEquals($expected, $translator->trans($interval.' foo|[1,Inf[ bar', ['%count%' => $number]));
+    }
+
+    public function getInternal()
+    {
+        return [
+            ['foo', 3, '{1,2, 3 ,4}'],
+            ['bar', 10, '{1,2, 3 ,4}'],
+            ['bar', 3, '[1,2]'],
+            ['foo', 1, '[1,2]'],
+            ['foo', 2, '[1,2]'],
+            ['bar', 1, ']1,2['],
+            ['bar', 2, ']1,2['],
+            ['foo', log(0), '[-Inf,2['],
+            ['foo', -log(0), '[-2,+Inf]'],
+        ];
+    }
+
+    /**
+     * @dataProvider getChooseTests
+     */
+    public function testChoose($expected, $id, $number, $locale = null)
+    {
+        $translator = $this->getTranslator();
+
+        $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number], null, $locale));
+    }
+
+    public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
+    {
+        $translator = $this->getTranslator();
+
+        $this->assertEquals('There are two apples', $translator->trans('There are two apples', ['%count%' => 2]));
+    }
+
+    /**
+     * @dataProvider getNonMatchingMessages
+     */
+    public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $translator = $this->getTranslator();
+
+        $translator->trans($id, ['%count%' => $number]);
+    }
+
+    public function getNonMatchingMessages()
+    {
+        return [
+            ['{0} There are no apples|{1} There is one apple', 2],
+            ['{1} There is one apple|]1,Inf] There are %count% apples', 0],
+            ['{1} There is one apple|]2,Inf] There are %count% apples', 2],
+            ['{0} There are no apples|There is one apple', 2],
+        ];
+    }
+
+    public function getChooseTests()
+    {
+        return [
+            ['There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
+            ['There are no apples', '{0}     There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
+            ['There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0],
+
+            ['There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1],
+
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10],
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10],
+            ['There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]     There are %count% apples', 10],
+
+            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
+            ['There is one apple', 'There is one apple|There are %count% apples', 1],
+            ['There are 10 apples', 'There is one apple|There are %count% apples', 10],
+
+            ['There are 0 apples', 'one: There is one apple|more: There are %count% apples', 0],
+            ['There is one apple', 'one: There is one apple|more: There are %count% apples', 1],
+            ['There are 10 apples', 'one: There is one apple|more: There are %count% apples', 10],
+
+            ['There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0],
+            ['There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1],
+            ['There are 10 apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10],
+
+            ['', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0],
+            ['', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1],
+
+            // Indexed only tests which are Gettext PoFile* compatible strings.
+            ['There are 0 apples', 'There is one apple|There are %count% apples', 0],
+            ['There is one apple', 'There is one apple|There are %count% apples', 1],
+            ['There are 2 apples', 'There is one apple|There are %count% apples', 2],
+
+            // Tests for float numbers
+            ['There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7],
+            ['There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1],
+            ['There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7],
+            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
+            ['There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0],
+            ['There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0],
+
+            // Test texts with new-lines
+            // with double-quotes and \n in id & double-quotes and actual newlines in text
+            ["This is a text with a\n            new-line in it. Selector = 0.", '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 0],
+            // with double-quotes and \n in id and single-quotes and actual newlines in text
+            ["This is a text with a\n            new-line in it. Selector = 1.", '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 1],
+            ["This is a text with a\n            new-line in it. Selector > 1.", '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 5],
+            // with double-quotes and id split accros lines
+            ['This is a text with a
+            new-line in it. Selector = 1.', '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 1],
+            // with single-quotes and id split accros lines
+            ['This is a text with a
+            new-line in it. Selector > 1.', '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 5],
+            // with single-quotes and \n in text
+            ['This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0],
+            // with double-quotes and id split accros lines
+            ["This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1],
+            // esacape pipe
+            ['This is a text with | in it. Selector = 0.', '{0}This is a text with || in it. Selector = 0.|{1}This is a text with || in it. Selector = 1.', 0],
+            // Empty plural set (2 plural forms) from a .PO file
+            ['', '|', 1],
+            // Empty plural set (3 plural forms) from a .PO file
+            ['', '||', 1],
+
+            // Floating values
+            ['1.5 liters', '%count% liter|%count% liters', 1.5],
+            ['1.5 litre', '%count% litre|%count% litres', 1.5, 'fr'],
+
+            // Negative values
+            ['-1 degree', '%count% degree|%count% degrees', -1],
+            ['-1 degré', '%count% degré|%count% degrés', -1],
+            ['-1.5 degrees', '%count% degree|%count% degrees', -1.5],
+            ['-1.5 degré', '%count% degré|%count% degrés', -1.5, 'fr'],
+            ['-2 degrees', '%count% degree|%count% degrees', -2],
+            ['-2 degrés', '%count% degré|%count% degrés', -2],
+        ];
+    }
+
+    /**
+     * @dataProvider failingLangcodes
+     */
+    public function testFailedLangcodes($nplural, $langCodes)
+    {
+        $matrix = $this->generateTestData($langCodes);
+        $this->validateMatrix($nplural, $matrix, false);
+    }
+
+    /**
+     * @dataProvider successLangcodes
+     */
+    public function testLangcodes($nplural, $langCodes)
+    {
+        $matrix = $this->generateTestData($langCodes);
+        $this->validateMatrix($nplural, $matrix);
+    }
+
+    /**
+     * This array should contain all currently known langcodes.
+     *
+     * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
+     *
+     * @return array
+     */
+    public function successLangcodes()
+    {
+        return [
+            ['1', ['ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky']],
+            ['2', ['nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM']],
+            ['3', ['be', 'bs', 'cs', 'hr']],
+            ['4', ['cy', 'mt', 'sl']],
+            ['6', ['ar']],
+        ];
+    }
+
+    /**
+     * This array should be at least empty within the near future.
+     *
+     * This both depends on a complete list trying to add above as understanding
+     * the plural rules of the current failing languages.
+     *
+     * @return array with nplural together with langcodes
+     */
+    public function failingLangcodes()
+    {
+        return [
+            ['1', ['fa']],
+            ['2', ['jbo']],
+            ['3', ['cbs']],
+            ['4', ['gd', 'kw']],
+            ['5', ['ga']],
+        ];
+    }
+
+    /**
+     * We validate only on the plural coverage. Thus the real rules is not tested.
+     *
+     * @param string $nplural       Plural expected
+     * @param array  $matrix        Containing langcodes and their plural index values
+     * @param bool   $expectSuccess
+     */
+    protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
+    {
+        foreach ($matrix as $langCode => $data) {
+            $indexes = array_flip($data);
+            if ($expectSuccess) {
+                $this->assertEquals($nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
+            } else {
+                $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
+            }
+        }
+    }
+
+    protected function generateTestData($langCodes)
+    {
+        $translator = new class() {
+            use TranslatorTrait {
+                getPluralizationRule as public;
+            }
+        };
+
+        $matrix = [];
+        foreach ($langCodes as $langCode) {
+            for ($count = 0; $count < 200; ++$count) {
+                $plural = $translator->getPluralizationRule($count, $langCode);
+                $matrix[$langCode][$count] = $plural;
+            }
+        }
+
+        return $matrix;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatableInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatableInterface.php
new file mode 100644
index 0000000..47fd6fa
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatableInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Translation;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+interface TranslatableInterface
+{
+    public function trans(TranslatorInterface $translator, string $locale = null): string;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatorInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatorInterface.php
new file mode 100644
index 0000000..dc9bf7f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatorInterface.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Translation;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @method string getLocale() Returns the default locale
+ */
+interface TranslatorInterface
+{
+    /**
+     * Translates the given message.
+     *
+     * When a number is provided as a parameter named "%count%", the message is parsed for plural
+     * forms and a translation is chosen according to this number using the following rules:
+     *
+     * Given a message with different plural translations separated by a
+     * pipe (|), this method returns the correct portion of the message based
+     * on the given number, locale and the pluralization rules in the message
+     * itself.
+     *
+     * The message supports two different types of pluralization rules:
+     *
+     * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
+     * indexed:  There is one apple|There are %count% apples
+     *
+     * The indexed solution can also contain labels (e.g. one: There is one apple).
+     * This is purely for making the translations more clear - it does not
+     * affect the functionality.
+     *
+     * The two methods can also be mixed:
+     *     {0} There are no apples|one: There is one apple|more: There are %count% apples
+     *
+     * An interval can represent a finite set of numbers:
+     *  {1,2,3,4}
+     *
+     * An interval can represent numbers between two numbers:
+     *  [1, +Inf]
+     *  ]-1,2[
+     *
+     * The left delimiter can be [ (inclusive) or ] (exclusive).
+     * The right delimiter can be [ (exclusive) or ] (inclusive).
+     * Beside numbers, you can use -Inf and +Inf for the infinite.
+     *
+     * @see https://en.wikipedia.org/wiki/ISO_31-11
+     *
+     * @param string      $id         The message id (may also be an object that can be cast to string)
+     * @param array       $parameters An array of parameters for the message
+     * @param string|null $domain     The domain for the message or null to use the default
+     * @param string|null $locale     The locale or null to use the default
+     *
+     * @return string The translated string
+     *
+     * @throws \InvalidArgumentException If the locale contains invalid characters
+     */
+    public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatorTrait.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatorTrait.php
new file mode 100644
index 0000000..789693d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/TranslatorTrait.php
@@ -0,0 +1,261 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Translation;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * A trait to help implement TranslatorInterface and LocaleAwareInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait TranslatorTrait
+{
+    private $locale;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $this->locale = $locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return string
+     */
+    public function getLocale()
+    {
+        return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string
+    {
+        if (null === $id || '' === $id) {
+            return '';
+        }
+
+        if (!isset($parameters['%count%']) || !is_numeric($parameters['%count%'])) {
+            return strtr($id, $parameters);
+        }
+
+        $number = (float) $parameters['%count%'];
+        $locale = $locale ?: $this->getLocale();
+
+        $parts = [];
+        if (preg_match('/^\|++$/', $id)) {
+            $parts = explode('|', $id);
+        } elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) {
+            $parts = $matches[0];
+        }
+
+        $intervalRegexp = <<<'EOF'
+/^(?P<interval>
+    ({\s*
+        (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
+    \s*})
+
+        |
+
+    (?P<left_delimiter>[\[\]])
+        \s*
+        (?P<left>-Inf|\-?\d+(\.\d+)?)
+        \s*,\s*
+        (?P<right>\+?Inf|\-?\d+(\.\d+)?)
+        \s*
+    (?P<right_delimiter>[\[\]])
+)\s*(?P<message>.*?)$/xs
+EOF;
+
+        $standardRules = [];
+        foreach ($parts as $part) {
+            $part = trim(str_replace('||', '|', $part));
+
+            // try to match an explicit rule, then fallback to the standard ones
+            if (preg_match($intervalRegexp, $part, $matches)) {
+                if ($matches[2]) {
+                    foreach (explode(',', $matches[3]) as $n) {
+                        if ($number == $n) {
+                            return strtr($matches['message'], $parameters);
+                        }
+                    }
+                } else {
+                    $leftNumber = '-Inf' === $matches['left'] ? -\INF : (float) $matches['left'];
+                    $rightNumber = is_numeric($matches['right']) ? (float) $matches['right'] : \INF;
+
+                    if (('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
+                        && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
+                    ) {
+                        return strtr($matches['message'], $parameters);
+                    }
+                }
+            } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
+                $standardRules[] = $matches[1];
+            } else {
+                $standardRules[] = $part;
+            }
+        }
+
+        $position = $this->getPluralizationRule($number, $locale);
+
+        if (!isset($standardRules[$position])) {
+            // when there's exactly one rule given, and that rule is a standard
+            // rule, use this rule
+            if (1 === \count($parts) && isset($standardRules[0])) {
+                return strtr($standardRules[0], $parameters);
+            }
+
+            $message = sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $id, $locale, $number);
+
+            if (class_exists(InvalidArgumentException::class)) {
+                throw new InvalidArgumentException($message);
+            }
+
+            throw new \InvalidArgumentException($message);
+        }
+
+        return strtr($standardRules[$position], $parameters);
+    }
+
+    /**
+     * Returns the plural position to use for the given locale and number.
+     *
+     * The plural rules are derived from code of the Zend Framework (2010-09-25),
+     * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
+     * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+     */
+    private function getPluralizationRule(float $number, string $locale): int
+    {
+        $number = abs($number);
+
+        switch ('pt_BR' !== $locale && \strlen($locale) > 3 ? substr($locale, 0, strrpos($locale, '_')) : $locale) {
+            case 'af':
+            case 'bn':
+            case 'bg':
+            case 'ca':
+            case 'da':
+            case 'de':
+            case 'el':
+            case 'en':
+            case 'eo':
+            case 'es':
+            case 'et':
+            case 'eu':
+            case 'fa':
+            case 'fi':
+            case 'fo':
+            case 'fur':
+            case 'fy':
+            case 'gl':
+            case 'gu':
+            case 'ha':
+            case 'he':
+            case 'hu':
+            case 'is':
+            case 'it':
+            case 'ku':
+            case 'lb':
+            case 'ml':
+            case 'mn':
+            case 'mr':
+            case 'nah':
+            case 'nb':
+            case 'ne':
+            case 'nl':
+            case 'nn':
+            case 'no':
+            case 'oc':
+            case 'om':
+            case 'or':
+            case 'pa':
+            case 'pap':
+            case 'ps':
+            case 'pt':
+            case 'so':
+            case 'sq':
+            case 'sv':
+            case 'sw':
+            case 'ta':
+            case 'te':
+            case 'tk':
+            case 'ur':
+            case 'zu':
+                return (1 == $number) ? 0 : 1;
+
+            case 'am':
+            case 'bh':
+            case 'fil':
+            case 'fr':
+            case 'gun':
+            case 'hi':
+            case 'hy':
+            case 'ln':
+            case 'mg':
+            case 'nso':
+            case 'pt_BR':
+            case 'ti':
+            case 'wa':
+                return ($number < 2) ? 0 : 1;
+
+            case 'be':
+            case 'bs':
+            case 'hr':
+            case 'ru':
+            case 'sh':
+            case 'sr':
+            case 'uk':
+                return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
+
+            case 'cs':
+            case 'sk':
+                return (1 == $number) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);
+
+            case 'ga':
+                return (1 == $number) ? 0 : ((2 == $number) ? 1 : 2);
+
+            case 'lt':
+                return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
+
+            case 'sl':
+                return (1 == $number % 100) ? 0 : ((2 == $number % 100) ? 1 : (((3 == $number % 100) || (4 == $number % 100)) ? 2 : 3));
+
+            case 'mk':
+                return (1 == $number % 10) ? 0 : 1;
+
+            case 'mt':
+                return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));
+
+            case 'lv':
+                return (0 == $number) ? 0 : (((1 == $number % 10) && (11 != $number % 100)) ? 1 : 2);
+
+            case 'pl':
+                return (1 == $number) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);
+
+            case 'cy':
+                return (1 == $number) ? 0 : ((2 == $number) ? 1 : (((8 == $number) || (11 == $number)) ? 2 : 3));
+
+            case 'ro':
+                return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);
+
+            case 'ar':
+                return (0 == $number) ? 0 : ((1 == $number) ? 1 : ((2 == $number) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));
+
+            default:
+                return 0;
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/composer.json
new file mode 100644
index 0000000..00e27f8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation-contracts/composer.json
@@ -0,0 +1,37 @@
+{
+    "name": "symfony/translation-contracts",
+    "type": "library",
+    "description": "Generic abstractions related to translation",
+    "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.2.5"
+    },
+    "suggest": {
+        "symfony/translation-implementation": ""
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Contracts\\Translation\\": "" }
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-main": "2.4-dev"
+        },
+        "thanks": {
+            "name": "symfony/contracts",
+            "url": "https://github.com/symfony/contracts"
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/CHANGELOG.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/CHANGELOG.md
new file mode 100644
index 0000000..3341328
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/CHANGELOG.md
@@ -0,0 +1,169 @@
+CHANGELOG
+=========
+
+5.3
+---
+
+ * Add `translation:pull` and `translation:push` commands to manage translations with third-party providers
+ * Add `TranslatorBagInterface::getCatalogues` method
+ * Add support to load XLIFF string in `XliffFileLoader`
+
+5.2.0
+-----
+
+ * added support for calling `trans` with ICU formatted messages
+ * added `PseudoLocalizationTranslator`
+ * added `TranslatableMessage` objects that represent a message that can be translated
+ * added the `t()` function to easily create `TranslatableMessage` objects
+ * Added support for extracting messages from `TranslatableMessage` objects
+
+5.1.0
+-----
+
+ * added support for `name` attribute on `unit` element from xliff2 to be used as a translation key instead of always the `source` element
+
+5.0.0
+-----
+
+ * removed support for using `null` as the locale in `Translator`
+ * removed `TranslatorInterface`
+ * removed `MessageSelector`
+ * removed `ChoiceMessageFormatterInterface`
+ * removed `PluralizationRule`
+ * removed `Interval`
+ * removed `transChoice()` methods, use the trans() method instead with a %count% parameter
+ * removed `FileDumper::setBackup()` and `TranslationWriter::disableBackup()`
+ * removed `MessageFormatter::choiceFormat()`
+ * added argument `$filename` to `PhpExtractor::parseTokens()`
+ * removed support for implicit STDIN usage in the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.
+
+4.4.0
+-----
+
+ * deprecated support for using `null` as the locale in `Translator`
+ * deprecated accepting STDIN implicitly when using the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.
+ * Marked the `TranslationDataCollector` class as `@final`.
+
+4.3.0
+-----
+
+ * Improved Xliff 1.2 loader to load the original file's metadata
+ * Added `TranslatorPathsPass`
+
+4.2.0
+-----
+
+ * Started using ICU parent locales as fallback locales.
+ * allow using the ICU message format using domains with the "+intl-icu" suffix
+ * deprecated `Translator::transChoice()` in favor of using `Translator::trans()` with a `%count%` parameter
+ * deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface`
+ * deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead
+ * Added `IntlFormatter` and `IntlFormatterInterface`
+ * added support for multiple files and directories in `XliffLintCommand`
+ * Marked `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` as internal
+
+4.1.0
+-----
+
+ * The `FileDumper::setBackup()` method is deprecated.
+ * The `TranslationWriter::disableBackup()` method is deprecated.
+ * The `XliffFileDumper` will write "name" on the "unit" node when dumping XLIFF 2.0.
+
+4.0.0
+-----
+
+ * removed the backup feature of the `FileDumper` class
+ * removed `TranslationWriter::writeTranslations()` method
+ * removed support for passing `MessageSelector` instances to the constructor of the `Translator` class
+
+3.4.0
+-----
+
+ * Added `TranslationDumperPass`
+ * Added `TranslationExtractorPass`
+ * Added `TranslatorPass`
+ * Added `TranslationReader` and `TranslationReaderInterface`
+ * Added `<notes>` section to the Xliff 2.0 dumper.
+ * Improved Xliff 2.0 loader to load `<notes>` section.
+ * Added `TranslationWriterInterface`
+ * Deprecated `TranslationWriter::writeTranslations` in favor of `TranslationWriter::write`
+ * added support for adding custom message formatter and decoupling the default one.
+ * Added `PhpExtractor`
+ * Added `PhpStringTokenParser`
+
+3.2.0
+-----
+
+ * Added support for escaping `|` in plural translations with double pipe.
+
+3.1.0
+-----
+
+ * Deprecated the backup feature of the file dumper classes.
+
+3.0.0
+-----
+
+ * removed `FileDumper::format()` method.
+ * Changed the visibility of the locale property in `Translator` from protected to private.
+
+2.8.0
+-----
+
+ * deprecated FileDumper::format(), overwrite FileDumper::formatCatalogue() instead.
+ * deprecated Translator::getMessages(), rely on TranslatorBagInterface::getCatalogue() instead.
+ * added `FileDumper::formatCatalogue` which allows format the catalogue without dumping it into file.
+ * added option `json_encoding` to JsonFileDumper
+ * added options `as_tree`, `inline` to YamlFileDumper
+ * added support for XLIFF 2.0.
+ * added support for XLIFF target and tool attributes.
+ * added message parameters to DataCollectorTranslator.
+ * [DEPRECATION] The `DiffOperation` class has been deprecated and
+   will be removed in Symfony 3.0, since its operation has nothing to do with 'diff',
+   so the class name is misleading. The `TargetOperation` class should be used for
+   this use-case instead.
+
+2.7.0
+-----
+
+ * added DataCollectorTranslator for collecting the translated messages.
+
+2.6.0
+-----
+
+ * added possibility to cache catalogues
+ * added TranslatorBagInterface
+ * added LoggingTranslator
+ * added Translator::getMessages() for retrieving the message catalogue as an array
+
+2.5.0
+-----
+
+ * added relative file path template to the file dumpers
+ * added optional backup to the file dumpers
+ * changed IcuResFileDumper to extend FileDumper
+
+2.3.0
+-----
+
+ * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
+ * added Translator::getFallbackLocales()
+ * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method
+
+2.2.0
+-----
+
+ * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
+ * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
+   throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
+   and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
+ * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
+   (IcuDatFileLoader, IcuResFileLoader and QtFileLoader)
+
+2.1.0
+-----
+
+ * added support for more than one fallback locale
+ * added support for extracting translation messages from templates (Twig and PHP)
+ * added dumpers for translation catalogs
+ * added support for QT, gettext, and ResourceBundles
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/AbstractOperation.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/AbstractOperation.php
new file mode 100644
index 0000000..9869fbb
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/AbstractOperation.php
@@ -0,0 +1,192 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\LogicException;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Base catalogues binary operation class.
+ *
+ * A catalogue binary operation performs operation on
+ * source (the left argument) and target (the right argument) catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractOperation implements OperationInterface
+{
+    public const OBSOLETE_BATCH = 'obsolete';
+    public const NEW_BATCH = 'new';
+    public const ALL_BATCH = 'all';
+
+    protected $source;
+    protected $target;
+    protected $result;
+
+    /**
+     * @var array|null The domains affected by this operation
+     */
+    private $domains;
+
+    /**
+     * This array stores 'all', 'new' and 'obsolete' messages for all valid domains.
+     *
+     * The data structure of this array is as follows:
+     *
+     *     [
+     *         'domain 1' => [
+     *             'all' => [...],
+     *             'new' => [...],
+     *             'obsolete' => [...]
+     *         ],
+     *         'domain 2' => [
+     *             'all' => [...],
+     *             'new' => [...],
+     *             'obsolete' => [...]
+     *         ],
+     *         ...
+     *     ]
+     *
+     * @var array The array that stores 'all', 'new' and 'obsolete' messages
+     */
+    protected $messages;
+
+    /**
+     * @throws LogicException
+     */
+    public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+    {
+        if ($source->getLocale() !== $target->getLocale()) {
+            throw new LogicException('Operated catalogues must belong to the same locale.');
+        }
+
+        $this->source = $source;
+        $this->target = $target;
+        $this->result = new MessageCatalogue($source->getLocale());
+        $this->messages = [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomains()
+    {
+        if (null === $this->domains) {
+            $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
+        }
+
+        return $this->domains;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMessages(string $domain)
+    {
+        if (!\in_array($domain, $this->getDomains())) {
+            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
+        }
+
+        if (!isset($this->messages[$domain][self::ALL_BATCH])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain][self::ALL_BATCH];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getNewMessages(string $domain)
+    {
+        if (!\in_array($domain, $this->getDomains())) {
+            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
+        }
+
+        if (!isset($this->messages[$domain][self::NEW_BATCH])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain][self::NEW_BATCH];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getObsoleteMessages(string $domain)
+    {
+        if (!\in_array($domain, $this->getDomains())) {
+            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
+        }
+
+        if (!isset($this->messages[$domain][self::OBSOLETE_BATCH])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain][self::OBSOLETE_BATCH];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResult()
+    {
+        foreach ($this->getDomains() as $domain) {
+            if (!isset($this->messages[$domain])) {
+                $this->processDomain($domain);
+            }
+        }
+
+        return $this->result;
+    }
+
+    /**
+     * @param self::*_BATCH $batch
+     */
+    public function moveMessagesToIntlDomainsIfPossible(string $batch = self::ALL_BATCH): void
+    {
+        // If MessageFormatter class does not exists, intl domains are not supported.
+        if (!class_exists(\MessageFormatter::class)) {
+            return;
+        }
+
+        foreach ($this->getDomains() as $domain) {
+            $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+            switch ($batch) {
+                case self::OBSOLETE_BATCH: $messages = $this->getObsoleteMessages($domain); break;
+                case self::NEW_BATCH: $messages = $this->getNewMessages($domain); break;
+                case self::ALL_BATCH: $messages = $this->getMessages($domain); break;
+                default: throw new \InvalidArgumentException(sprintf('$batch argument must be one of ["%s", "%s", "%s"].', self::ALL_BATCH, self::NEW_BATCH, self::OBSOLETE_BATCH));
+            }
+
+            if (!$messages || (!$this->source->all($intlDomain) && $this->source->all($domain))) {
+                continue;
+            }
+
+            $result = $this->getResult();
+            $allIntlMessages = $result->all($intlDomain);
+            $currentMessages = array_diff_key($messages, $result->all($domain));
+            $result->replace($currentMessages, $domain);
+            $result->replace($allIntlMessages + $messages, $intlDomain);
+        }
+    }
+
+    /**
+     * Performs operation on source and target catalogues for the given domain and
+     * stores the results.
+     *
+     * @param string $domain The domain which the operation will be performed for
+     */
+    abstract protected function processDomain(string $domain);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/MergeOperation.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/MergeOperation.php
new file mode 100644
index 0000000..87db2fb
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/MergeOperation.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Merge operation between two catalogues as follows:
+ * all = source ∪ target = {x: x ∈ source ∨ x ∈ target}
+ * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
+ * obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ source ∧ x ∉ target} = ∅
+ * Basically, the result contains messages from both catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class MergeOperation extends AbstractOperation
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function processDomain(string $domain)
+    {
+        $this->messages[$domain] = [
+            'all' => [],
+            'new' => [],
+            'obsolete' => [],
+        ];
+        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+
+        foreach ($this->source->all($domain) as $id => $message) {
+            $this->messages[$domain]['all'][$id] = $message;
+            $d = $this->source->defines($id, $intlDomain) ? $intlDomain : $domain;
+            $this->result->add([$id => $message], $d);
+            if (null !== $keyMetadata = $this->source->getMetadata($id, $d)) {
+                $this->result->setMetadata($id, $keyMetadata, $d);
+            }
+        }
+
+        foreach ($this->target->all($domain) as $id => $message) {
+            if (!$this->source->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->messages[$domain]['new'][$id] = $message;
+                $d = $this->target->defines($id, $intlDomain) ? $intlDomain : $domain;
+                $this->result->add([$id => $message], $d);
+                if (null !== $keyMetadata = $this->target->getMetadata($id, $d)) {
+                    $this->result->setMetadata($id, $keyMetadata, $d);
+                }
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/OperationInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/OperationInterface.php
new file mode 100644
index 0000000..9ffac88
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/OperationInterface.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Represents an operation on catalogue(s).
+ *
+ * An instance of this interface performs an operation on one or more catalogues and
+ * stores intermediate and final results of the operation.
+ *
+ * The first catalogue in its argument(s) is called the 'source catalogue' or 'source' and
+ * the following results are stored:
+ *
+ * Messages: also called 'all', are valid messages for the given domain after the operation is performed.
+ *
+ * New Messages: also called 'new' (new = all ∖ source = {x: x ∈ all ∧ x ∉ source}).
+ *
+ * Obsolete Messages: also called 'obsolete' (obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ all}).
+ *
+ * Result: also called 'result', is the resulting catalogue for the given domain that holds the same messages as 'all'.
+ *
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+interface OperationInterface
+{
+    /**
+     * Returns domains affected by operation.
+     *
+     * @return array
+     */
+    public function getDomains();
+
+    /**
+     * Returns all valid messages ('all') after operation.
+     *
+     * @return array
+     */
+    public function getMessages(string $domain);
+
+    /**
+     * Returns new messages ('new') after operation.
+     *
+     * @return array
+     */
+    public function getNewMessages(string $domain);
+
+    /**
+     * Returns obsolete messages ('obsolete') after operation.
+     *
+     * @return array
+     */
+    public function getObsoleteMessages(string $domain);
+
+    /**
+     * Returns resulting catalogue ('result').
+     *
+     * @return MessageCatalogueInterface
+     */
+    public function getResult();
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/TargetOperation.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/TargetOperation.php
new file mode 100644
index 0000000..399d917
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/TargetOperation.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Target operation between two catalogues:
+ * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
+ * all = intersection ∪ (target ∖ intersection) = target
+ * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
+ * obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
+ * Basically, the result contains messages from the target catalogue.
+ *
+ * @author Michael Lee <michael.lee@zerustech.com>
+ */
+class TargetOperation extends AbstractOperation
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function processDomain(string $domain)
+    {
+        $this->messages[$domain] = [
+            'all' => [],
+            'new' => [],
+            'obsolete' => [],
+        ];
+        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+
+        // For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``,
+        // because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
+        //
+        // For 'new' messages, the code can't be simplified as ``array_diff_assoc($this->target->all($domain), $this->source->all($domain));``
+        // because doing so will not exclude messages like {x: x ∈ target ∧ x ∉ source.all ∧ x ∈ source.fallback}
+        //
+        // For 'obsolete' messages, the code can't be simplified as ``array_diff_assoc($this->source->all($domain), $this->target->all($domain))``
+        // because doing so will not exclude messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
+
+        foreach ($this->source->all($domain) as $id => $message) {
+            if ($this->target->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $d = $this->target->defines($id, $intlDomain) ? $intlDomain : $domain;
+                $this->result->add([$id => $message], $d);
+                if (null !== $keyMetadata = $this->source->getMetadata($id, $d)) {
+                    $this->result->setMetadata($id, $keyMetadata, $d);
+                }
+            } else {
+                $this->messages[$domain]['obsolete'][$id] = $message;
+            }
+        }
+
+        foreach ($this->target->all($domain) as $id => $message) {
+            if (!$this->source->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->messages[$domain]['new'][$id] = $message;
+                $d = $this->target->defines($id, $intlDomain) ? $intlDomain : $domain;
+                $this->result->add([$id => $message], $d);
+                if (null !== $keyMetadata = $this->target->getMetadata($id, $d)) {
+                    $this->result->setMetadata($id, $keyMetadata, $d);
+                }
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPullCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPullCommand.php
new file mode 100644
index 0000000..0ec02ca
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPullCommand.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Translation\Catalogue\TargetOperation;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Provider\TranslationProviderCollection;
+use Symfony\Component\Translation\Reader\TranslationReaderInterface;
+use Symfony\Component\Translation\Writer\TranslationWriterInterface;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class TranslationPullCommand extends Command
+{
+    use TranslationTrait;
+
+    protected static $defaultName = 'translation:pull';
+    protected static $defaultDescription = 'Pull translations from a given provider.';
+
+    private $providerCollection;
+    private $writer;
+    private $reader;
+    private $defaultLocale;
+    private $transPaths;
+    private $enabledLocales;
+
+    public function __construct(TranslationProviderCollection $providerCollection, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, array $transPaths = [], array $enabledLocales = [])
+    {
+        $this->providerCollection = $providerCollection;
+        $this->writer = $writer;
+        $this->reader = $reader;
+        $this->defaultLocale = $defaultLocale;
+        $this->transPaths = $transPaths;
+        $this->enabledLocales = $enabledLocales;
+
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $keys = $this->providerCollection->keys();
+        $defaultProvider = 1 === \count($keys) ? $keys[0] : null;
+
+        $this
+            ->setDefinition([
+                new InputArgument('provider', null !== $defaultProvider ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The provider to pull translations from.', $defaultProvider),
+                new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with provider ones (it will delete not synchronized messages).'),
+                new InputOption('intl-icu', null, InputOption::VALUE_NONE, 'Associated to --force option, it will write messages in "%domain%+intl-icu.%locale%.xlf" files.'),
+                new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull.'),
+                new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to pull.'),
+                new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format.', 'xlf12'),
+            ])
+            ->setHelp(<<<'EOF'
+The <info>%command.name%</> command pulls translations from the given provider. Only
+new translations are pulled, existing ones are not overwritten.
+
+You can overwrite existing translations (and remove the missing ones on local side) by using the <comment>--force</> flag:
+
+  <info>php %command.full_name% --force provider</>
+
+Full example:
+
+  <info>php %command.full_name% provider --force --domains=messages,validators --locales=en</>
+
+This command pulls all translations associated with the <comment>messages</> and <comment>validators</> domains for the <comment>en</> locale.
+Local translations for the specified domains and locale are deleted if they're not present on the provider and overwritten if it's the case.
+Local translations for others domains and locales are ignored.
+EOF
+            )
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+
+        $provider = $this->providerCollection->get($input->getArgument('provider'));
+        $force = $input->getOption('force');
+        $intlIcu = $input->getOption('intl-icu');
+        $locales = $input->getOption('locales') ?: $this->enabledLocales;
+        $domains = $input->getOption('domains');
+        $format = $input->getOption('format');
+        $xliffVersion = '1.2';
+
+        if ($intlIcu && !$force) {
+            $io->note('--intl-icu option only has an effect when used with --force. Here, it will be ignored.');
+        }
+
+        switch ($format) {
+            case 'xlf20': $xliffVersion = '2.0';
+            // no break
+            case 'xlf12': $format = 'xlf';
+        }
+
+        $writeOptions = [
+            'path' => end($this->transPaths),
+            'xliff_version' => $xliffVersion,
+        ];
+
+        if (!$domains) {
+            $domains = $provider->getDomains();
+        }
+
+        $providerTranslations = $provider->read($domains, $locales);
+
+        if ($force) {
+            foreach ($providerTranslations->getCatalogues() as $catalogue) {
+                $operation = new TargetOperation((new MessageCatalogue($catalogue->getLocale())), $catalogue);
+                if ($intlIcu) {
+                    $operation->moveMessagesToIntlDomainsIfPossible();
+                }
+                $this->writer->write($operation->getResult(), $format, $writeOptions);
+            }
+
+            $io->success(sprintf('Local translations has been updated from "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+            return 0;
+        }
+
+        $localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
+
+        // Append pulled translations to local ones.
+        $localTranslations->addBag($providerTranslations->diff($localTranslations));
+
+        foreach ($localTranslations->getCatalogues() as $catalogue) {
+            $this->writer->write($catalogue, $format, $writeOptions);
+        }
+
+        $io->success(sprintf('New translations from "%s" has been written locally (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+        return 0;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPushCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPushCommand.php
new file mode 100644
index 0000000..b28d3e1
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPushCommand.php
@@ -0,0 +1,158 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Translation\Provider\TranslationProviderCollection;
+use Symfony\Component\Translation\Reader\TranslationReaderInterface;
+use Symfony\Component\Translation\TranslatorBag;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class TranslationPushCommand extends Command
+{
+    use TranslationTrait;
+
+    protected static $defaultName = 'translation:push';
+    protected static $defaultDescription = 'Push translations to a given provider.';
+
+    private $providers;
+    private $reader;
+    private $transPaths;
+    private $enabledLocales;
+
+    public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
+    {
+        $this->providers = $providers;
+        $this->reader = $reader;
+        $this->transPaths = $transPaths;
+        $this->enabledLocales = $enabledLocales;
+
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $keys = $this->providers->keys();
+        $defaultProvider = 1 === \count($keys) ? $keys[0] : null;
+
+        $this
+            ->setDefinition([
+                new InputArgument('provider', null !== $defaultProvider ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The provider to push translations to.', $defaultProvider),
+                new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with local ones (it will delete not synchronized messages).'),
+                new InputOption('delete-missing', null, InputOption::VALUE_NONE, 'Delete translations available on provider but not locally.'),
+                new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to push.'),
+                new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to push.', $this->enabledLocales),
+            ])
+            ->setHelp(<<<'EOF'
+The <info>%command.name%</> command pushes translations to the given provider. Only new
+translations are pushed, existing ones are not overwritten.
+
+You can overwrite existing translations by using the <comment>--force</> flag:
+
+  <info>php %command.full_name% --force provider</>
+
+You can delete provider translations which are not present locally by using the <comment>--delete-missing</> flag:
+
+  <info>php %command.full_name% --delete-missing provider</>
+
+Full example:
+
+  <info>php %command.full_name% provider --force --delete-missing --domains=messages,validators --locales=en</>
+
+This command pushes all translations associated with the <comment>messages</> and <comment>validators</> domains for the <comment>en</> locale.
+Provider translations for the specified domains and locale are deleted if they're not present locally and overwritten if it's the case.
+Provider translations for others domains and locales are ignored.
+EOF
+            )
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $provider = $this->providers->get($input->getArgument('provider'));
+
+        if (!$this->enabledLocales) {
+            throw new InvalidArgumentException(sprintf('You must define "framework.translator.enabled_locales" or "framework.translator.providers.%s.locales" config key in order to work with translation providers.', parse_url($provider, \PHP_URL_SCHEME)));
+        }
+
+        $io = new SymfonyStyle($input, $output);
+        $domains = $input->getOption('domains');
+        $locales = $input->getOption('locales');
+        $force = $input->getOption('force');
+        $deleteMissing = $input->getOption('delete-missing');
+
+        $localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
+
+        if (!$domains) {
+            $domains = $this->getDomainsFromTranslatorBag($localTranslations);
+        }
+
+        if (!$deleteMissing && $force) {
+            $provider->write($localTranslations);
+
+            $io->success(sprintf('All local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+            return 0;
+        }
+
+        $providerTranslations = $provider->read($domains, $locales);
+
+        if ($deleteMissing) {
+            $provider->delete($providerTranslations->diff($localTranslations));
+
+            $io->success(sprintf('Missing translations on "%s" has been deleted (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+            // Read provider translations again, after missing translations deletion,
+            // to avoid push freshly deleted translations.
+            $providerTranslations = $provider->read($domains, $locales);
+        }
+
+        $translationsToWrite = $localTranslations->diff($providerTranslations);
+
+        if ($force) {
+            $translationsToWrite->addBag($localTranslations->intersect($providerTranslations));
+        }
+
+        $provider->write($translationsToWrite);
+
+        $io->success(sprintf('%s local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', $force ? 'All' : 'New', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+        return 0;
+    }
+
+    private function getDomainsFromTranslatorBag(TranslatorBag $translatorBag): array
+    {
+        $domains = [];
+
+        foreach ($translatorBag->getCatalogues() as $catalogue) {
+            $domains += $catalogue->getDomains();
+        }
+
+        return array_unique($domains);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationTrait.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationTrait.php
new file mode 100644
index 0000000..6a2b1ba
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationTrait.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+use Symfony\Component\Translation\TranslatorBag;
+
+/**
+ * @internal
+ */
+trait TranslationTrait
+{
+    private function readLocalTranslations(array $locales, array $domains, array $transPaths): TranslatorBag
+    {
+        $bag = new TranslatorBag();
+
+        foreach ($locales as $locale) {
+            $catalogue = new MessageCatalogue($locale);
+            foreach ($transPaths as $path) {
+                $this->reader->read($path, $catalogue);
+            }
+
+            if ($domains) {
+                foreach ($domains as $domain) {
+                    $catalogue = $this->filterCatalogue($catalogue, $domain);
+                    $bag->addCatalogue($catalogue);
+                }
+            } else {
+                $bag->addCatalogue($catalogue);
+            }
+        }
+
+        return $bag;
+    }
+
+    private function filterCatalogue(MessageCatalogue $catalogue, string $domain): MessageCatalogue
+    {
+        $filteredCatalogue = new MessageCatalogue($catalogue->getLocale());
+
+        // extract intl-icu messages only
+        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+        if ($intlMessages = $catalogue->all($intlDomain)) {
+            $filteredCatalogue->add($intlMessages, $intlDomain);
+        }
+
+        // extract all messages and subtract intl-icu messages
+        if ($messages = array_diff($catalogue->all($domain), $intlMessages)) {
+            $filteredCatalogue->add($messages, $domain);
+        }
+        foreach ($catalogue->getResources() as $resource) {
+            $filteredCatalogue->addResource($resource);
+        }
+
+        if ($metadata = $catalogue->getMetadata('', $intlDomain)) {
+            foreach ($metadata as $k => $v) {
+                $filteredCatalogue->setMetadata($k, $v, $intlDomain);
+            }
+        }
+
+        if ($metadata = $catalogue->getMetadata('', $domain)) {
+            foreach ($metadata as $k => $v) {
+                $filteredCatalogue->setMetadata($k, $v, $domain);
+            }
+        }
+
+        return $filteredCatalogue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/XliffLintCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/XliffLintCommand.php
new file mode 100644
index 0000000..4117d87
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/XliffLintCommand.php
@@ -0,0 +1,267 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Util\XliffUtils;
+
+/**
+ * Validates XLIFF files syntax and outputs encountered errors.
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ * @author Robin Chalas <robin.chalas@gmail.com>
+ * @author Javier Eguiluz <javier.eguiluz@gmail.com>
+ */
+class XliffLintCommand extends Command
+{
+    protected static $defaultName = 'lint:xliff';
+    protected static $defaultDescription = 'Lint an XLIFF file and outputs encountered errors';
+
+    private $format;
+    private $displayCorrectFiles;
+    private $directoryIteratorProvider;
+    private $isReadableProvider;
+    private $requireStrictFileNames;
+
+    public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true)
+    {
+        parent::__construct($name);
+
+        $this->directoryIteratorProvider = $directoryIteratorProvider;
+        $this->isReadableProvider = $isReadableProvider;
+        $this->requireStrictFileNames = $requireStrictFileNames;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this
+            ->setDescription(self::$defaultDescription)
+            ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
+            ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
+            ->setHelp(<<<EOF
+The <info>%command.name%</info> command lints an XLIFF file and outputs to STDOUT
+the first encountered syntax error.
+
+You can validates XLIFF contents passed from STDIN:
+
+  <info>cat filename | php %command.full_name% -</info>
+
+You can also validate the syntax of a file:
+
+  <info>php %command.full_name% filename</info>
+
+Or of a whole directory:
+
+  <info>php %command.full_name% dirname</info>
+  <info>php %command.full_name% dirname --format=json</info>
+
+EOF
+            )
+        ;
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $io = new SymfonyStyle($input, $output);
+        $filenames = (array) $input->getArgument('filename');
+        $this->format = $input->getOption('format');
+        $this->displayCorrectFiles = $output->isVerbose();
+
+        if (['-'] === $filenames) {
+            return $this->display($io, [$this->validate(file_get_contents('php://stdin'))]);
+        }
+
+        if (!$filenames) {
+            throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
+        }
+
+        $filesInfo = [];
+        foreach ($filenames as $filename) {
+            if (!$this->isReadable($filename)) {
+                throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
+            }
+
+            foreach ($this->getFiles($filename) as $file) {
+                $filesInfo[] = $this->validate(file_get_contents($file), $file);
+            }
+        }
+
+        return $this->display($io, $filesInfo);
+    }
+
+    private function validate(string $content, string $file = null): array
+    {
+        $errors = [];
+
+        // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input
+        if ('' === trim($content)) {
+            return ['file' => $file, 'valid' => true];
+        }
+
+        $internal = libxml_use_internal_errors(true);
+
+        $document = new \DOMDocument();
+        $document->loadXML($content);
+
+        if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
+            $normalizedLocalePattern = sprintf('(%s|%s)', preg_quote($targetLanguage, '/'), preg_quote(str_replace('-', '_', $targetLanguage), '/'));
+            // strict file names require translation files to be named '____.locale.xlf'
+            // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed
+            // also, the regexp matching must be case-insensitive, as defined for 'target-language' values
+            // http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language
+            $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.(?:xlf|xliff)/', $normalizedLocalePattern) : sprintf('/^(?:.*\.(?i:%s)|(?i:%s)\..*)\.(?:xlf|xliff)/', $normalizedLocalePattern, $normalizedLocalePattern);
+
+            if (0 === preg_match($expectedFilenamePattern, basename($file))) {
+                $errors[] = [
+                    'line' => -1,
+                    'column' => -1,
+                    'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
+                ];
+            }
+        }
+
+        foreach (XliffUtils::validateSchema($document) as $xmlError) {
+            $errors[] = [
+                'line' => $xmlError['line'],
+                'column' => $xmlError['column'],
+                'message' => $xmlError['message'],
+            ];
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internal);
+
+        return ['file' => $file, 'valid' => 0 === \count($errors), 'messages' => $errors];
+    }
+
+    private function display(SymfonyStyle $io, array $files)
+    {
+        switch ($this->format) {
+            case 'txt':
+                return $this->displayTxt($io, $files);
+            case 'json':
+                return $this->displayJson($io, $files);
+            default:
+                throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
+        }
+    }
+
+    private function displayTxt(SymfonyStyle $io, array $filesInfo)
+    {
+        $countFiles = \count($filesInfo);
+        $erroredFiles = 0;
+
+        foreach ($filesInfo as $info) {
+            if ($info['valid'] && $this->displayCorrectFiles) {
+                $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
+            } elseif (!$info['valid']) {
+                ++$erroredFiles;
+                $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
+                $io->listing(array_map(function ($error) {
+                    // general document errors have a '-1' line number
+                    return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
+                }, $info['messages']));
+            }
+        }
+
+        if (0 === $erroredFiles) {
+            $io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
+        } else {
+            $io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
+        }
+
+        return min($erroredFiles, 1);
+    }
+
+    private function displayJson(SymfonyStyle $io, array $filesInfo)
+    {
+        $errors = 0;
+
+        array_walk($filesInfo, function (&$v) use (&$errors) {
+            $v['file'] = (string) $v['file'];
+            if (!$v['valid']) {
+                ++$errors;
+            }
+        });
+
+        $io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
+
+        return min($errors, 1);
+    }
+
+    private function getFiles(string $fileOrDirectory)
+    {
+        if (is_file($fileOrDirectory)) {
+            yield new \SplFileInfo($fileOrDirectory);
+
+            return;
+        }
+
+        foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
+            if (!\in_array($file->getExtension(), ['xlf', 'xliff'])) {
+                continue;
+            }
+
+            yield $file;
+        }
+    }
+
+    private function getDirectoryIterator(string $directory)
+    {
+        $default = function ($directory) {
+            return new \RecursiveIteratorIterator(
+                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
+                \RecursiveIteratorIterator::LEAVES_ONLY
+            );
+        };
+
+        if (null !== $this->directoryIteratorProvider) {
+            return ($this->directoryIteratorProvider)($directory, $default);
+        }
+
+        return $default($directory);
+    }
+
+    private function isReadable(string $fileOrDirectory)
+    {
+        $default = function ($fileOrDirectory) {
+            return is_readable($fileOrDirectory);
+        };
+
+        if (null !== $this->isReadableProvider) {
+            return ($this->isReadableProvider)($fileOrDirectory, $default);
+        }
+
+        return $default($fileOrDirectory);
+    }
+
+    private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string
+    {
+        foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? [] as $attribute) {
+            if ('target-language' === $attribute->nodeName) {
+                return $attribute->nodeValue;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollector/TranslationDataCollector.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollector/TranslationDataCollector.php
new file mode 100644
index 0000000..f8480ad
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollector/TranslationDataCollector.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DataCollector;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\DataCollector\DataCollector;
+use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
+use Symfony\Component\Translation\DataCollectorTranslator;
+use Symfony\Component\VarDumper\Cloner\Data;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ *
+ * @final
+ */
+class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
+{
+    private $translator;
+
+    public function __construct(DataCollectorTranslator $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function lateCollect()
+    {
+        $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());
+
+        $this->data += $this->computeCount($messages);
+        $this->data['messages'] = $messages;
+
+        $this->data = $this->cloneVar($this->data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function collect(Request $request, Response $response, \Throwable $exception = null)
+    {
+        $this->data['locale'] = $this->translator->getLocale();
+        $this->data['fallback_locales'] = $this->translator->getFallbackLocales();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function reset()
+    {
+        $this->data = [];
+    }
+
+    /**
+     * @return array|Data
+     */
+    public function getMessages()
+    {
+        return $this->data['messages'] ?? [];
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountMissings()
+    {
+        return $this->data[DataCollectorTranslator::MESSAGE_MISSING] ?? 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountFallbacks()
+    {
+        return $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] ?? 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountDefines()
+    {
+        return $this->data[DataCollectorTranslator::MESSAGE_DEFINED] ?? 0;
+    }
+
+    public function getLocale()
+    {
+        return !empty($this->data['locale']) ? $this->data['locale'] : null;
+    }
+
+    /**
+     * @internal
+     */
+    public function getFallbackLocales()
+    {
+        return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'translation';
+    }
+
+    private function sanitizeCollectedMessages(array $messages)
+    {
+        $result = [];
+        foreach ($messages as $key => $message) {
+            $messageId = $message['locale'].$message['domain'].$message['id'];
+
+            if (!isset($result[$messageId])) {
+                $message['count'] = 1;
+                $message['parameters'] = !empty($message['parameters']) ? [$message['parameters']] : [];
+                $messages[$key]['translation'] = $this->sanitizeString($message['translation']);
+                $result[$messageId] = $message;
+            } else {
+                if (!empty($message['parameters'])) {
+                    $result[$messageId]['parameters'][] = $message['parameters'];
+                }
+
+                ++$result[$messageId]['count'];
+            }
+
+            unset($messages[$key]);
+        }
+
+        return $result;
+    }
+
+    private function computeCount(array $messages)
+    {
+        $count = [
+            DataCollectorTranslator::MESSAGE_DEFINED => 0,
+            DataCollectorTranslator::MESSAGE_MISSING => 0,
+            DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0,
+        ];
+
+        foreach ($messages as $message) {
+            ++$count[$message['state']];
+        }
+
+        return $count;
+    }
+
+    private function sanitizeString(string $string, int $length = 80)
+    {
+        $string = trim(preg_replace('/\s+/', ' ', $string));
+
+        if (false !== $encoding = mb_detect_encoding($string, null, true)) {
+            if (mb_strlen($string, $encoding) > $length) {
+                return mb_substr($string, 0, $length - 3, $encoding).'...';
+            }
+        } elseif (\strlen($string) > $length) {
+            return substr($string, 0, $length - 3).'...';
+        }
+
+        return $string;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollectorTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollectorTranslator.php
new file mode 100644
index 0000000..c7d3597
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollectorTranslator.php
@@ -0,0 +1,171 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface, WarmableInterface
+{
+    public const MESSAGE_DEFINED = 0;
+    public const MESSAGE_MISSING = 1;
+    public const MESSAGE_EQUALS_FALLBACK = 2;
+
+    /**
+     * @var TranslatorInterface|TranslatorBagInterface
+     */
+    private $translator;
+
+    private $messages = [];
+
+    /**
+     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
+     */
+    public function __construct(TranslatorInterface $translator)
+    {
+        if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
+            throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
+        }
+
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
+        $this->collectMessage($locale, $domain, $id, $trans, $parameters);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $this->translator->setLocale($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        return $this->translator->getCatalogue($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return $this->translator->getCatalogues();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return string[]
+     */
+    public function warmUp(string $cacheDir)
+    {
+        if ($this->translator instanceof WarmableInterface) {
+            return (array) $this->translator->warmUp($cacheDir);
+        }
+
+        return [];
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @return array The fallback locales
+     */
+    public function getFallbackLocales()
+    {
+        if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
+            return $this->translator->getFallbackLocales();
+        }
+
+        return [];
+    }
+
+    /**
+     * Passes through all unknown calls onto the translator object.
+     */
+    public function __call(string $method, array $args)
+    {
+        return $this->translator->{$method}(...$args);
+    }
+
+    /**
+     * @return array
+     */
+    public function getCollectedMessages()
+    {
+        return $this->messages;
+    }
+
+    private function collectMessage(?string $locale, ?string $domain, string $id, string $translation, ?array $parameters = [])
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $catalogue = $this->translator->getCatalogue($locale);
+        $locale = $catalogue->getLocale();
+        $fallbackLocale = null;
+        if ($catalogue->defines($id, $domain)) {
+            $state = self::MESSAGE_DEFINED;
+        } elseif ($catalogue->has($id, $domain)) {
+            $state = self::MESSAGE_EQUALS_FALLBACK;
+
+            $fallbackCatalogue = $catalogue->getFallbackCatalogue();
+            while ($fallbackCatalogue) {
+                if ($fallbackCatalogue->defines($id, $domain)) {
+                    $fallbackLocale = $fallbackCatalogue->getLocale();
+                    break;
+                }
+                $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
+            }
+        } else {
+            $state = self::MESSAGE_MISSING;
+        }
+
+        $this->messages[] = [
+            'locale' => $locale,
+            'fallbackLocale' => $fallbackLocale,
+            'domain' => $domain,
+            'id' => $id,
+            'translation' => $translation,
+            'parameters' => $parameters,
+            'state' => $state,
+            'transChoiceNumber' => isset($parameters['%count%']) && is_numeric($parameters['%count%']) ? $parameters['%count%'] : null,
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php
new file mode 100644
index 0000000..6d78342
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Adds tagged translation.formatter services to translation writer.
+ */
+class TranslationDumperPass implements CompilerPassInterface
+{
+    private $writerServiceId;
+    private $dumperTag;
+
+    public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper')
+    {
+        if (1 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->writerServiceId = $writerServiceId;
+        $this->dumperTag = $dumperTag;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->writerServiceId)) {
+            return;
+        }
+
+        $definition = $container->getDefinition($this->writerServiceId);
+
+        foreach ($container->findTaggedServiceIds($this->dumperTag, true) as $id => $attributes) {
+            $definition->addMethodCall('addDumper', [$attributes[0]['alias'], new Reference($id)]);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php
new file mode 100644
index 0000000..fab6b20
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Adds tagged translation.extractor services to translation extractor.
+ */
+class TranslationExtractorPass implements CompilerPassInterface
+{
+    private $extractorServiceId;
+    private $extractorTag;
+
+    public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor')
+    {
+        if (0 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->extractorServiceId = $extractorServiceId;
+        $this->extractorTag = $extractorTag;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->extractorServiceId)) {
+            return;
+        }
+
+        $definition = $container->getDefinition($this->extractorServiceId);
+
+        foreach ($container->findTaggedServiceIds($this->extractorTag, true) as $id => $attributes) {
+            if (!isset($attributes[0]['alias'])) {
+                throw new RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id));
+            }
+
+            $definition->addMethodCall('addExtractor', [$attributes[0]['alias'], new Reference($id)]);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPass.php
new file mode 100644
index 0000000..c6a1306
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPass.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+class TranslatorPass implements CompilerPassInterface
+{
+    private $translatorServiceId;
+    private $readerServiceId;
+    private $loaderTag;
+    private $debugCommandServiceId;
+    private $updateCommandServiceId;
+
+    public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update')
+    {
+        if (0 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->translatorServiceId = $translatorServiceId;
+        $this->readerServiceId = $readerServiceId;
+        $this->loaderTag = $loaderTag;
+        $this->debugCommandServiceId = $debugCommandServiceId;
+        $this->updateCommandServiceId = $updateCommandServiceId;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->translatorServiceId)) {
+            return;
+        }
+
+        $loaders = [];
+        $loaderRefs = [];
+        foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
+            $loaderRefs[$id] = new Reference($id);
+            $loaders[$id][] = $attributes[0]['alias'];
+            if (isset($attributes[0]['legacy-alias'])) {
+                $loaders[$id][] = $attributes[0]['legacy-alias'];
+            }
+        }
+
+        if ($container->hasDefinition($this->readerServiceId)) {
+            $definition = $container->getDefinition($this->readerServiceId);
+            foreach ($loaders as $id => $formats) {
+                foreach ($formats as $format) {
+                    $definition->addMethodCall('addLoader', [$format, $loaderRefs[$id]]);
+                }
+            }
+        }
+
+        $container
+            ->findDefinition($this->translatorServiceId)
+            ->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs))
+            ->replaceArgument(3, $loaders)
+        ;
+
+        if (!$container->hasParameter('twig.default_path')) {
+            return;
+        }
+
+        $paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(1));
+        if ($container->hasDefinition($this->debugCommandServiceId)) {
+            $definition = $container->getDefinition($this->debugCommandServiceId);
+            $definition->replaceArgument(4, $container->getParameter('twig.default_path'));
+
+            if (\count($definition->getArguments()) > 6) {
+                $definition->replaceArgument(6, $paths);
+            }
+        }
+        if ($container->hasDefinition($this->updateCommandServiceId)) {
+            $definition = $container->getDefinition($this->updateCommandServiceId);
+            $definition->replaceArgument(5, $container->getParameter('twig.default_path'));
+
+            if (\count($definition->getArguments()) > 7) {
+                $definition->replaceArgument(7, $paths);
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php
new file mode 100644
index 0000000..85b0fa4
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ServiceLocator;
+
+/**
+ * @author Yonel Ceruto <yonelceruto@gmail.com>
+ */
+class TranslatorPathsPass extends AbstractRecursivePass
+{
+    private $translatorServiceId;
+    private $debugCommandServiceId;
+    private $updateCommandServiceId;
+    private $resolverServiceId;
+    private $level = 0;
+    private $paths = [];
+    private $definitions = [];
+    private $controllers = [];
+
+    public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update', string $resolverServiceId = 'argument_resolver.service')
+    {
+        if (0 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->translatorServiceId = $translatorServiceId;
+        $this->debugCommandServiceId = $debugCommandServiceId;
+        $this->updateCommandServiceId = $updateCommandServiceId;
+        $this->resolverServiceId = $resolverServiceId;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->translatorServiceId)) {
+            return;
+        }
+
+        foreach ($this->findControllerArguments($container) as $controller => $argument) {
+            $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller));
+            if ($container->hasDefinition($id)) {
+                [$locatorRef] = $argument->getValues();
+                $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true;
+            }
+        }
+
+        try {
+            parent::process($container);
+
+            $paths = [];
+            foreach ($this->paths as $class => $_) {
+                if (($r = $container->getReflectionClass($class)) && !$r->isInterface()) {
+                    $paths[] = $r->getFileName();
+                    foreach ($r->getTraits() as $trait) {
+                        $paths[] = $trait->getFileName();
+                    }
+                }
+            }
+            if ($paths) {
+                if ($container->hasDefinition($this->debugCommandServiceId)) {
+                    $definition = $container->getDefinition($this->debugCommandServiceId);
+                    $definition->replaceArgument(6, array_merge($definition->getArgument(6), $paths));
+                }
+                if ($container->hasDefinition($this->updateCommandServiceId)) {
+                    $definition = $container->getDefinition($this->updateCommandServiceId);
+                    $definition->replaceArgument(7, array_merge($definition->getArgument(7), $paths));
+                }
+            }
+        } finally {
+            $this->level = 0;
+            $this->paths = [];
+            $this->definitions = [];
+        }
+    }
+
+    protected function processValue($value, bool $isRoot = false)
+    {
+        if ($value instanceof Reference) {
+            if ((string) $value === $this->translatorServiceId) {
+                for ($i = $this->level - 1; $i >= 0; --$i) {
+                    $class = $this->definitions[$i]->getClass();
+
+                    if (ServiceLocator::class === $class) {
+                        if (!isset($this->controllers[$this->currentId])) {
+                            continue;
+                        }
+                        foreach ($this->controllers[$this->currentId] as $class => $_) {
+                            $this->paths[$class] = true;
+                        }
+                    } else {
+                        $this->paths[$class] = true;
+                    }
+
+                    break;
+                }
+            }
+
+            return $value;
+        }
+
+        if ($value instanceof Definition) {
+            $this->definitions[$this->level++] = $value;
+            $value = parent::processValue($value, $isRoot);
+            unset($this->definitions[--$this->level]);
+
+            return $value;
+        }
+
+        return parent::processValue($value, $isRoot);
+    }
+
+    private function findControllerArguments(ContainerBuilder $container): array
+    {
+        if ($container->hasDefinition($this->resolverServiceId)) {
+            $argument = $container->getDefinition($this->resolverServiceId)->getArgument(0);
+            if ($argument instanceof Reference) {
+                $argument = $container->getDefinition($argument);
+            }
+
+            return $argument->getArgument(0);
+        }
+
+        if ($container->hasDefinition('debug.'.$this->resolverServiceId)) {
+            $argument = $container->getDefinition('debug.'.$this->resolverServiceId)->getArgument(0);
+            if ($argument instanceof Reference) {
+                $argument = $container->getDefinition($argument);
+            }
+            $argument = $argument->getArgument(0);
+            if ($argument instanceof Reference) {
+                $argument = $container->getDefinition($argument);
+            }
+
+            return $argument->getArgument(0);
+        }
+
+        return [];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/CsvFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/CsvFileDumper.php
new file mode 100644
index 0000000..0c8589a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/CsvFileDumper.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * CsvFileDumper generates a csv formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class CsvFileDumper extends FileDumper
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $handle = fopen('php://memory', 'r+');
+
+        foreach ($messages->all($domain) as $source => $target) {
+            fputcsv($handle, [$source, $target], $this->delimiter, $this->enclosure);
+        }
+
+        rewind($handle);
+        $output = stream_get_contents($handle);
+        fclose($handle);
+
+        return $output;
+    }
+
+    /**
+     * Sets the delimiter and escape character for CSV.
+     */
+    public function setCsvControl(string $delimiter = ';', string $enclosure = '"')
+    {
+        $this->delimiter = $delimiter;
+        $this->enclosure = $enclosure;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'csv';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/DumperInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/DumperInterface.php
new file mode 100644
index 0000000..7cdaef5
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/DumperInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * DumperInterface is the interface implemented by all translation dumpers.
+ * There is no common option.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface DumperInterface
+{
+    /**
+     * Dumps the message catalogue.
+     *
+     * @param array $options Options that are used by the dumper
+     */
+    public function dump(MessageCatalogue $messages, array $options = []);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/FileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/FileDumper.php
new file mode 100644
index 0000000..e257e72
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/FileDumper.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
+ *
+ * Options:
+ * - path (mandatory): the directory where the files should be saved
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+abstract class FileDumper implements DumperInterface
+{
+    /**
+     * A template for the relative paths to files.
+     *
+     * @var string
+     */
+    protected $relativePathTemplate = '%domain%.%locale%.%extension%';
+
+    /**
+     * Sets the template for the relative paths to files.
+     *
+     * @param string $relativePathTemplate A template for the relative paths to files
+     */
+    public function setRelativePathTemplate(string $relativePathTemplate)
+    {
+        $this->relativePathTemplate = $relativePathTemplate;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dump(MessageCatalogue $messages, array $options = [])
+    {
+        if (!\array_key_exists('path', $options)) {
+            throw new InvalidArgumentException('The file dumper needs a path option.');
+        }
+
+        // save a file for each domain
+        foreach ($messages->getDomains() as $domain) {
+            $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
+            if (!file_exists($fullpath)) {
+                $directory = \dirname($fullpath);
+                if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
+                    throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
+                }
+            }
+
+            $intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX;
+            $intlMessages = $messages->all($intlDomain);
+
+            if ($intlMessages) {
+                $intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale());
+                file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options));
+
+                $messages->replace([], $intlDomain);
+
+                try {
+                    if ($messages->all($domain)) {
+                        file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
+                    }
+                    continue;
+                } finally {
+                    $messages->replace($intlMessages, $intlDomain);
+                }
+            }
+
+            file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
+        }
+    }
+
+    /**
+     * Transforms a domain of a message catalogue to its string representation.
+     *
+     * @return string representation
+     */
+    abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []);
+
+    /**
+     * Gets the file extension of the dumper.
+     *
+     * @return string file extension
+     */
+    abstract protected function getExtension();
+
+    /**
+     * Gets the relative file path using the template.
+     */
+    private function getRelativePath(string $domain, string $locale): string
+    {
+        return strtr($this->relativePathTemplate, [
+            '%domain%' => $domain,
+            '%locale%' => $locale,
+            '%extension%' => $this->getExtension(),
+        ]);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IcuResFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IcuResFileDumper.php
new file mode 100644
index 0000000..cdc5991
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IcuResFileDumper.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IcuResFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $relativePathTemplate = '%domain%/%locale%.%extension%';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $data = $indexes = $resources = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $indexes .= pack('v', \strlen($data) + 28);
+            $data .= $source."\0";
+        }
+
+        $data .= $this->writePadding($data);
+
+        $keyTop = $this->getPosition($data);
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $resources .= pack('V', $this->getPosition($data));
+
+            $data .= pack('V', \strlen($target))
+                .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8')
+                .$this->writePadding($data)
+                  ;
+        }
+
+        $resOffset = $this->getPosition($data);
+
+        $data .= pack('v', \count($messages->all($domain)))
+            .$indexes
+            .$this->writePadding($data)
+            .$resources
+              ;
+
+        $bundleTop = $this->getPosition($data);
+
+        $root = pack('V7',
+            $resOffset + (2 << 28), // Resource Offset + Resource Type
+            6,                      // Index length
+            $keyTop,                        // Index keys top
+            $bundleTop,                     // Index resources top
+            $bundleTop,                     // Index bundle top
+            \count($messages->all($domain)), // Index max table length
+            0                               // Index attributes
+        );
+
+        $header = pack('vC2v4C12@32',
+            32,                     // Header size
+            0xDA, 0x27,             // Magic number 1 and 2
+            20, 0, 0, 2,            // Rest of the header, ..., Size of a char
+            0x52, 0x65, 0x73, 0x42, // Data format identifier
+            1, 2, 0, 0,             // Data version
+            1, 4, 0, 0              // Unicode version
+        );
+
+        return $header.$root.$data;
+    }
+
+    private function writePadding(string $data): ?string
+    {
+        $padding = \strlen($data) % 4;
+
+        return $padding ? str_repeat("\xAA", 4 - $padding) : null;
+    }
+
+    private function getPosition(string $data)
+    {
+        return (\strlen($data) + 28) / 4;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'res';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IniFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IniFileDumper.php
new file mode 100644
index 0000000..93c900a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IniFileDumper.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IniFileDumper generates an ini formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IniFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $output = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $escapeTarget = str_replace('"', '\"', $target);
+            $output .= $source.'="'.$escapeTarget."\"\n";
+        }
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'ini';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/JsonFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/JsonFileDumper.php
new file mode 100644
index 0000000..34c0b56
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/JsonFileDumper.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * JsonFileDumper generates an json formatted string representation of a message catalogue.
+ *
+ * @author singles
+ */
+class JsonFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $flags = $options['json_encoding'] ?? \JSON_PRETTY_PRINT;
+
+        return json_encode($messages->all($domain), $flags);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'json';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/MoFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/MoFileDumper.php
new file mode 100644
index 0000000..54d0da8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/MoFileDumper.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Loader\MoFileLoader;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * MoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class MoFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $sources = $targets = $sourceOffsets = $targetOffsets = '';
+        $offsets = [];
+        $size = 0;
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $offsets[] = array_map('strlen', [$sources, $source, $targets, $target]);
+            $sources .= "\0".$source;
+            $targets .= "\0".$target;
+            ++$size;
+        }
+
+        $header = [
+            'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
+            'formatRevision' => 0,
+            'count' => $size,
+            'offsetId' => MoFileLoader::MO_HEADER_SIZE,
+            'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
+            'sizeHashes' => 0,
+            'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
+        ];
+
+        $sourcesSize = \strlen($sources);
+        $sourcesStart = $header['offsetHashes'] + 1;
+
+        foreach ($offsets as $offset) {
+            $sourceOffsets .= $this->writeLong($offset[1])
+                          .$this->writeLong($offset[0] + $sourcesStart);
+            $targetOffsets .= $this->writeLong($offset[3])
+                          .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
+        }
+
+        $output = implode('', array_map([$this, 'writeLong'], $header))
+               .$sourceOffsets
+               .$targetOffsets
+               .$sources
+               .$targets
+                ;
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'mo';
+    }
+
+    private function writeLong($str): string
+    {
+        return pack('V*', $str);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PhpFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PhpFileDumper.php
new file mode 100644
index 0000000..6163b52
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PhpFileDumper.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PhpFileDumper generates PHP files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class PhpFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'php';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PoFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PoFileDumper.php
new file mode 100644
index 0000000..0d82281
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PoFileDumper.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class PoFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $output = 'msgid ""'."\n";
+        $output .= 'msgstr ""'."\n";
+        $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n";
+        $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n";
+        $output .= '"Language: '.$messages->getLocale().'\n"'."\n";
+        $output .= "\n";
+
+        $newLine = false;
+        foreach ($messages->all($domain) as $source => $target) {
+            if ($newLine) {
+                $output .= "\n";
+            } else {
+                $newLine = true;
+            }
+            $metadata = $messages->getMetadata($source, $domain);
+
+            if (isset($metadata['comments'])) {
+                $output .= $this->formatComments($metadata['comments']);
+            }
+            if (isset($metadata['flags'])) {
+                $output .= $this->formatComments(implode(',', (array) $metadata['flags']), ',');
+            }
+            if (isset($metadata['sources'])) {
+                $output .= $this->formatComments(implode(' ', (array) $metadata['sources']), ':');
+            }
+
+            $sourceRules = $this->getStandardRules($source);
+            $targetRules = $this->getStandardRules($target);
+            if (2 == \count($sourceRules) && [] !== $targetRules) {
+                $output .= sprintf('msgid "%s"'."\n", $this->escape($sourceRules[0]));
+                $output .= sprintf('msgid_plural "%s"'."\n", $this->escape($sourceRules[1]));
+                foreach ($targetRules as $i => $targetRule) {
+                    $output .= sprintf('msgstr[%d] "%s"'."\n", $i, $this->escape($targetRule));
+                }
+            } else {
+                $output .= sprintf('msgid "%s"'."\n", $this->escape($source));
+                $output .= sprintf('msgstr "%s"'."\n", $this->escape($target));
+            }
+        }
+
+        return $output;
+    }
+
+    private function getStandardRules(string $id)
+    {
+        // Partly copied from TranslatorTrait::trans.
+        $parts = [];
+        if (preg_match('/^\|++$/', $id)) {
+            $parts = explode('|', $id);
+        } elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) {
+            $parts = $matches[0];
+        }
+
+        $intervalRegexp = <<<'EOF'
+/^(?P<interval>
+    ({\s*
+        (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
+    \s*})
+
+        |
+
+    (?P<left_delimiter>[\[\]])
+        \s*
+        (?P<left>-Inf|\-?\d+(\.\d+)?)
+        \s*,\s*
+        (?P<right>\+?Inf|\-?\d+(\.\d+)?)
+        \s*
+    (?P<right_delimiter>[\[\]])
+)\s*(?P<message>.*?)$/xs
+EOF;
+
+        $standardRules = [];
+        foreach ($parts as $part) {
+            $part = trim(str_replace('||', '|', $part));
+
+            if (preg_match($intervalRegexp, $part)) {
+                // Explicit rule is not a standard rule.
+                return [];
+            } else {
+                $standardRules[] = $part;
+            }
+        }
+
+        return $standardRules;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'po';
+    }
+
+    private function escape(string $str): string
+    {
+        return addcslashes($str, "\0..\37\42\134");
+    }
+
+    private function formatComments($comments, string $prefix = ''): ?string
+    {
+        $output = null;
+
+        foreach ((array) $comments as $comment) {
+            $output .= sprintf('#%s %s'."\n", $prefix, $comment);
+        }
+
+        return $output;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/QtFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/QtFileDumper.php
new file mode 100644
index 0000000..406e9f0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/QtFileDumper.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtFileDumper generates ts files from a message catalogue.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QtFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+        $ts = $dom->appendChild($dom->createElement('TS'));
+        $context = $ts->appendChild($dom->createElement('context'));
+        $context->appendChild($dom->createElement('name', $domain));
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $message = $context->appendChild($dom->createElement('message'));
+            $metadata = $messages->getMetadata($source, $domain);
+            if (isset($metadata['sources'])) {
+                foreach ((array) $metadata['sources'] as $location) {
+                    $loc = explode(':', $location, 2);
+                    $location = $message->appendChild($dom->createElement('location'));
+                    $location->setAttribute('filename', $loc[0]);
+                    if (isset($loc[1])) {
+                        $location->setAttribute('line', $loc[1]);
+                    }
+                }
+            }
+            $message->appendChild($dom->createElement('source', $source));
+            $message->appendChild($dom->createElement('translation', $target));
+        }
+
+        return $dom->saveXML();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'ts';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/XliffFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/XliffFileDumper.php
new file mode 100644
index 0000000..f7dbdcd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/XliffFileDumper.php
@@ -0,0 +1,203 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * XliffFileDumper generates xliff files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class XliffFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $xliffVersion = '1.2';
+        if (\array_key_exists('xliff_version', $options)) {
+            $xliffVersion = $options['xliff_version'];
+        }
+
+        if (\array_key_exists('default_locale', $options)) {
+            $defaultLocale = $options['default_locale'];
+        } else {
+            $defaultLocale = \Locale::getDefault();
+        }
+
+        if ('1.2' === $xliffVersion) {
+            return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
+        }
+        if ('2.0' === $xliffVersion) {
+            return $this->dumpXliff2($defaultLocale, $messages, $domain);
+        }
+
+        throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'xlf';
+    }
+
+    private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?string $domain, array $options = [])
+    {
+        $toolInfo = ['tool-id' => 'symfony', 'tool-name' => 'Symfony'];
+        if (\array_key_exists('tool_info', $options)) {
+            $toolInfo = array_merge($toolInfo, $options['tool_info']);
+        }
+
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+
+        $xliff = $dom->appendChild($dom->createElement('xliff'));
+        $xliff->setAttribute('version', '1.2');
+        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
+
+        $xliffFile = $xliff->appendChild($dom->createElement('file'));
+        $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
+        $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
+        $xliffFile->setAttribute('datatype', 'plaintext');
+        $xliffFile->setAttribute('original', 'file.ext');
+
+        $xliffHead = $xliffFile->appendChild($dom->createElement('header'));
+        $xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
+        foreach ($toolInfo as $id => $value) {
+            $xliffTool->setAttribute($id, $value);
+        }
+
+        $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
+        foreach ($messages->all($domain) as $source => $target) {
+            $translation = $dom->createElement('trans-unit');
+
+            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
+            $translation->setAttribute('resname', $source);
+
+            $s = $translation->appendChild($dom->createElement('source'));
+            $s->appendChild($dom->createTextNode($source));
+
+            // Does the target contain characters requiring a CDATA section?
+            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
+
+            $targetElement = $dom->createElement('target');
+            $metadata = $messages->getMetadata($source, $domain);
+            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
+                foreach ($metadata['target-attributes'] as $name => $value) {
+                    $targetElement->setAttribute($name, $value);
+                }
+            }
+            $t = $translation->appendChild($targetElement);
+            $t->appendChild($text);
+
+            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
+                foreach ($metadata['notes'] as $note) {
+                    if (!isset($note['content'])) {
+                        continue;
+                    }
+
+                    $n = $translation->appendChild($dom->createElement('note'));
+                    $n->appendChild($dom->createTextNode($note['content']));
+
+                    if (isset($note['priority'])) {
+                        $n->setAttribute('priority', $note['priority']);
+                    }
+
+                    if (isset($note['from'])) {
+                        $n->setAttribute('from', $note['from']);
+                    }
+                }
+            }
+
+            $xliffBody->appendChild($translation);
+        }
+
+        return $dom->saveXML();
+    }
+
+    private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?string $domain)
+    {
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+
+        $xliff = $dom->appendChild($dom->createElement('xliff'));
+        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
+        $xliff->setAttribute('version', '2.0');
+        $xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
+        $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
+
+        $xliffFile = $xliff->appendChild($dom->createElement('file'));
+        if (str_ends_with($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
+            $xliffFile->setAttribute('id', substr($domain, 0, -\strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)).'.'.$messages->getLocale());
+        } else {
+            $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
+        }
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $translation = $dom->createElement('unit');
+            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
+
+            if (\strlen($source) <= 80) {
+                $translation->setAttribute('name', $source);
+            }
+
+            $metadata = $messages->getMetadata($source, $domain);
+
+            // Add notes section
+            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
+                $notesElement = $dom->createElement('notes');
+                foreach ($metadata['notes'] as $note) {
+                    $n = $dom->createElement('note');
+                    $n->appendChild($dom->createTextNode($note['content'] ?? ''));
+                    unset($note['content']);
+
+                    foreach ($note as $name => $value) {
+                        $n->setAttribute($name, $value);
+                    }
+                    $notesElement->appendChild($n);
+                }
+                $translation->appendChild($notesElement);
+            }
+
+            $segment = $translation->appendChild($dom->createElement('segment'));
+
+            $s = $segment->appendChild($dom->createElement('source'));
+            $s->appendChild($dom->createTextNode($source));
+
+            // Does the target contain characters requiring a CDATA section?
+            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
+
+            $targetElement = $dom->createElement('target');
+            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
+                foreach ($metadata['target-attributes'] as $name => $value) {
+                    $targetElement->setAttribute($name, $value);
+                }
+            }
+            $t = $segment->appendChild($targetElement);
+            $t->appendChild($text);
+
+            $xliffFile->appendChild($translation);
+        }
+
+        return $dom->saveXML();
+    }
+
+    private function hasMetadataArrayInfo(string $key, array $metadata = null): bool
+    {
+        return is_iterable($metadata[$key] ?? null);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/YamlFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/YamlFileDumper.php
new file mode 100644
index 0000000..0b21e8c
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/YamlFileDumper.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Exception\LogicException;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Util\ArrayConverter;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileDumper generates yaml files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class YamlFileDumper extends FileDumper
+{
+    private $extension;
+
+    public function __construct(string $extension = 'yml')
+    {
+        $this->extension = $extension;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        if (!class_exists(Yaml::class)) {
+            throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
+        }
+
+        $data = $messages->all($domain);
+
+        if (isset($options['as_tree']) && $options['as_tree']) {
+            $data = ArrayConverter::expandToTree($data);
+        }
+
+        if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
+            return Yaml::dump($data, $inline);
+        }
+
+        return Yaml::dump($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return $this->extension;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ExceptionInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..8f9c54e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ExceptionInterface extends \Throwable
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/IncompleteDsnException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/IncompleteDsnException.php
new file mode 100644
index 0000000..cb0ce02
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/IncompleteDsnException.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+class IncompleteDsnException extends InvalidArgumentException
+{
+    public function __construct(string $message, string $dsn = null, \Throwable $previous = null)
+    {
+        if ($dsn) {
+            $message = sprintf('Invalid "%s" provider DSN: ', $dsn).$message;
+        }
+
+        parent::__construct($message, 0, $previous);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidArgumentException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..90d0669
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidArgumentException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Base InvalidArgumentException for the Translation component.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidResourceException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidResourceException.php
new file mode 100644
index 0000000..cf07943
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidResourceException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource cannot be loaded.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/LogicException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/LogicException.php
new file mode 100644
index 0000000..9019c7e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/LogicException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Base LogicException for Translation component.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class LogicException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/MissingRequiredOptionException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/MissingRequiredOptionException.php
new file mode 100644
index 0000000..2b5f808
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/MissingRequiredOptionException.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * @author Oskar Stark <oskarstark@googlemail.com>
+ */
+class MissingRequiredOptionException extends IncompleteDsnException
+{
+    public function __construct(string $option, string $dsn = null, \Throwable $previous = null)
+    {
+        $message = sprintf('The option "%s" is required but missing.', $option);
+
+        parent::__construct($message, $dsn, $previous);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/NotFoundResourceException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/NotFoundResourceException.php
new file mode 100644
index 0000000..cff73ae
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/NotFoundResourceException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource does not exist.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderException.php
new file mode 100644
index 0000000..659c6d7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderException.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+use Symfony\Contracts\HttpClient\ResponseInterface;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @experimental in 5.3
+ */
+class ProviderException extends RuntimeException implements ProviderExceptionInterface
+{
+    private $response;
+    private $debug;
+
+    public function __construct(string $message, ResponseInterface $response, int $code = 0, \Exception $previous = null)
+    {
+        $this->response = $response;
+        $this->debug .= $response->getInfo('debug') ?? '';
+
+        parent::__construct($message, $code, $previous);
+    }
+
+    public function getResponse(): ResponseInterface
+    {
+        return $this->response;
+    }
+
+    public function getDebug(): string
+    {
+        return $this->debug;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderExceptionInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderExceptionInterface.php
new file mode 100644
index 0000000..8cf1c51
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderExceptionInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @experimental in 5.3
+ */
+interface ProviderExceptionInterface extends ExceptionInterface
+{
+    /*
+     * Returns debug info coming from the Symfony\Contracts\HttpClient\ResponseInterface
+     */
+    public function getDebug(): string;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/RuntimeException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/RuntimeException.php
new file mode 100644
index 0000000..dcd7940
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/RuntimeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Base RuntimeException for the Translation component.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/UnsupportedSchemeException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/UnsupportedSchemeException.php
new file mode 100644
index 0000000..7fbaa8f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/UnsupportedSchemeException.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+use Symfony\Component\Translation\Bridge;
+use Symfony\Component\Translation\Provider\Dsn;
+
+class UnsupportedSchemeException extends LogicException
+{
+    private const SCHEME_TO_PACKAGE_MAP = [
+        'crowdin' => [
+            'class' => Bridge\Crowdin\CrowdinProviderFactory::class,
+            'package' => 'symfony/crowdin-translation-provider',
+        ],
+        'loco' => [
+            'class' => Bridge\Loco\LocoProviderFactory::class,
+            'package' => 'symfony/loco-translation-provider',
+        ],
+        'lokalise' => [
+            'class' => Bridge\Lokalise\LokaliseProviderFactory::class,
+            'package' => 'symfony/lokalise-translation-provider',
+        ],
+    ];
+
+    public function __construct(Dsn $dsn, string $name = null, array $supported = [])
+    {
+        $provider = $dsn->getScheme();
+        if (false !== $pos = strpos($provider, '+')) {
+            $provider = substr($provider, 0, $pos);
+        }
+        $package = self::SCHEME_TO_PACKAGE_MAP[$provider] ?? null;
+        if ($package && !class_exists($package['class'])) {
+            parent::__construct(sprintf('Unable to synchronize translations via "%s" as the provider is not installed; try running "composer require %s".', $provider, $package['package']));
+
+            return;
+        }
+
+        $message = sprintf('The "%s" scheme is not supported', $dsn->getScheme());
+        if ($name && $supported) {
+            $message .= sprintf('; supported schemes for translation provider "%s" are: "%s"', $name, implode('", "', $supported));
+        }
+
+        parent::__construct($message.'.');
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/AbstractFileExtractor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/AbstractFileExtractor.php
new file mode 100644
index 0000000..729dd17
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/AbstractFileExtractor.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * Base class used by classes that extract translation messages from files.
+ *
+ * @author Marcos D. Sánchez <marcosdsanchez@gmail.com>
+ */
+abstract class AbstractFileExtractor
+{
+    /**
+     * @param string|iterable $resource Files, a file or a directory
+     *
+     * @return iterable
+     */
+    protected function extractFiles($resource)
+    {
+        if (is_iterable($resource)) {
+            $files = [];
+            foreach ($resource as $file) {
+                if ($this->canBeExtracted($file)) {
+                    $files[] = $this->toSplFileInfo($file);
+                }
+            }
+        } elseif (is_file($resource)) {
+            $files = $this->canBeExtracted($resource) ? [$this->toSplFileInfo($resource)] : [];
+        } else {
+            $files = $this->extractFromDirectory($resource);
+        }
+
+        return $files;
+    }
+
+    private function toSplFileInfo(string $file): \SplFileInfo
+    {
+        return new \SplFileInfo($file);
+    }
+
+    /**
+     * @return bool
+     *
+     * @throws InvalidArgumentException
+     */
+    protected function isFile(string $file)
+    {
+        if (!is_file($file)) {
+            throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
+        }
+
+        return true;
+    }
+
+    /**
+     * @return bool
+     */
+    abstract protected function canBeExtracted(string $file);
+
+    /**
+     * @param string|array $resource Files, a file or a directory
+     *
+     * @return iterable files to be extracted
+     */
+    abstract protected function extractFromDirectory($resource);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ChainExtractor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ChainExtractor.php
new file mode 100644
index 0000000..95dcf15
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ChainExtractor.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ChainExtractor extracts translation messages from template files.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class ChainExtractor implements ExtractorInterface
+{
+    /**
+     * The extractors.
+     *
+     * @var ExtractorInterface[]
+     */
+    private $extractors = [];
+
+    /**
+     * Adds a loader to the translation extractor.
+     */
+    public function addExtractor(string $format, ExtractorInterface $extractor)
+    {
+        $this->extractors[$format] = $extractor;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setPrefix(string $prefix)
+    {
+        foreach ($this->extractors as $extractor) {
+            $extractor->setPrefix($prefix);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function extract($directory, MessageCatalogue $catalogue)
+    {
+        foreach ($this->extractors as $extractor) {
+            $extractor->extract($directory, $catalogue);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ExtractorInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ExtractorInterface.php
new file mode 100644
index 0000000..e1db8a9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ExtractorInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * Extracts translation messages from a directory or files to the catalogue.
+ * New found messages are injected to the catalogue using the prefix.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface ExtractorInterface
+{
+    /**
+     * Extracts translation messages from files, a file or a directory to the catalogue.
+     *
+     * @param string|iterable<string> $resource Files, a file or a directory
+     */
+    public function extract($resource, MessageCatalogue $catalogue);
+
+    /**
+     * Sets the prefix that should be used for new found messages.
+     */
+    public function setPrefix(string $prefix);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpExtractor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpExtractor.php
new file mode 100644
index 0000000..c5efb5f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpExtractor.php
@@ -0,0 +1,336 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PhpExtractor extracts translation messages from a PHP template.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
+{
+    public const MESSAGE_TOKEN = 300;
+    public const METHOD_ARGUMENTS_TOKEN = 1000;
+    public const DOMAIN_TOKEN = 1001;
+
+    /**
+     * Prefix for new found message.
+     *
+     * @var string
+     */
+    private $prefix = '';
+
+    /**
+     * The sequence that captures translation messages.
+     *
+     * @var array
+     */
+    protected $sequences = [
+        [
+            '->',
+            'trans',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            '->',
+            'trans',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            'new',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            'new',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            'new',
+            '\\',
+            'Symfony',
+            '\\',
+            'Component',
+            '\\',
+            'Translation',
+            '\\',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            'new',
+            '\Symfony\Component\Translation\TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            'new',
+            '\\',
+            'Symfony',
+            '\\',
+            'Component',
+            '\\',
+            'Translation',
+            '\\',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            'new',
+            '\Symfony\Component\Translation\TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            't',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            't',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+    ];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function extract($resource, MessageCatalogue $catalog)
+    {
+        $files = $this->extractFiles($resource);
+        foreach ($files as $file) {
+            $this->parseTokens(token_get_all(file_get_contents($file)), $catalog, $file);
+
+            gc_mem_caches();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setPrefix(string $prefix)
+    {
+        $this->prefix = $prefix;
+    }
+
+    /**
+     * Normalizes a token.
+     *
+     * @param mixed $token
+     *
+     * @return string|null
+     */
+    protected function normalizeToken($token)
+    {
+        if (isset($token[1]) && 'b"' !== $token) {
+            return $token[1];
+        }
+
+        return $token;
+    }
+
+    /**
+     * Seeks to a non-whitespace token.
+     */
+    private function seekToNextRelevantToken(\Iterator $tokenIterator)
+    {
+        for (; $tokenIterator->valid(); $tokenIterator->next()) {
+            $t = $tokenIterator->current();
+            if (\T_WHITESPACE !== $t[0]) {
+                break;
+            }
+        }
+    }
+
+    private function skipMethodArgument(\Iterator $tokenIterator)
+    {
+        $openBraces = 0;
+
+        for (; $tokenIterator->valid(); $tokenIterator->next()) {
+            $t = $tokenIterator->current();
+
+            if ('[' === $t[0] || '(' === $t[0]) {
+                ++$openBraces;
+            }
+
+            if (']' === $t[0] || ')' === $t[0]) {
+                --$openBraces;
+            }
+
+            if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Extracts the message from the iterator while the tokens
+     * match allowed message tokens.
+     */
+    private function getValue(\Iterator $tokenIterator)
+    {
+        $message = '';
+        $docToken = '';
+        $docPart = '';
+
+        for (; $tokenIterator->valid(); $tokenIterator->next()) {
+            $t = $tokenIterator->current();
+            if ('.' === $t) {
+                // Concatenate with next token
+                continue;
+            }
+            if (!isset($t[1])) {
+                break;
+            }
+
+            switch ($t[0]) {
+                case \T_START_HEREDOC:
+                    $docToken = $t[1];
+                    break;
+                case \T_ENCAPSED_AND_WHITESPACE:
+                case \T_CONSTANT_ENCAPSED_STRING:
+                    if ('' === $docToken) {
+                        $message .= PhpStringTokenParser::parse($t[1]);
+                    } else {
+                        $docPart = $t[1];
+                    }
+                    break;
+                case \T_END_HEREDOC:
+                    if ($indentation = strspn($t[1], ' ')) {
+                        $docPartWithLineBreaks = $docPart;
+                        $docPart = '';
+
+                        foreach (preg_split('~(\r\n|\n|\r)~', $docPartWithLineBreaks, -1, \PREG_SPLIT_DELIM_CAPTURE) as $str) {
+                            if (\in_array($str, ["\r\n", "\n", "\r"], true)) {
+                                $docPart .= $str;
+                            } else {
+                                $docPart .= substr($str, $indentation);
+                            }
+                        }
+                    }
+
+                    $message .= PhpStringTokenParser::parseDocString($docToken, $docPart);
+                    $docToken = '';
+                    $docPart = '';
+                    break;
+                case \T_WHITESPACE:
+                    break;
+                default:
+                    break 2;
+            }
+        }
+
+        return $message;
+    }
+
+    /**
+     * Extracts trans message from PHP tokens.
+     */
+    protected function parseTokens(array $tokens, MessageCatalogue $catalog, string $filename)
+    {
+        $tokenIterator = new \ArrayIterator($tokens);
+
+        for ($key = 0; $key < $tokenIterator->count(); ++$key) {
+            foreach ($this->sequences as $sequence) {
+                $message = '';
+                $domain = 'messages';
+                $tokenIterator->seek($key);
+
+                foreach ($sequence as $sequenceKey => $item) {
+                    $this->seekToNextRelevantToken($tokenIterator);
+
+                    if ($this->normalizeToken($tokenIterator->current()) === $item) {
+                        $tokenIterator->next();
+                        continue;
+                    } elseif (self::MESSAGE_TOKEN === $item) {
+                        $message = $this->getValue($tokenIterator);
+
+                        if (\count($sequence) === ($sequenceKey + 1)) {
+                            break;
+                        }
+                    } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
+                        $this->skipMethodArgument($tokenIterator);
+                    } elseif (self::DOMAIN_TOKEN === $item) {
+                        $domainToken = $this->getValue($tokenIterator);
+                        if ('' !== $domainToken) {
+                            $domain = $domainToken;
+                        }
+
+                        break;
+                    } else {
+                        break;
+                    }
+                }
+
+                if ($message) {
+                    $catalog->set($message, $this->prefix.$message, $domain);
+                    $metadata = $catalog->getMetadata($message, $domain) ?? [];
+                    $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename);
+                    $metadata['sources'][] = $normalizedFilename.':'.$tokens[$key][2];
+                    $catalog->setMetadata($message, $metadata, $domain);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * @return bool
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function canBeExtracted(string $file)
+    {
+        return $this->isFile($file) && 'php' === pathinfo($file, \PATHINFO_EXTENSION);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function extractFromDirectory($directory)
+    {
+        $finder = new Finder();
+
+        return $finder->files()->name('*.php')->in($directory);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpStringTokenParser.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpStringTokenParser.php
new file mode 100644
index 0000000..1d82caf
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpStringTokenParser.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+/*
+ * The following is derived from code at http://github.com/nikic/PHP-Parser
+ *
+ * Copyright (c) 2011 by Nikita Popov
+ *
+ * Some 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.
+ *
+ *     * The names of the contributors may not 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.
+ */
+
+class PhpStringTokenParser
+{
+    protected static $replacements = [
+        '\\' => '\\',
+        '$' => '$',
+        'n' => "\n",
+        'r' => "\r",
+        't' => "\t",
+        'f' => "\f",
+        'v' => "\v",
+        'e' => "\x1B",
+    ];
+
+    /**
+     * Parses a string token.
+     *
+     * @param string $str String token content
+     *
+     * @return string The parsed string
+     */
+    public static function parse(string $str)
+    {
+        $bLength = 0;
+        if ('b' === $str[0]) {
+            $bLength = 1;
+        }
+
+        if ('\'' === $str[$bLength]) {
+            return str_replace(
+                ['\\\\', '\\\''],
+                ['\\', '\''],
+                substr($str, $bLength + 1, -1)
+            );
+        } else {
+            return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
+        }
+    }
+
+    /**
+     * Parses escape sequences in strings (all string types apart from single quoted).
+     *
+     * @param string      $str   String without quotes
+     * @param string|null $quote Quote type
+     *
+     * @return string String with escape sequences parsed
+     */
+    public static function parseEscapeSequences(string $str, string $quote = null)
+    {
+        if (null !== $quote) {
+            $str = str_replace('\\'.$quote, $quote, $str);
+        }
+
+        return preg_replace_callback(
+            '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~',
+            [__CLASS__, 'parseCallback'],
+            $str
+        );
+    }
+
+    private static function parseCallback(array $matches): string
+    {
+        $str = $matches[1];
+
+        if (isset(self::$replacements[$str])) {
+            return self::$replacements[$str];
+        } elseif ('x' === $str[0] || 'X' === $str[0]) {
+            return \chr(hexdec($str));
+        } else {
+            return \chr(octdec($str));
+        }
+    }
+
+    /**
+     * Parses a constant doc string.
+     *
+     * @param string $startToken Doc string start token content (<<<SMTHG)
+     * @param string $str        String token content
+     *
+     * @return string Parsed string
+     */
+    public static function parseDocString(string $startToken, string $str)
+    {
+        // strip last newline (thanks tokenizer for sticking it into the string!)
+        $str = preg_replace('~(\r\n|\n|\r)$~', '', $str);
+
+        // nowdoc string
+        if (str_contains($startToken, '\'')) {
+            return $str;
+        }
+
+        return self::parseEscapeSequences($str, null);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatter.php
new file mode 100644
index 0000000..f7f1c36
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatter.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\LogicException;
+
+/**
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class IntlFormatter implements IntlFormatterInterface
+{
+    private $hasMessageFormatter;
+    private $cache = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatIntl(string $message, string $locale, array $parameters = []): string
+    {
+        // MessageFormatter constructor throws an exception if the message is empty
+        if ('' === $message) {
+            return '';
+        }
+
+        if (!$formatter = $this->cache[$locale][$message] ?? null) {
+            if (!($this->hasMessageFormatter ?? $this->hasMessageFormatter = class_exists(\MessageFormatter::class))) {
+                throw new LogicException('Cannot parse message translation: please install the "intl" PHP extension or the "symfony/polyfill-intl-messageformatter" package.');
+            }
+            try {
+                $this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message);
+            } catch (\IntlException $e) {
+                throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): ', intl_get_error_code()).intl_get_error_message(), 0, $e);
+            }
+        }
+
+        foreach ($parameters as $key => $value) {
+            if (\in_array($key[0] ?? null, ['%', '{'], true)) {
+                unset($parameters[$key]);
+                $parameters[trim($key, '%{ }')] = $value;
+            }
+        }
+
+        if (false === $message = $formatter->format($parameters)) {
+            throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): ', $formatter->getErrorCode()).$formatter->getErrorMessage());
+        }
+
+        return $message;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatterInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatterInterface.php
new file mode 100644
index 0000000..02fc6ac
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatterInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+/**
+ * Formats ICU message patterns.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+interface IntlFormatterInterface
+{
+    /**
+     * Formats a localized message using rules defined by ICU MessageFormat.
+     *
+     * @see http://icu-project.org/apiref/icu4c/classMessageFormat.html#details
+     */
+    public function formatIntl(string $message, string $locale, array $parameters = []): string;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatter.php
new file mode 100644
index 0000000..0407964
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatter.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+use Symfony\Component\Translation\IdentityTranslator;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+// Help opcache.preload discover always-needed symbols
+class_exists(IntlFormatter::class);
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterface
+{
+    private $translator;
+    private $intlFormatter;
+
+    /**
+     * @param TranslatorInterface|null $translator An identity translator to use as selector for pluralization
+     */
+    public function __construct(TranslatorInterface $translator = null, IntlFormatterInterface $intlFormatter = null)
+    {
+        $this->translator = $translator ?? new IdentityTranslator();
+        $this->intlFormatter = $intlFormatter ?? new IntlFormatter();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(string $message, string $locale, array $parameters = [])
+    {
+        if ($this->translator instanceof TranslatorInterface) {
+            return $this->translator->trans($message, $parameters, null, $locale);
+        }
+
+        return strtr($message, $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatIntl(string $message, string $locale, array $parameters = []): string
+    {
+        return $this->intlFormatter->formatIntl($message, $locale, $parameters);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatterInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatterInterface.php
new file mode 100644
index 0000000..b85dbfd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatterInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+/**
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+interface MessageFormatterInterface
+{
+    /**
+     * Formats a localized message pattern with given arguments.
+     *
+     * @param string $message    The message (may also be an object that can be cast to string)
+     * @param string $locale     The message locale
+     * @param array  $parameters An array of parameters for the message
+     *
+     * @return string
+     */
+    public function format(string $message, string $locale, array $parameters = []);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/IdentityTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/IdentityTranslator.php
new file mode 100644
index 0000000..46875ed
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/IdentityTranslator.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+use Symfony\Contracts\Translation\TranslatorTrait;
+
+/**
+ * IdentityTranslator does not translate anything.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class IdentityTranslator implements TranslatorInterface, LocaleAwareInterface
+{
+    use TranslatorTrait;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LICENSE
new file mode 100644
index 0000000..9ff2d0d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2021 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/ArrayLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/ArrayLoader.php
new file mode 100644
index 0000000..0758da8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/ArrayLoader.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ArrayLoader loads translations from a PHP array.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ArrayLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        $resource = $this->flatten($resource);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($resource, $domain);
+
+        return $catalogue;
+    }
+
+    /**
+     * Flattens an nested array of translations.
+     *
+     * The scheme used is:
+     *   'key' => ['key2' => ['key3' => 'value']]
+     * Becomes:
+     *   'key.key2.key3' => 'value'
+     */
+    private function flatten(array $messages): array
+    {
+        $result = [];
+        foreach ($messages as $key => $value) {
+            if (\is_array($value)) {
+                foreach ($this->flatten($value) as $k => $v) {
+                    $result[$key.'.'.$k] = $v;
+                }
+            } else {
+                $result[$key] = $value;
+            }
+        }
+
+        return $result;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/CsvFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/CsvFileLoader.php
new file mode 100644
index 0000000..8d5d4db
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/CsvFileLoader.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+
+/**
+ * CsvFileLoader loads translations from CSV files.
+ *
+ * @author Saša Stamenković <umpirsky@gmail.com>
+ */
+class CsvFileLoader extends FileLoader
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+    private $escape = '\\';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $messages = [];
+
+        try {
+            $file = new \SplFileObject($resource, 'rb');
+        } catch (\RuntimeException $e) {
+            throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
+        }
+
+        $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
+        $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
+
+        foreach ($file as $data) {
+            if (false === $data) {
+                continue;
+            }
+
+            if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === \count($data)) {
+                $messages[$data[0]] = $data[1];
+            }
+        }
+
+        return $messages;
+    }
+
+    /**
+     * Sets the delimiter, enclosure, and escape character for CSV.
+     */
+    public function setCsvControl(string $delimiter = ';', string $enclosure = '"', string $escape = '\\')
+    {
+        $this->delimiter = $delimiter;
+        $this->enclosure = $enclosure;
+        $this->escape = $escape;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/FileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/FileLoader.php
new file mode 100644
index 0000000..4725ea6
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/FileLoader.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+abstract class FileLoader extends ArrayLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = $this->loadResource($resource);
+
+        // empty resource
+        if (null === $messages) {
+            $messages = [];
+        }
+
+        // not an array
+        if (!\is_array($messages)) {
+            throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists(FileResource::class)) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * @return array
+     *
+     * @throws InvalidResourceException if stream content has an invalid format
+     */
+    abstract protected function loadResource(string $resource);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuDatFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuDatFileLoader.php
new file mode 100644
index 0000000..2a1aecc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuDatFileLoader.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuDatFileLoader extends IcuResFileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!stream_is_local($resource.'.dat')) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource.'.dat')) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $rb = new \ResourceBundle($locale, $resource);
+        } catch (\Exception $e) {
+            $rb = null;
+        }
+
+        if (!$rb) {
+            throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+
+        if (class_exists(FileResource::class)) {
+            $catalogue->addResource(new FileResource($resource.'.dat'));
+        }
+
+        return $catalogue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuResFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuResFileLoader.php
new file mode 100644
index 0000000..64bbd3e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuResFileLoader.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\DirectoryResource;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuResFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!is_dir($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $rb = new \ResourceBundle($locale, $resource);
+        } catch (\Exception $e) {
+            $rb = null;
+        }
+
+        if (!$rb) {
+            throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+
+        if (class_exists(DirectoryResource::class)) {
+            $catalogue->addResource(new DirectoryResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Flattens an ResourceBundle.
+     *
+     * The scheme used is:
+     *   key { key2 { key3 { "value" } } }
+     * Becomes:
+     *   'key.key2.key3' => 'value'
+     *
+     * This function takes an array by reference and will modify it
+     *
+     * @param \ResourceBundle $rb       The ResourceBundle that will be flattened
+     * @param array           $messages Used internally for recursive calls
+     * @param string          $path     Current path being parsed, used internally for recursive calls
+     *
+     * @return array the flattened ResourceBundle
+     */
+    protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null)
+    {
+        foreach ($rb as $key => $value) {
+            $nodePath = $path ? $path.'.'.$key : $key;
+            if ($value instanceof \ResourceBundle) {
+                $this->flatten($value, $messages, $nodePath);
+            } else {
+                $messages[$nodePath] = $value;
+            }
+        }
+
+        return $messages;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IniFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IniFileLoader.php
new file mode 100644
index 0000000..7398f77
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IniFileLoader.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+/**
+ * IniFileLoader loads translations from an ini file.
+ *
+ * @author stealth35
+ */
+class IniFileLoader extends FileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        return parse_ini_file($resource, true);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/JsonFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/JsonFileLoader.php
new file mode 100644
index 0000000..5aefba0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/JsonFileLoader.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+
+/**
+ * JsonFileLoader loads translations from an json file.
+ *
+ * @author singles
+ */
+class JsonFileLoader extends FileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $messages = [];
+        if ($data = file_get_contents($resource)) {
+            $messages = json_decode($data, true);
+
+            if (0 < $errorCode = json_last_error()) {
+                throw new InvalidResourceException('Error parsing JSON: '.$this->getJSONErrorMessage($errorCode));
+            }
+        }
+
+        return $messages;
+    }
+
+    /**
+     * Translates JSON_ERROR_* constant into meaningful message.
+     */
+    private function getJSONErrorMessage(int $errorCode): string
+    {
+        switch ($errorCode) {
+            case \JSON_ERROR_DEPTH:
+                return 'Maximum stack depth exceeded';
+            case \JSON_ERROR_STATE_MISMATCH:
+                return 'Underflow or the modes mismatch';
+            case \JSON_ERROR_CTRL_CHAR:
+                return 'Unexpected control character found';
+            case \JSON_ERROR_SYNTAX:
+                return 'Syntax error, malformed JSON';
+            case \JSON_ERROR_UTF8:
+                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+            default:
+                return 'Unknown error';
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/LoaderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/LoaderInterface.php
new file mode 100644
index 0000000..2073f2b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/LoaderInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * LoaderInterface is the interface implemented by all translation loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderInterface
+{
+    /**
+     * Loads a locale.
+     *
+     * @param mixed  $resource A resource
+     * @param string $locale   A locale
+     * @param string $domain   The domain
+     *
+     * @return MessageCatalogue A MessageCatalogue instance
+     *
+     * @throws NotFoundResourceException when the resource cannot be found
+     * @throws InvalidResourceException  when the resource cannot be loaded
+     */
+    public function load($resource, string $locale, string $domain = 'messages');
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/MoFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/MoFileLoader.php
new file mode 100644
index 0000000..0ff6549
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/MoFileLoader.php
@@ -0,0 +1,140 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ */
+class MoFileLoader extends FileLoader
+{
+    /**
+     * Magic used for validating the format of an MO file as well as
+     * detecting if the machine used to create that file was little endian.
+     */
+    public const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;
+
+    /**
+     * Magic used for validating the format of an MO file as well as
+     * detecting if the machine used to create that file was big endian.
+     */
+    public const MO_BIG_ENDIAN_MAGIC = 0xde120495;
+
+    /**
+     * The size of the header of an MO file in bytes.
+     */
+    public const MO_HEADER_SIZE = 28;
+
+    /**
+     * Parses machine object (MO) format, independent of the machine's endian it
+     * was created on. Both 32bit and 64bit systems are supported.
+     *
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $stream = fopen($resource, 'r');
+
+        $stat = fstat($stream);
+
+        if ($stat['size'] < self::MO_HEADER_SIZE) {
+            throw new InvalidResourceException('MO stream content has an invalid format.');
+        }
+        $magic = unpack('V1', fread($stream, 4));
+        $magic = hexdec(substr(dechex(current($magic)), -8));
+
+        if (self::MO_LITTLE_ENDIAN_MAGIC == $magic) {
+            $isBigEndian = false;
+        } elseif (self::MO_BIG_ENDIAN_MAGIC == $magic) {
+            $isBigEndian = true;
+        } else {
+            throw new InvalidResourceException('MO stream content has an invalid format.');
+        }
+
+        // formatRevision
+        $this->readLong($stream, $isBigEndian);
+        $count = $this->readLong($stream, $isBigEndian);
+        $offsetId = $this->readLong($stream, $isBigEndian);
+        $offsetTranslated = $this->readLong($stream, $isBigEndian);
+        // sizeHashes
+        $this->readLong($stream, $isBigEndian);
+        // offsetHashes
+        $this->readLong($stream, $isBigEndian);
+
+        $messages = [];
+
+        for ($i = 0; $i < $count; ++$i) {
+            $pluralId = null;
+            $translated = null;
+
+            fseek($stream, $offsetId + $i * 8);
+
+            $length = $this->readLong($stream, $isBigEndian);
+            $offset = $this->readLong($stream, $isBigEndian);
+
+            if ($length < 1) {
+                continue;
+            }
+
+            fseek($stream, $offset);
+            $singularId = fread($stream, $length);
+
+            if (str_contains($singularId, "\000")) {
+                [$singularId, $pluralId] = explode("\000", $singularId);
+            }
+
+            fseek($stream, $offsetTranslated + $i * 8);
+            $length = $this->readLong($stream, $isBigEndian);
+            $offset = $this->readLong($stream, $isBigEndian);
+
+            if ($length < 1) {
+                continue;
+            }
+
+            fseek($stream, $offset);
+            $translated = fread($stream, $length);
+
+            if (str_contains($translated, "\000")) {
+                $translated = explode("\000", $translated);
+            }
+
+            $ids = ['singular' => $singularId, 'plural' => $pluralId];
+            $item = compact('ids', 'translated');
+
+            if (!empty($item['ids']['singular'])) {
+                $id = $item['ids']['singular'];
+                if (isset($item['ids']['plural'])) {
+                    $id .= '|'.$item['ids']['plural'];
+                }
+                $messages[$id] = stripcslashes(implode('|', (array) $item['translated']));
+            }
+        }
+
+        fclose($stream);
+
+        return array_filter($messages);
+    }
+
+    /**
+     * Reads an unsigned long from stream respecting endianness.
+     *
+     * @param resource $stream
+     */
+    private function readLong($stream, bool $isBigEndian): int
+    {
+        $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
+        $result = current($result);
+
+        return (int) substr($result, -8);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PhpFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PhpFileLoader.php
new file mode 100644
index 0000000..85f1090
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PhpFileLoader.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+/**
+ * PhpFileLoader loads translations from PHP files returning an array of translations.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PhpFileLoader extends FileLoader
+{
+    private static $cache = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) {
+            self::$cache = null;
+        }
+
+        if (null === self::$cache) {
+            return require $resource;
+        }
+
+        if (isset(self::$cache[$resource])) {
+            return self::$cache[$resource];
+        }
+
+        return self::$cache[$resource] = require $resource;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PoFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PoFileLoader.php
new file mode 100644
index 0000000..ee143e2
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PoFileLoader.php
@@ -0,0 +1,149 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD https://github.com/UnionOfRAD/lithium
+ * @copyright Copyright (c) 2012, Clemens Tolboom
+ */
+class PoFileLoader extends FileLoader
+{
+    /**
+     * Parses portable object (PO) format.
+     *
+     * From https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
+     * we should be able to parse files having:
+     *
+     * white-space
+     * #  translator-comments
+     * #. extracted-comments
+     * #: reference...
+     * #, flag...
+     * #| msgid previous-untranslated-string
+     * msgid untranslated-string
+     * msgstr translated-string
+     *
+     * extra or different lines are:
+     *
+     * #| msgctxt previous-context
+     * #| msgid previous-untranslated-string
+     * msgctxt context
+     *
+     * #| msgid previous-untranslated-string-singular
+     * #| msgid_plural previous-untranslated-string-plural
+     * msgid untranslated-string-singular
+     * msgid_plural untranslated-string-plural
+     * msgstr[0] translated-string-case-0
+     * ...
+     * msgstr[N] translated-string-case-n
+     *
+     * The definition states:
+     * - white-space and comments are optional.
+     * - msgid "" that an empty singleline defines a header.
+     *
+     * This parser sacrifices some features of the reference implementation the
+     * differences to that implementation are as follows.
+     * - No support for comments spanning multiple lines.
+     * - Translator and extracted comments are treated as being the same type.
+     * - Message IDs are allowed to have other encodings as just US-ASCII.
+     *
+     * Items with an empty id are ignored.
+     *
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $stream = fopen($resource, 'r');
+
+        $defaults = [
+            'ids' => [],
+            'translated' => null,
+        ];
+
+        $messages = [];
+        $item = $defaults;
+        $flags = [];
+
+        while ($line = fgets($stream)) {
+            $line = trim($line);
+
+            if ('' === $line) {
+                // Whitespace indicated current item is done
+                if (!\in_array('fuzzy', $flags)) {
+                    $this->addMessage($messages, $item);
+                }
+                $item = $defaults;
+                $flags = [];
+            } elseif ('#,' === substr($line, 0, 2)) {
+                $flags = array_map('trim', explode(',', substr($line, 2)));
+            } elseif ('msgid "' === substr($line, 0, 7)) {
+                // We start a new msg so save previous
+                // TODO: this fails when comments or contexts are added
+                $this->addMessage($messages, $item);
+                $item = $defaults;
+                $item['ids']['singular'] = substr($line, 7, -1);
+            } elseif ('msgstr "' === substr($line, 0, 8)) {
+                $item['translated'] = substr($line, 8, -1);
+            } elseif ('"' === $line[0]) {
+                $continues = isset($item['translated']) ? 'translated' : 'ids';
+
+                if (\is_array($item[$continues])) {
+                    end($item[$continues]);
+                    $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
+                } else {
+                    $item[$continues] .= substr($line, 1, -1);
+                }
+            } elseif ('msgid_plural "' === substr($line, 0, 14)) {
+                $item['ids']['plural'] = substr($line, 14, -1);
+            } elseif ('msgstr[' === substr($line, 0, 7)) {
+                $size = strpos($line, ']');
+                $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
+            }
+        }
+        // save last item
+        if (!\in_array('fuzzy', $flags)) {
+            $this->addMessage($messages, $item);
+        }
+        fclose($stream);
+
+        return $messages;
+    }
+
+    /**
+     * Save a translation item to the messages.
+     *
+     * A .po file could contain by error missing plural indexes. We need to
+     * fix these before saving them.
+     */
+    private function addMessage(array &$messages, array $item)
+    {
+        if (!empty($item['ids']['singular'])) {
+            $id = stripcslashes($item['ids']['singular']);
+            if (isset($item['ids']['plural'])) {
+                $id .= '|'.stripcslashes($item['ids']['plural']);
+            }
+
+            $translated = (array) $item['translated'];
+            // PO are by definition indexed so sort by index.
+            ksort($translated);
+            // Make sure every index is filled.
+            end($translated);
+            $count = key($translated);
+            // Fill missing spots with '-'.
+            $empties = array_fill(0, $count + 1, '-');
+            $translated += $empties;
+            ksort($translated);
+
+            $messages[$id] = stripcslashes(implode('|', $translated));
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/QtFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/QtFileLoader.php
new file mode 100644
index 0000000..9cf2fe9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/QtFileLoader.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtFileLoader loads translations from QT Translations XML files.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QtFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!class_exists(XmlUtils::class)) {
+            throw new RuntimeException('Loading translations from the QT format requires the Symfony Config component.');
+        }
+
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $dom = XmlUtils::loadFile($resource);
+        } catch (\InvalidArgumentException $e) {
+            throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
+        }
+
+        $internalErrors = libxml_use_internal_errors(true);
+        libxml_clear_errors();
+
+        $xpath = new \DOMXPath($dom);
+        $nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');
+
+        $catalogue = new MessageCatalogue($locale);
+        if (1 == $nodes->length) {
+            $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
+            foreach ($translations as $translation) {
+                $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue;
+
+                if (!empty($translationValue)) {
+                    $catalogue->set(
+                        (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
+                        $translationValue,
+                        $domain
+                    );
+                }
+                $translation = $translation->nextSibling;
+            }
+
+            if (class_exists(FileResource::class)) {
+                $catalogue->addResource(new FileResource($resource));
+            }
+        }
+
+        libxml_use_internal_errors($internalErrors);
+
+        return $catalogue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/XliffFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/XliffFileLoader.php
new file mode 100644
index 0000000..35ad33e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/XliffFileLoader.php
@@ -0,0 +1,232 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Config\Util\Exception\InvalidXmlException;
+use Symfony\Component\Config\Util\Exception\XmlParsingException;
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Util\XliffUtils;
+
+/**
+ * XliffFileLoader loads translations from XLIFF files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class XliffFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!class_exists(XmlUtils::class)) {
+            throw new RuntimeException('Loading translations from the Xliff format requires the Symfony Config component.');
+        }
+
+        if (!$this->isXmlString($resource)) {
+            if (!stream_is_local($resource)) {
+                throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+            }
+
+            if (!file_exists($resource)) {
+                throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+            }
+
+            if (!is_file($resource)) {
+                throw new InvalidResourceException(sprintf('This is neither a file nor an XLIFF string "%s".', $resource));
+            }
+        }
+
+        try {
+            if ($this->isXmlString($resource)) {
+                $dom = XmlUtils::parse($resource);
+            } else {
+                $dom = XmlUtils::loadFile($resource);
+            }
+        } catch (\InvalidArgumentException | XmlParsingException | InvalidXmlException $e) {
+            throw new InvalidResourceException(sprintf('Unable to load "%s": ', $resource).$e->getMessage(), $e->getCode(), $e);
+        }
+
+        if ($errors = XliffUtils::validateSchema($dom)) {
+            throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: ', $resource).XliffUtils::getErrorsAsString($errors));
+        }
+
+        $catalogue = new MessageCatalogue($locale);
+        $this->extract($dom, $catalogue, $domain);
+
+        if (is_file($resource) && class_exists(FileResource::class)) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    private function extract(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
+    {
+        $xliffVersion = XliffUtils::getVersionNumber($dom);
+
+        if ('1.2' === $xliffVersion) {
+            $this->extractXliff1($dom, $catalogue, $domain);
+        }
+
+        if ('2.0' === $xliffVersion) {
+            $this->extractXliff2($dom, $catalogue, $domain);
+        }
+    }
+
+    /**
+     * Extract messages and metadata from DOMDocument into a MessageCatalogue.
+     */
+    private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
+    {
+        $xml = simplexml_import_dom($dom);
+        $encoding = $dom->encoding ? strtoupper($dom->encoding) : null;
+
+        $namespace = 'urn:oasis:names:tc:xliff:document:1.2';
+        $xml->registerXPathNamespace('xliff', $namespace);
+
+        foreach ($xml->xpath('//xliff:file') as $file) {
+            $fileAttributes = $file->attributes();
+
+            $file->registerXPathNamespace('xliff', $namespace);
+
+            foreach ($file->xpath('.//xliff:trans-unit') as $translation) {
+                $attributes = $translation->attributes();
+
+                if (!(isset($attributes['resname']) || isset($translation->source))) {
+                    continue;
+                }
+
+                $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
+                // If the xlf file has another encoding specified, try to convert it because
+                // simple_xml will always return utf-8 encoded values
+                $target = $this->utf8ToCharset((string) ($translation->target ?? $translation->source), $encoding);
+
+                $catalogue->set((string) $source, $target, $domain);
+
+                $metadata = [
+                    'source' => (string) $translation->source,
+                    'file' => [
+                        'original' => (string) $fileAttributes['original'],
+                    ],
+                ];
+                if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) {
+                    $metadata['notes'] = $notes;
+                }
+
+                if (isset($translation->target) && $translation->target->attributes()) {
+                    $metadata['target-attributes'] = [];
+                    foreach ($translation->target->attributes() as $key => $value) {
+                        $metadata['target-attributes'][$key] = (string) $value;
+                    }
+                }
+
+                if (isset($attributes['id'])) {
+                    $metadata['id'] = (string) $attributes['id'];
+                }
+
+                $catalogue->setMetadata((string) $source, $metadata, $domain);
+            }
+        }
+    }
+
+    private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
+    {
+        $xml = simplexml_import_dom($dom);
+        $encoding = $dom->encoding ? strtoupper($dom->encoding) : null;
+
+        $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');
+
+        foreach ($xml->xpath('//xliff:unit') as $unit) {
+            foreach ($unit->segment as $segment) {
+                $attributes = $unit->attributes();
+                $source = $attributes['name'] ?? $segment->source;
+
+                // If the xlf file has another encoding specified, try to convert it because
+                // simple_xml will always return utf-8 encoded values
+                $target = $this->utf8ToCharset((string) ($segment->target ?? $segment->source), $encoding);
+
+                $catalogue->set((string) $source, $target, $domain);
+
+                $metadata = [];
+                if (isset($segment->target) && $segment->target->attributes()) {
+                    $metadata['target-attributes'] = [];
+                    foreach ($segment->target->attributes() as $key => $value) {
+                        $metadata['target-attributes'][$key] = (string) $value;
+                    }
+                }
+
+                if (isset($unit->notes)) {
+                    $metadata['notes'] = [];
+                    foreach ($unit->notes->note as $noteNode) {
+                        $note = [];
+                        foreach ($noteNode->attributes() as $key => $value) {
+                            $note[$key] = (string) $value;
+                        }
+                        $note['content'] = (string) $noteNode;
+                        $metadata['notes'][] = $note;
+                    }
+                }
+
+                $catalogue->setMetadata((string) $source, $metadata, $domain);
+            }
+        }
+    }
+
+    /**
+     * Convert a UTF8 string to the specified encoding.
+     */
+    private function utf8ToCharset(string $content, string $encoding = null): string
+    {
+        if ('UTF-8' !== $encoding && !empty($encoding)) {
+            return mb_convert_encoding($content, $encoding, 'UTF-8');
+        }
+
+        return $content;
+    }
+
+    private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, string $encoding = null): array
+    {
+        $notes = [];
+
+        if (null === $noteElement) {
+            return $notes;
+        }
+
+        /** @var \SimpleXMLElement $xmlNote */
+        foreach ($noteElement as $xmlNote) {
+            $noteAttributes = $xmlNote->attributes();
+            $note = ['content' => $this->utf8ToCharset((string) $xmlNote, $encoding)];
+            if (isset($noteAttributes['priority'])) {
+                $note['priority'] = (int) $noteAttributes['priority'];
+            }
+
+            if (isset($noteAttributes['from'])) {
+                $note['from'] = (string) $noteAttributes['from'];
+            }
+
+            $notes[] = $note;
+        }
+
+        return $notes;
+    }
+
+    private function isXmlString(string $resource): bool
+    {
+        return 0 === strpos($resource, '<?xml');
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/YamlFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..8588e18
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/YamlFileLoader.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\LogicException;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser as YamlParser;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileLoader loads translations from Yaml files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class YamlFileLoader extends FileLoader
+{
+    private $yamlParser;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        if (null === $this->yamlParser) {
+            if (!class_exists(\Symfony\Component\Yaml\Parser::class)) {
+                throw new LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
+            }
+
+            $this->yamlParser = new YamlParser();
+        }
+
+        try {
+            $messages = $this->yamlParser->parseFile($resource, Yaml::PARSE_CONSTANT);
+        } catch (ParseException $e) {
+            throw new InvalidResourceException(sprintf('The file "%s" does not contain valid YAML: ', $resource).$e->getMessage(), 0, $e);
+        }
+
+        if (null !== $messages && !\is_array($messages)) {
+            throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
+        }
+
+        return $messages ?: [];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LoggingTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LoggingTranslator.php
new file mode 100644
index 0000000..bb93435
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LoggingTranslator.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
+{
+    /**
+     * @var TranslatorInterface|TranslatorBagInterface
+     */
+    private $translator;
+
+    private $logger;
+
+    /**
+     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
+     */
+    public function __construct(TranslatorInterface $translator, LoggerInterface $logger)
+    {
+        if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
+            throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
+        }
+
+        $this->translator = $translator;
+        $this->logger = $logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
+        $this->log($id, $domain, $locale);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $prev = $this->translator->getLocale();
+        $this->translator->setLocale($locale);
+        if ($prev === $locale) {
+            return;
+        }
+
+        $this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        return $this->translator->getCatalogue($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return $this->translator->getCatalogues();
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @return array The fallback locales
+     */
+    public function getFallbackLocales()
+    {
+        if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
+            return $this->translator->getFallbackLocales();
+        }
+
+        return [];
+    }
+
+    /**
+     * Passes through all unknown calls onto the translator object.
+     */
+    public function __call(string $method, array $args)
+    {
+        return $this->translator->{$method}(...$args);
+    }
+
+    /**
+     * Logs for missing translations.
+     */
+    private function log(string $id, ?string $domain, ?string $locale)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $catalogue = $this->translator->getCatalogue($locale);
+        if ($catalogue->defines($id, $domain)) {
+            return;
+        }
+
+        if ($catalogue->has($id, $domain)) {
+            $this->logger->debug('Translation use fallback catalogue.', ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]);
+        } else {
+            $this->logger->warning('Translation not found.', ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogue.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogue.php
new file mode 100644
index 0000000..ff49b5a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogue.php
@@ -0,0 +1,314 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+use Symfony\Component\Translation\Exception\LogicException;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
+{
+    private $messages = [];
+    private $metadata = [];
+    private $resources = [];
+    private $locale;
+    private $fallbackCatalogue;
+    private $parent;
+
+    /**
+     * @param array $messages An array of messages classified by domain
+     */
+    public function __construct(string $locale, array $messages = [])
+    {
+        $this->locale = $locale;
+        $this->messages = $messages;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomains()
+    {
+        $domains = [];
+
+        foreach ($this->messages as $domain => $messages) {
+            if (str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+                $domain = substr($domain, 0, -\strlen(self::INTL_DOMAIN_SUFFIX));
+            }
+            $domains[$domain] = $domain;
+        }
+
+        return array_values($domains);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function all(string $domain = null)
+    {
+        if (null !== $domain) {
+            // skip messages merge if intl-icu requested explicitly
+            if (str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+                return $this->messages[$domain] ?? [];
+            }
+
+            return ($this->messages[$domain.self::INTL_DOMAIN_SUFFIX] ?? []) + ($this->messages[$domain] ?? []);
+        }
+
+        $allMessages = [];
+
+        foreach ($this->messages as $domain => $messages) {
+            if (str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+                $domain = substr($domain, 0, -\strlen(self::INTL_DOMAIN_SUFFIX));
+                $allMessages[$domain] = $messages + ($allMessages[$domain] ?? []);
+            } else {
+                $allMessages[$domain] = ($allMessages[$domain] ?? []) + $messages;
+            }
+        }
+
+        return $allMessages;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set(string $id, string $translation, string $domain = 'messages')
+    {
+        $this->add([$id => $translation], $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has(string $id, string $domain = 'messages')
+    {
+        if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
+            return true;
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->has($id, $domain);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function defines(string $id, string $domain = 'messages')
+    {
+        return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get(string $id, string $domain = 'messages')
+    {
+        if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
+            return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id];
+        }
+
+        if (isset($this->messages[$domain][$id])) {
+            return $this->messages[$domain][$id];
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->get($id, $domain);
+        }
+
+        return $id;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function replace(array $messages, string $domain = 'messages')
+    {
+        unset($this->messages[$domain], $this->messages[$domain.self::INTL_DOMAIN_SUFFIX]);
+
+        $this->add($messages, $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function add(array $messages, string $domain = 'messages')
+    {
+        if (!isset($this->messages[$domain])) {
+            $this->messages[$domain] = [];
+        }
+        $intlDomain = $domain;
+        if (!str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+            $intlDomain .= self::INTL_DOMAIN_SUFFIX;
+        }
+        foreach ($messages as $id => $message) {
+            if (isset($this->messages[$intlDomain]) && \array_key_exists($id, $this->messages[$intlDomain])) {
+                $this->messages[$intlDomain][$id] = $message;
+            } else {
+                $this->messages[$domain][$id] = $message;
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        if ($catalogue->getLocale() !== $this->locale) {
+            throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s".', $catalogue->getLocale(), $this->locale));
+        }
+
+        foreach ($catalogue->all() as $domain => $messages) {
+            if ($intlMessages = $catalogue->all($domain.self::INTL_DOMAIN_SUFFIX)) {
+                $this->add($intlMessages, $domain.self::INTL_DOMAIN_SUFFIX);
+                $messages = array_diff_key($messages, $intlMessages);
+            }
+            $this->add($messages, $domain);
+        }
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+
+        if ($catalogue instanceof MetadataAwareInterface) {
+            $metadata = $catalogue->getMetadata('', '');
+            $this->addMetadata($metadata);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        // detect circular references
+        $c = $catalogue;
+        while ($c = $c->getFallbackCatalogue()) {
+            if ($c->getLocale() === $this->getLocale()) {
+                throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+            }
+        }
+
+        $c = $this;
+        do {
+            if ($c->getLocale() === $catalogue->getLocale()) {
+                throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+            }
+
+            foreach ($catalogue->getResources() as $resource) {
+                $c->addResource($resource);
+            }
+        } while ($c = $c->parent);
+
+        $catalogue->parent = $this;
+        $this->fallbackCatalogue = $catalogue;
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFallbackCatalogue()
+    {
+        return $this->fallbackCatalogue;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResources()
+    {
+        return array_values($this->resources);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addResource(ResourceInterface $resource)
+    {
+        $this->resources[$resource->__toString()] = $resource;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata(string $key = '', string $domain = 'messages')
+    {
+        if ('' == $domain) {
+            return $this->metadata;
+        }
+
+        if (isset($this->metadata[$domain])) {
+            if ('' == $key) {
+                return $this->metadata[$domain];
+            }
+
+            if (isset($this->metadata[$domain][$key])) {
+                return $this->metadata[$domain][$key];
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMetadata(string $key, $value, string $domain = 'messages')
+    {
+        $this->metadata[$domain][$key] = $value;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMetadata(string $key = '', string $domain = 'messages')
+    {
+        if ('' == $domain) {
+            $this->metadata = [];
+        } elseif ('' == $key) {
+            unset($this->metadata[$domain]);
+        } else {
+            unset($this->metadata[$domain][$key]);
+        }
+    }
+
+    /**
+     * Adds current values with the new values.
+     *
+     * @param array $values Values to add
+     */
+    private function addMetadata(array $values)
+    {
+        foreach ($values as $domain => $keys) {
+            foreach ($keys as $key => $value) {
+                $this->setMetadata($key, $value, $domain);
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogueInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogueInterface.php
new file mode 100644
index 0000000..5d83bd8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogueInterface.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * MessageCatalogueInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MessageCatalogueInterface
+{
+    public const INTL_DOMAIN_SUFFIX = '+intl-icu';
+
+    /**
+     * Gets the catalogue locale.
+     *
+     * @return string The locale
+     */
+    public function getLocale();
+
+    /**
+     * Gets the domains.
+     *
+     * @return array An array of domains
+     */
+    public function getDomains();
+
+    /**
+     * Gets the messages within a given domain.
+     *
+     * If $domain is null, it returns all messages.
+     *
+     * @param string $domain The domain name
+     *
+     * @return array An array of messages
+     */
+    public function all(string $domain = null);
+
+    /**
+     * Sets a message translation.
+     *
+     * @param string $id          The message id
+     * @param string $translation The messages translation
+     * @param string $domain      The domain name
+     */
+    public function set(string $id, string $translation, string $domain = 'messages');
+
+    /**
+     * Checks if a message has a translation.
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return bool true if the message has a translation, false otherwise
+     */
+    public function has(string $id, string $domain = 'messages');
+
+    /**
+     * Checks if a message has a translation (it does not take into account the fallback mechanism).
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return bool true if the message has a translation, false otherwise
+     */
+    public function defines(string $id, string $domain = 'messages');
+
+    /**
+     * Gets a message translation.
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return string The message translation
+     */
+    public function get(string $id, string $domain = 'messages');
+
+    /**
+     * Sets translations for a given domain.
+     *
+     * @param array  $messages An array of translations
+     * @param string $domain   The domain name
+     */
+    public function replace(array $messages, string $domain = 'messages');
+
+    /**
+     * Adds translations for a given domain.
+     *
+     * @param array  $messages An array of translations
+     * @param string $domain   The domain name
+     */
+    public function add(array $messages, string $domain = 'messages');
+
+    /**
+     * Merges translations from the given Catalogue into the current one.
+     *
+     * The two catalogues must have the same locale.
+     */
+    public function addCatalogue(self $catalogue);
+
+    /**
+     * Merges translations from the given Catalogue into the current one
+     * only when the translation does not exist.
+     *
+     * This is used to provide default translations when they do not exist for the current locale.
+     */
+    public function addFallbackCatalogue(self $catalogue);
+
+    /**
+     * Gets the fallback catalogue.
+     *
+     * @return self|null A MessageCatalogueInterface instance or null when no fallback has been set
+     */
+    public function getFallbackCatalogue();
+
+    /**
+     * Returns an array of resources loaded to build this collection.
+     *
+     * @return ResourceInterface[] An array of resources
+     */
+    public function getResources();
+
+    /**
+     * Adds a resource for this collection.
+     */
+    public function addResource(ResourceInterface $resource);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MetadataAwareInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MetadataAwareInterface.php
new file mode 100644
index 0000000..2216eed
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MetadataAwareInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * MetadataAwareInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MetadataAwareInterface
+{
+    /**
+     * Gets metadata for the given domain and key.
+     *
+     * Passing an empty domain will return an array with all metadata indexed by
+     * domain and then by key. Passing an empty key will return an array with all
+     * metadata for the given domain.
+     *
+     * @return mixed The value that was set or an array with the domains/keys or null
+     */
+    public function getMetadata(string $key = '', string $domain = 'messages');
+
+    /**
+     * Adds metadata to a message domain.
+     *
+     * @param mixed $value
+     */
+    public function setMetadata(string $key, $value, string $domain = 'messages');
+
+    /**
+     * Deletes metadata for the given key and domain.
+     *
+     * Passing an empty domain will delete all metadata. Passing an empty key will
+     * delete all metadata for the given domain.
+     */
+    public function deleteMetadata(string $key = '', string $domain = 'messages');
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/AbstractProviderFactory.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/AbstractProviderFactory.php
new file mode 100644
index 0000000..17442fd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/AbstractProviderFactory.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\IncompleteDsnException;
+
+abstract class AbstractProviderFactory implements ProviderFactoryInterface
+{
+    public function supports(Dsn $dsn): bool
+    {
+        return \in_array($dsn->getScheme(), $this->getSupportedSchemes(), true);
+    }
+
+    /**
+     * @return string[]
+     */
+    abstract protected function getSupportedSchemes(): array;
+
+    protected function getUser(Dsn $dsn): string
+    {
+        if (null === $user = $dsn->getUser()) {
+            throw new IncompleteDsnException('User is not set.', $dsn->getOriginalDsn());
+        }
+
+        return $user;
+    }
+
+    protected function getPassword(Dsn $dsn): string
+    {
+        if (null === $password = $dsn->getPassword()) {
+            throw new IncompleteDsnException('Password is not set.', $dsn->getOriginalDsn());
+        }
+
+        return $password;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/Dsn.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/Dsn.php
new file mode 100644
index 0000000..820cabf
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/Dsn.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\MissingRequiredOptionException;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Oskar Stark <oskarstark@googlemail.com>
+ */
+final class Dsn
+{
+    private $scheme;
+    private $host;
+    private $user;
+    private $password;
+    private $port;
+    private $path;
+    private $options;
+    private $originalDsn;
+
+    public function __construct(string $dsn)
+    {
+        $this->originalDsn = $dsn;
+
+        if (false === $parsedDsn = parse_url($dsn)) {
+            throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN is invalid.', $dsn));
+        }
+
+        if (!isset($parsedDsn['scheme'])) {
+            throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN must contain a scheme.', $dsn));
+        }
+        $this->scheme = $parsedDsn['scheme'];
+
+        if (!isset($parsedDsn['host'])) {
+            throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN must contain a host (use "default" by default).', $dsn));
+        }
+        $this->host = $parsedDsn['host'];
+
+        $this->user = '' !== ($parsedDsn['user'] ?? '') ? urldecode($parsedDsn['user']) : null;
+        $this->password = '' !== ($parsedDsn['pass'] ?? '') ? urldecode($parsedDsn['pass']) : null;
+        $this->port = $parsedDsn['port'] ?? null;
+        $this->path = $parsedDsn['path'] ?? null;
+        parse_str($parsedDsn['query'] ?? '', $this->options);
+    }
+
+    public function getScheme(): string
+    {
+        return $this->scheme;
+    }
+
+    public function getHost(): string
+    {
+        return $this->host;
+    }
+
+    public function getUser(): ?string
+    {
+        return $this->user;
+    }
+
+    public function getPassword(): ?string
+    {
+        return $this->password;
+    }
+
+    public function getPort(int $default = null): ?int
+    {
+        return $this->port ?? $default;
+    }
+
+    public function getOption(string $key, $default = null)
+    {
+        return $this->options[$key] ?? $default;
+    }
+
+    public function getRequiredOption(string $key)
+    {
+        if (!\array_key_exists($key, $this->options) || '' === trim($this->options[$key])) {
+            throw new MissingRequiredOptionException($key);
+        }
+
+        return $this->options[$key];
+    }
+
+    public function getOptions(): array
+    {
+        return $this->options;
+    }
+
+    public function getPath(): ?string
+    {
+        return $this->path;
+    }
+
+    public function getOriginalDsn(): string
+    {
+        return $this->originalDsn;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/FilteringProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/FilteringProvider.php
new file mode 100644
index 0000000..0307cda
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/FilteringProvider.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\TranslatorBag;
+use Symfony\Component\Translation\TranslatorBagInterface;
+
+/**
+ * Filters domains and locales between the Translator config values and those specific to each provider.
+ *
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+class FilteringProvider implements ProviderInterface
+{
+    private $provider;
+    private $locales;
+    private $domains;
+
+    public function __construct(ProviderInterface $provider, array $locales, array $domains = [])
+    {
+        $this->provider = $provider;
+        $this->locales = $locales;
+        $this->domains = $domains;
+    }
+
+    public function __toString(): string
+    {
+        return (string) $this->provider;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function write(TranslatorBagInterface $translatorBag): void
+    {
+        $this->provider->write($translatorBag);
+    }
+
+    public function read(array $domains, array $locales): TranslatorBag
+    {
+        $domains = !$this->domains ? $domains : array_intersect($this->domains, $domains);
+        $locales = array_intersect($this->locales, $locales);
+
+        return $this->provider->read($domains, $locales);
+    }
+
+    public function delete(TranslatorBagInterface $translatorBag): void
+    {
+        $this->provider->delete($translatorBag);
+    }
+
+    public function getDomains(): array
+    {
+        return $this->domains;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProvider.php
new file mode 100644
index 0000000..785fcaa
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProvider.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\TranslatorBag;
+use Symfony\Component\Translation\TranslatorBagInterface;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+class NullProvider implements ProviderInterface
+{
+    public function __toString(): string
+    {
+        return 'null';
+    }
+
+    public function write(TranslatorBagInterface $translatorBag, bool $override = false): void
+    {
+    }
+
+    public function read(array $domains, array $locales): TranslatorBag
+    {
+        return new TranslatorBag();
+    }
+
+    public function delete(TranslatorBagInterface $translatorBag): void
+    {
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProviderFactory.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProviderFactory.php
new file mode 100644
index 0000000..6ddbd85
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProviderFactory.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class NullProviderFactory extends AbstractProviderFactory
+{
+    public function create(Dsn $dsn): ProviderInterface
+    {
+        if ('null' === $dsn->getScheme()) {
+            return new NullProvider();
+        }
+
+        throw new UnsupportedSchemeException($dsn, 'null', $this->getSupportedSchemes());
+    }
+
+    protected function getSupportedSchemes(): array
+    {
+        return ['null'];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderFactoryInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderFactoryInterface.php
new file mode 100644
index 0000000..3fd4494
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderFactoryInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\IncompleteDsnException;
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+
+interface ProviderFactoryInterface
+{
+    /**
+     * @throws UnsupportedSchemeException
+     * @throws IncompleteDsnException
+     */
+    public function create(Dsn $dsn): ProviderInterface;
+
+    public function supports(Dsn $dsn): bool;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderInterface.php
new file mode 100644
index 0000000..a32193f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\TranslatorBag;
+use Symfony\Component\Translation\TranslatorBagInterface;
+
+interface ProviderInterface
+{
+    public function __toString(): string;
+
+    /**
+     * Translations available in the TranslatorBag only must be created.
+     * Translations available in both the TranslatorBag and on the provider
+     * must be overwritten.
+     * Translations available on the provider only must be kept.
+     */
+    public function write(TranslatorBagInterface $translatorBag): void;
+
+    public function read(array $domains, array $locales): TranslatorBag;
+
+    public function delete(TranslatorBagInterface $translatorBag): void;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollection.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollection.php
new file mode 100644
index 0000000..9963cb9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollection.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class TranslationProviderCollection
+{
+    private $providers;
+
+    /**
+     * @param array<string, ProviderInterface> $providers
+     */
+    public function __construct(iterable $providers)
+    {
+        $this->providers = [];
+        foreach ($providers as $name => $provider) {
+            $this->providers[$name] = $provider;
+        }
+    }
+
+    public function __toString(): string
+    {
+        return '['.implode(',', array_keys($this->providers)).']';
+    }
+
+    public function has(string $name): bool
+    {
+        return isset($this->providers[$name]);
+    }
+
+    public function get(string $name): ProviderInterface
+    {
+        if (!$this->has($name)) {
+            throw new InvalidArgumentException(sprintf('Provider "%s" not found. Available: "%s".', $name, (string) $this));
+        }
+
+        return $this->providers[$name];
+    }
+
+    public function keys(): array
+    {
+        return array_keys($this->providers);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollectionFactory.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollectionFactory.php
new file mode 100644
index 0000000..43f4a34
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollectionFactory.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+class TranslationProviderCollectionFactory
+{
+    private $factories;
+    private $enabledLocales;
+
+    /**
+     * @param ProviderFactoryInterface[] $factories
+     */
+    public function __construct(iterable $factories, array $enabledLocales)
+    {
+        $this->factories = $factories;
+        $this->enabledLocales = $enabledLocales;
+    }
+
+    public function fromConfig(array $config): TranslationProviderCollection
+    {
+        $providers = [];
+        foreach ($config as $name => $currentConfig) {
+            $providers[$name] = $this->fromDsnObject(
+                new Dsn($currentConfig['dsn']),
+                !$currentConfig['locales'] ? $this->enabledLocales : $currentConfig['locales'],
+                !$currentConfig['domains'] ? [] : $currentConfig['domains']
+            );
+        }
+
+        return new TranslationProviderCollection($providers);
+    }
+
+    public function fromDsnObject(Dsn $dsn, array $locales, array $domains = []): ProviderInterface
+    {
+        foreach ($this->factories as $factory) {
+            if ($factory->supports($dsn)) {
+                return new FilteringProvider($factory->create($dsn), $locales, $domains);
+            }
+        }
+
+        throw new UnsupportedSchemeException($dsn);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/PseudoLocalizationTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/PseudoLocalizationTranslator.php
new file mode 100644
index 0000000..49f122e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/PseudoLocalizationTranslator.php
@@ -0,0 +1,364 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * This translator should only be used in a development environment.
+ */
+final class PseudoLocalizationTranslator implements TranslatorInterface
+{
+    private const EXPANSION_CHARACTER = '~';
+
+    private $translator;
+    private $accents;
+    private $expansionFactor;
+    private $brackets;
+    private $parseHTML;
+    private $localizableHTMLAttributes;
+
+    /**
+     * Available options:
+     *  * accents:
+     *      type: boolean
+     *      default: true
+     *      description: replace ASCII characters of the translated string with accented versions or similar characters
+     *      example: if true, "foo" => "ƒöö".
+     *
+     *  * expansion_factor:
+     *      type: float
+     *      default: 1
+     *      validation: it must be greater than or equal to 1
+     *      description: expand the translated string by the given factor with spaces and tildes
+     *      example: if 2, "foo" => "~foo ~"
+     *
+     *  * brackets:
+     *      type: boolean
+     *      default: true
+     *      description: wrap the translated string with brackets
+     *      example: if true, "foo" => "[foo]"
+     *
+     *  * parse_html:
+     *      type: boolean
+     *      default: false
+     *      description: parse the translated string as HTML - looking for HTML tags has a performance impact but allows to preserve them from alterations - it also allows to compute the visible translated string length which is useful to correctly expand ot when it contains HTML
+     *      warning: unclosed tags are unsupported, they will be fixed (closed) by the parser - eg, "foo <div>bar" => "foo <div>bar</div>"
+     *
+     *  * localizable_html_attributes:
+     *      type: string[]
+     *      default: []
+     *      description: the list of HTML attributes whose values can be altered - it is only useful when the "parse_html" option is set to true
+     *      example: if ["title"], and with the "accents" option set to true, "<a href="#" title="Go to your profile">Profile</a>" => "<a href="#" title="Ĝö ţö ýöûŕ þŕöƒîļé">Þŕöƒîļé</a>" - if "title" was not in the "localizable_html_attributes" list, the title attribute data would be left unchanged.
+     */
+    public function __construct(TranslatorInterface $translator, array $options = [])
+    {
+        $this->translator = $translator;
+        $this->accents = $options['accents'] ?? true;
+
+        if (1.0 > ($this->expansionFactor = $options['expansion_factor'] ?? 1.0)) {
+            throw new \InvalidArgumentException('The expansion factor must be greater than or equal to 1.');
+        }
+
+        $this->brackets = $options['brackets'] ?? true;
+
+        $this->parseHTML = $options['parse_html'] ?? false;
+        if ($this->parseHTML && !$this->accents && 1.0 === $this->expansionFactor) {
+            $this->parseHTML = false;
+        }
+
+        $this->localizableHTMLAttributes = $options['localizable_html_attributes'] ?? [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        $trans = '';
+        $visibleText = '';
+
+        foreach ($this->getParts($this->translator->trans($id, $parameters, $domain, $locale)) as [$visible, $localizable, $text]) {
+            if ($visible) {
+                $visibleText .= $text;
+            }
+
+            if (!$localizable) {
+                $trans .= $text;
+
+                continue;
+            }
+
+            $this->addAccents($trans, $text);
+        }
+
+        $this->expand($trans, $visibleText);
+
+        $this->addBrackets($trans);
+
+        return $trans;
+    }
+
+    public function getLocale(): string
+    {
+        return $this->translator->getLocale();
+    }
+
+    private function getParts(string $originalTrans): array
+    {
+        if (!$this->parseHTML) {
+            return [[true, true, $originalTrans]];
+        }
+
+        $html = mb_convert_encoding($originalTrans, 'HTML-ENTITIES', mb_detect_encoding($originalTrans, null, true) ?: 'UTF-8');
+
+        $useInternalErrors = libxml_use_internal_errors(true);
+
+        $dom = new \DOMDocument();
+        $dom->loadHTML('<trans>'.$html.'</trans>');
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($useInternalErrors);
+
+        return $this->parseNode($dom->childNodes->item(1)->childNodes->item(0)->childNodes->item(0));
+    }
+
+    private function parseNode(\DOMNode $node): array
+    {
+        $parts = [];
+
+        foreach ($node->childNodes as $childNode) {
+            if (!$childNode instanceof \DOMElement) {
+                $parts[] = [true, true, $childNode->nodeValue];
+
+                continue;
+            }
+
+            $parts[] = [false, false, '<'.$childNode->tagName];
+
+            /** @var \DOMAttr $attribute */
+            foreach ($childNode->attributes as $attribute) {
+                $parts[] = [false, false, ' '.$attribute->nodeName.'="'];
+
+                $localizableAttribute = \in_array($attribute->nodeName, $this->localizableHTMLAttributes, true);
+                foreach (preg_split('/(&(?:amp|quot|#039|lt|gt);+)/', htmlspecialchars($attribute->nodeValue, \ENT_QUOTES, 'UTF-8'), -1, \PREG_SPLIT_DELIM_CAPTURE) as $i => $match) {
+                    if ('' === $match) {
+                        continue;
+                    }
+
+                    $parts[] = [false, $localizableAttribute && 0 === $i % 2, $match];
+                }
+
+                $parts[] = [false, false, '"'];
+            }
+
+            $parts[] = [false, false, '>'];
+
+            $parts = array_merge($parts, $this->parseNode($childNode, $parts));
+
+            $parts[] = [false, false, '</'.$childNode->tagName.'>'];
+        }
+
+        return $parts;
+    }
+
+    private function addAccents(string &$trans, string $text): void
+    {
+        $trans .= $this->accents ? strtr($text, [
+            ' ' => ' ',
+            '!' => '¡',
+            '"' => '″',
+            '#' => '♯',
+            '$' => '€',
+            '%' => '‰',
+            '&' => '⅋',
+            '\'' => '´',
+            '(' => '{',
+            ')' => '}',
+            '*' => '⁎',
+            '+' => '⁺',
+            ',' => '،',
+            '-' => '‐',
+            '.' => '·',
+            '/' => '⁄',
+            '0' => '⓪',
+            '1' => '①',
+            '2' => '②',
+            '3' => '③',
+            '4' => '④',
+            '5' => '⑤',
+            '6' => '⑥',
+            '7' => '⑦',
+            '8' => '⑧',
+            '9' => '⑨',
+            ':' => '∶',
+            ';' => '⁏',
+            '<' => '≤',
+            '=' => '≂',
+            '>' => '≥',
+            '?' => '¿',
+            '@' => '՞',
+            'A' => 'Å',
+            'B' => 'Ɓ',
+            'C' => 'Ç',
+            'D' => 'Ð',
+            'E' => 'É',
+            'F' => 'Ƒ',
+            'G' => 'Ĝ',
+            'H' => 'Ĥ',
+            'I' => 'Î',
+            'J' => 'Ĵ',
+            'K' => 'Ķ',
+            'L' => 'Ļ',
+            'M' => 'Ṁ',
+            'N' => 'Ñ',
+            'O' => 'Ö',
+            'P' => 'Þ',
+            'Q' => 'Ǫ',
+            'R' => 'Ŕ',
+            'S' => 'Š',
+            'T' => 'Ţ',
+            'U' => 'Û',
+            'V' => 'Ṽ',
+            'W' => 'Ŵ',
+            'X' => 'Ẋ',
+            'Y' => 'Ý',
+            'Z' => 'Ž',
+            '[' => '⁅',
+            '\\' => '∖',
+            ']' => '⁆',
+            '^' => '˄',
+            '_' => '‿',
+            '`' => '‵',
+            'a' => 'å',
+            'b' => 'ƀ',
+            'c' => 'ç',
+            'd' => 'ð',
+            'e' => 'é',
+            'f' => 'ƒ',
+            'g' => 'ĝ',
+            'h' => 'ĥ',
+            'i' => 'î',
+            'j' => 'ĵ',
+            'k' => 'ķ',
+            'l' => 'ļ',
+            'm' => 'ɱ',
+            'n' => 'ñ',
+            'o' => 'ö',
+            'p' => 'þ',
+            'q' => 'ǫ',
+            'r' => 'ŕ',
+            's' => 'š',
+            't' => 'ţ',
+            'u' => 'û',
+            'v' => 'ṽ',
+            'w' => 'ŵ',
+            'x' => 'ẋ',
+            'y' => 'ý',
+            'z' => 'ž',
+            '{' => '(',
+            '|' => '¦',
+            '}' => ')',
+            '~' => '˞',
+        ]) : $text;
+    }
+
+    private function expand(string &$trans, string $visibleText): void
+    {
+        if (1.0 >= $this->expansionFactor) {
+            return;
+        }
+
+        $visibleLength = $this->strlen($visibleText);
+        $missingLength = (int) (ceil($visibleLength * $this->expansionFactor)) - $visibleLength;
+        if ($this->brackets) {
+            $missingLength -= 2;
+        }
+
+        if (0 >= $missingLength) {
+            return;
+        }
+
+        $words = [];
+        $wordsCount = 0;
+        foreach (preg_split('/ +/', $visibleText, -1, \PREG_SPLIT_NO_EMPTY) as $word) {
+            $wordLength = $this->strlen($word);
+
+            if ($wordLength >= $missingLength) {
+                continue;
+            }
+
+            if (!isset($words[$wordLength])) {
+                $words[$wordLength] = 0;
+            }
+
+            ++$words[$wordLength];
+            ++$wordsCount;
+        }
+
+        if (!$words) {
+            $trans .= 1 === $missingLength ? self::EXPANSION_CHARACTER : ' '.str_repeat(self::EXPANSION_CHARACTER, $missingLength - 1);
+
+            return;
+        }
+
+        arsort($words, \SORT_NUMERIC);
+
+        $longestWordLength = max(array_keys($words));
+
+        while (true) {
+            $r = mt_rand(1, $wordsCount);
+
+            foreach ($words as $length => $count) {
+                $r -= $count;
+                if ($r <= 0) {
+                    break;
+                }
+            }
+
+            $trans .= ' '.str_repeat(self::EXPANSION_CHARACTER, $length);
+
+            $missingLength -= $length + 1;
+
+            if (0 === $missingLength) {
+                return;
+            }
+
+            while ($longestWordLength >= $missingLength) {
+                $wordsCount -= $words[$longestWordLength];
+                unset($words[$longestWordLength]);
+
+                if (!$words) {
+                    $trans .= 1 === $missingLength ? self::EXPANSION_CHARACTER : ' '.str_repeat(self::EXPANSION_CHARACTER, $missingLength - 1);
+
+                    return;
+                }
+
+                $longestWordLength = max(array_keys($words));
+            }
+        }
+    }
+
+    private function addBrackets(string &$trans): void
+    {
+        if (!$this->brackets) {
+            return;
+        }
+
+        $trans = '['.$trans.']';
+    }
+
+    private function strlen(string $s): int
+    {
+        return false === ($encoding = mb_detect_encoding($s, null, true)) ? \strlen($s) : mb_strlen($s, $encoding);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/README.md
new file mode 100644
index 0000000..720bee3
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/README.md
@@ -0,0 +1,33 @@
+Translation Component
+=====================
+
+The Translation component provides tools to internationalize your application.
+
+Getting Started
+---------------
+
+```
+$ composer require symfony/translation
+```
+
+```php
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+$translator = new Translator('fr_FR');
+$translator->addLoader('array', new ArrayLoader());
+$translator->addResource('array', [
+    'Hello World!' => 'Bonjour !',
+], 'fr_FR');
+
+echo $translator->trans('Hello World!'); // outputs « Bonjour ! »
+```
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/translation.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+   [send Pull Requests](https://github.com/symfony/symfony/pulls)
+   in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReader.php
new file mode 100644
index 0000000..9e51b15
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReader.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Reader;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationReader reads translation messages from translation files.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class TranslationReader implements TranslationReaderInterface
+{
+    /**
+     * Loaders used for import.
+     *
+     * @var array
+     */
+    private $loaders = [];
+
+    /**
+     * Adds a loader to the translation extractor.
+     *
+     * @param string $format The format of the loader
+     */
+    public function addLoader(string $format, LoaderInterface $loader)
+    {
+        $this->loaders[$format] = $loader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function read(string $directory, MessageCatalogue $catalogue)
+    {
+        if (!is_dir($directory)) {
+            return;
+        }
+
+        foreach ($this->loaders as $format => $loader) {
+            // load any existing translation files
+            $finder = new Finder();
+            $extension = $catalogue->getLocale().'.'.$format;
+            $files = $finder->files()->name('*.'.$extension)->in($directory);
+            foreach ($files as $file) {
+                $domain = substr($file->getFilename(), 0, -1 * \strlen($extension) - 1);
+                $catalogue->addCatalogue($loader->load($file->getPathname(), $catalogue->getLocale(), $domain));
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReaderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReaderInterface.php
new file mode 100644
index 0000000..bc37204
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReaderInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Reader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationReader reads translation messages from translation files.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+interface TranslationReaderInterface
+{
+    /**
+     * Reads translation messages from a directory to the catalogue.
+     */
+    public function read(string $directory, MessageCatalogue $catalogue);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/bin/translation-status.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/bin/translation-status.php
new file mode 100644
index 0000000..4e0723b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/bin/translation-status.php
@@ -0,0 +1,207 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+$usageInstructions = <<<END
+
+  Usage instructions
+  -------------------------------------------------------------------------------
+
+  $ cd symfony-code-root-directory/
+
+  # show the translation status of all locales
+  $ php translation-status.php
+
+  # show the translation status of all locales and all their missing translations
+  $ php translation-status.php -v
+
+  # show the status of a single locale
+  $ php translation-status.php fr
+
+  # show the status of a single locale and all its missing translations
+  $ php translation-status.php fr -v
+
+END;
+
+$config = [
+    // if TRUE, the full list of missing translations is displayed
+    'verbose_output' => false,
+    // NULL = analyze all locales
+    'locale_to_analyze' => null,
+    // the reference files all the other translations are compared to
+    'original_files' => [
+        'src/Symfony/Component/Form/Resources/translations/validators.en.xlf',
+        'src/Symfony/Component/Security/Core/Resources/translations/security.en.xlf',
+        'src/Symfony/Component/Validator/Resources/translations/validators.en.xlf',
+    ],
+];
+
+$argc = $_SERVER['argc'];
+$argv = $_SERVER['argv'];
+
+if ($argc > 3) {
+    echo str_replace('translation-status.php', $argv[0], $usageInstructions);
+    exit(1);
+}
+
+foreach (array_slice($argv, 1) as $argumentOrOption) {
+    if (str_starts_with($argumentOrOption, '-')) {
+        $config['verbose_output'] = true;
+    } else {
+        $config['locale_to_analyze'] = $argumentOrOption;
+    }
+}
+
+foreach ($config['original_files'] as $originalFilePath) {
+    if (!file_exists($originalFilePath)) {
+        echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s  %s', \PHP_EOL, $originalFilePath);
+        exit(1);
+    }
+}
+
+$totalMissingTranslations = 0;
+
+foreach ($config['original_files'] as $originalFilePath) {
+    $translationFilePaths = findTranslationFiles($originalFilePath, $config['locale_to_analyze']);
+    $translationStatus = calculateTranslationStatus($originalFilePath, $translationFilePaths);
+
+    $totalMissingTranslations += array_sum(array_map(function ($translation) {
+        return count($translation['missingKeys']);
+    }, array_values($translationStatus)));
+
+    printTranslationStatus($originalFilePath, $translationStatus, $config['verbose_output']);
+}
+
+exit($totalMissingTranslations > 0 ? 1 : 0);
+
+function findTranslationFiles($originalFilePath, $localeToAnalyze)
+{
+    $translations = [];
+
+    $translationsDir = dirname($originalFilePath);
+    $originalFileName = basename($originalFilePath);
+    $translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName);
+
+    $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern, \GLOB_NOSORT);
+    sort($translationFiles);
+    foreach ($translationFiles as $filePath) {
+        $locale = extractLocaleFromFilePath($filePath);
+
+        if (null !== $localeToAnalyze && $locale !== $localeToAnalyze) {
+            continue;
+        }
+
+        $translations[$locale] = $filePath;
+    }
+
+    return $translations;
+}
+
+function calculateTranslationStatus($originalFilePath, $translationFilePaths)
+{
+    $translationStatus = [];
+    $allTranslationKeys = extractTranslationKeys($originalFilePath);
+
+    foreach ($translationFilePaths as $locale => $translationPath) {
+        $translatedKeys = extractTranslationKeys($translationPath);
+        $missingKeys = array_diff_key($allTranslationKeys, $translatedKeys);
+
+        $translationStatus[$locale] = [
+            'total' => count($allTranslationKeys),
+            'translated' => count($translatedKeys),
+            'missingKeys' => $missingKeys,
+        ];
+    }
+
+    return $translationStatus;
+}
+
+function printTranslationStatus($originalFilePath, $translationStatus, $verboseOutput)
+{
+    printTitle($originalFilePath);
+    printTable($translationStatus, $verboseOutput);
+    echo \PHP_EOL.\PHP_EOL;
+}
+
+function extractLocaleFromFilePath($filePath)
+{
+    $parts = explode('.', $filePath);
+
+    return $parts[count($parts) - 2];
+}
+
+function extractTranslationKeys($filePath)
+{
+    $translationKeys = [];
+    $contents = new \SimpleXMLElement(file_get_contents($filePath));
+
+    foreach ($contents->file->body->{'trans-unit'} as $translationKey) {
+        $translationId = (string) $translationKey['id'];
+        $translationKey = (string) $translationKey->source;
+
+        $translationKeys[$translationId] = $translationKey;
+    }
+
+    return $translationKeys;
+}
+
+function printTitle($title)
+{
+    echo $title.\PHP_EOL;
+    echo str_repeat('=', strlen($title)).\PHP_EOL.\PHP_EOL;
+}
+
+function printTable($translations, $verboseOutput)
+{
+    if (0 === count($translations)) {
+        echo 'No translations found';
+
+        return;
+    }
+    $longestLocaleNameLength = max(array_map('strlen', array_keys($translations)));
+
+    foreach ($translations as $locale => $translation) {
+        if ($translation['translated'] > $translation['total']) {
+            textColorRed();
+        } elseif ($translation['translated'] === $translation['total']) {
+            textColorGreen();
+        }
+
+        echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).\PHP_EOL;
+
+        textColorNormal();
+
+        if (true === $verboseOutput && count($translation['missingKeys']) > 0) {
+            echo str_repeat('-', 80).\PHP_EOL;
+            echo '| Missing Translations:'.\PHP_EOL;
+
+            foreach ($translation['missingKeys'] as $id => $content) {
+                echo sprintf('|   (id=%s) %s', $id, $content).\PHP_EOL;
+            }
+
+            echo str_repeat('-', 80).\PHP_EOL;
+        }
+    }
+}
+
+function textColorGreen()
+{
+    echo "\033[32m";
+}
+
+function textColorRed()
+{
+    echo "\033[31m";
+}
+
+function textColorNormal()
+{
+    echo "\033[0m";
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/data/parents.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/data/parents.json
new file mode 100644
index 0000000..a67458a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/data/parents.json
@@ -0,0 +1,140 @@
+{
+    "az_Cyrl": "root",
+    "bs_Cyrl": "root",
+    "en_150": "en_001",
+    "en_AG": "en_001",
+    "en_AI": "en_001",
+    "en_AT": "en_150",
+    "en_AU": "en_001",
+    "en_BB": "en_001",
+    "en_BE": "en_150",
+    "en_BM": "en_001",
+    "en_BS": "en_001",
+    "en_BW": "en_001",
+    "en_BZ": "en_001",
+    "en_CA": "en_001",
+    "en_CC": "en_001",
+    "en_CH": "en_150",
+    "en_CK": "en_001",
+    "en_CM": "en_001",
+    "en_CX": "en_001",
+    "en_CY": "en_001",
+    "en_DE": "en_150",
+    "en_DG": "en_001",
+    "en_DK": "en_150",
+    "en_DM": "en_001",
+    "en_ER": "en_001",
+    "en_FI": "en_150",
+    "en_FJ": "en_001",
+    "en_FK": "en_001",
+    "en_FM": "en_001",
+    "en_GB": "en_001",
+    "en_GD": "en_001",
+    "en_GG": "en_001",
+    "en_GH": "en_001",
+    "en_GI": "en_001",
+    "en_GM": "en_001",
+    "en_GY": "en_001",
+    "en_HK": "en_001",
+    "en_IE": "en_001",
+    "en_IL": "en_001",
+    "en_IM": "en_001",
+    "en_IN": "en_001",
+    "en_IO": "en_001",
+    "en_JE": "en_001",
+    "en_JM": "en_001",
+    "en_KE": "en_001",
+    "en_KI": "en_001",
+    "en_KN": "en_001",
+    "en_KY": "en_001",
+    "en_LC": "en_001",
+    "en_LR": "en_001",
+    "en_LS": "en_001",
+    "en_MG": "en_001",
+    "en_MO": "en_001",
+    "en_MS": "en_001",
+    "en_MT": "en_001",
+    "en_MU": "en_001",
+    "en_MW": "en_001",
+    "en_MY": "en_001",
+    "en_NA": "en_001",
+    "en_NF": "en_001",
+    "en_NG": "en_001",
+    "en_NL": "en_150",
+    "en_NR": "en_001",
+    "en_NU": "en_001",
+    "en_NZ": "en_001",
+    "en_PG": "en_001",
+    "en_PH": "en_001",
+    "en_PK": "en_001",
+    "en_PN": "en_001",
+    "en_PW": "en_001",
+    "en_RW": "en_001",
+    "en_SB": "en_001",
+    "en_SC": "en_001",
+    "en_SD": "en_001",
+    "en_SE": "en_150",
+    "en_SG": "en_001",
+    "en_SH": "en_001",
+    "en_SI": "en_150",
+    "en_SL": "en_001",
+    "en_SS": "en_001",
+    "en_SX": "en_001",
+    "en_SZ": "en_001",
+    "en_TC": "en_001",
+    "en_TK": "en_001",
+    "en_TO": "en_001",
+    "en_TT": "en_001",
+    "en_TV": "en_001",
+    "en_TZ": "en_001",
+    "en_UG": "en_001",
+    "en_VC": "en_001",
+    "en_VG": "en_001",
+    "en_VU": "en_001",
+    "en_WS": "en_001",
+    "en_ZA": "en_001",
+    "en_ZM": "en_001",
+    "en_ZW": "en_001",
+    "es_AR": "es_419",
+    "es_BO": "es_419",
+    "es_BR": "es_419",
+    "es_BZ": "es_419",
+    "es_CL": "es_419",
+    "es_CO": "es_419",
+    "es_CR": "es_419",
+    "es_CU": "es_419",
+    "es_DO": "es_419",
+    "es_EC": "es_419",
+    "es_GT": "es_419",
+    "es_HN": "es_419",
+    "es_MX": "es_419",
+    "es_NI": "es_419",
+    "es_PA": "es_419",
+    "es_PE": "es_419",
+    "es_PR": "es_419",
+    "es_PY": "es_419",
+    "es_SV": "es_419",
+    "es_US": "es_419",
+    "es_UY": "es_419",
+    "es_VE": "es_419",
+    "ff_Adlm": "root",
+    "nb": "no",
+    "nn": "no",
+    "pa_Arab": "root",
+    "pt_AO": "pt_PT",
+    "pt_CH": "pt_PT",
+    "pt_CV": "pt_PT",
+    "pt_GQ": "pt_PT",
+    "pt_GW": "pt_PT",
+    "pt_LU": "pt_PT",
+    "pt_MO": "pt_PT",
+    "pt_MZ": "pt_PT",
+    "pt_ST": "pt_PT",
+    "pt_TL": "pt_PT",
+    "sd_Deva": "root",
+    "sr_Latn": "root",
+    "uz_Arab": "root",
+    "uz_Cyrl": "root",
+    "zh_Hant": "root",
+    "zh_Hant_MO": "zh_Hant_HK"
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/functions.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/functions.php
new file mode 100644
index 0000000..901d2f8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/functions.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+if (!\function_exists(t::class)) {
+    /**
+     * @author Nate Wiebe <nate@northern.co>
+     */
+    function t(string $message, array $parameters = [], string $domain = null): TranslatableMessage
+    {
+        return new TranslatableMessage($message, $parameters, $domain);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd
new file mode 100644
index 0000000..dface62
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd
@@ -0,0 +1,2223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+May-19-2004:
+- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements
+to <choice> itself.
+- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
+<alt-trans>.
+
+Oct-2005
+- updated version info to 1.2
+- equiv-trans attribute to <trans-unit> element
+- merged-trans attribute for <group> element
+- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source>
+- Create a new value "seg" for the mtype attribute of the <mrk> element
+- Add mid as an optional attribute for the <alt-trans> element
+
+Nov-14-2005
+- Changed name attribute for <context-group> from required to optional
+- Added extension point at <xliff>
+
+Jan-9-2006
+- Added alttranstype type attribute to <alt-trans>, and values
+
+Jan-10-2006
+- Corrected error with overwritten purposeValueList
+- Corrected name="AttrType_Version",  attribute should have been "name"
+
+-->
+<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
+  <!-- Import for xml:lang and xml:space -->
+  <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+  <!-- Attributes Lists -->
+  <xsd:simpleType name="XTend">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="x-[^\s]+"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="context-typeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="database">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a database content.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="element">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="elementtitle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="linenumber">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="numparams">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="paramnotes">
+        <xsd:annotation>
+          <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="record">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="recordtitle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sourcefile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="count-typeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="num-usages">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="repetition">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="total">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a total count.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="InlineDelimitersValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="bold">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="italic">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="underlined">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="link">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="InlinePlaceholdersValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="image">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a inline image.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pb">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a page break.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="lb">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a line break.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="mime-typeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="datatypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="asp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="c">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cdf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cfm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cpp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="csharp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cstring">
+        <xsd:annotation>
+          <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="csv">
+        <xsd:annotation>
+          <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="database">
+        <xsd:annotation>
+          <xsd:documentation>Indicates database data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="documentfooter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="documentheader">
+        <xsd:annotation>
+          <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="filedialog">
+        <xsd:annotation>
+          <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="form">
+        <xsd:annotation>
+          <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="html">
+        <xsd:annotation>
+          <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="htmlbody">
+        <xsd:annotation>
+          <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ini">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="interleaf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javaclass">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javapropertyresourcebundle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javalistresourcebundle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javascript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="jscript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="layout">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="lisp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="margin">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menufile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="messagefile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mif">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mimetype">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mo">
+        <xsd:annotation>
+          <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="msglib">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pagefooter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pageheader">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="parameters">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pascal">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="php">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="plaintext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="po">
+        <xsd:annotation>
+          <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="report">
+        <xsd:annotation>
+          <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="resources">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="resx">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rtf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sgml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sgmldtd">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="svg">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="vbscript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="warning">
+        <xsd:annotation>
+          <xsd:documentation>Indicates warning message.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="winres">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xhtml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xmldtd">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xsl">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xul">
+        <xsd:annotation>
+          <xsd:documentation>Indicates XUL elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="mtypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="abbrev">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="abbreviated-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="abbreviation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="acronym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="appellation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="collocation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="common-name">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="datetime">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="equation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="expanded-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="formula">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="head-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="initialism">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="international-scientific-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="internationalism">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="logical-expression">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="materials-management-unit">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="name">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="near-synonym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="part-number">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="phrase">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="phraseological-unit">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="protected">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="romanized-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="seg">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="set-phrase">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="short-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sku">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="standard-text">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="symbol">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="synonym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="synonymous-phrase">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="term">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="transcribed-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="transliterated-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="truncated-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="variant">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="restypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="auto3state">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="autocheckbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="autoradiobutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bitmap">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="button">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="caption">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cell">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkboxmenuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkedlistbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="colorchooser">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="combobox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="comboboxexitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="comboboxitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="component">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="contextmenu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a context menu.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ctext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cursor">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="datetimepicker">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="defpushbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dialog">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a dialog box.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dlginit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="edit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="file">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a filename.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="filechooser">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a file dialog.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="fn">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a footnote.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="font">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a font name.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="footer">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a footer.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="frame">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a frame object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="grid">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="groupbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="header">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a header item.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="heading">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="hedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="hscrollbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="icon">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="iedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="keywords">
+        <xsd:annotation>
+          <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="label">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a label object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="linklabel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="list">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="listbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="listitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ltext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menubar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menuseparator">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="message">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="monthcalendar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a calendar control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="numericupdown">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="panel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="popupmenu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pushbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pushbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="radio">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a radio button object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="radiobuttonmenuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rcdata">
+        <xsd:annotation>
+          <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="row">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a row in a table.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rtext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="scrollpane">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="separator">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="shortcut">
+        <xsd:annotation>
+          <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="spinner">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="splitter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="state3">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="statusbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="string">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tabcontrol">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="table">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="textbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="togglebutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="toolbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tooltip">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="trackbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tree">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="uri">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="userbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="usercontrol">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="var">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="versioninfo">
+        <xsd:annotation>
+          <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="vscrollbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="window">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a graphical window.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="size-unitValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="byte">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="char">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="col">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dlgunit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="em">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ex">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="glyph">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="in">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in inches.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="percent">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pixel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="point">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in point.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="row">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="stateValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="final">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the terminating state.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-adaptation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-l10n">
+        <xsd:annotation>
+          <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-adaptation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-l10n">
+        <xsd:annotation>
+          <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-translation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-translation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="new">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="signed-off">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="translated">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="state-qualifierValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="exact-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="fuzzy-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="id-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-glossary">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-inherited">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-mt">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-repository">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-tm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mt-suggestion">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-grammar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-inaccurate">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-length">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-spelling">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tm-suggestion">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="unitValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="word">
+        <xsd:annotation>
+          <xsd:documentation>Refers to words.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="page">
+        <xsd:annotation>
+          <xsd:documentation>Refers to pages.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="trans-unit">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bin-unit">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="glyph">
+        <xsd:annotation>
+          <xsd:documentation>Refers to glyphs.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="item">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="instance">
+        <xsd:annotation>
+          <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="character">
+        <xsd:annotation>
+          <xsd:documentation>Refers to characters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="line">
+        <xsd:annotation>
+          <xsd:documentation>Refers to lines.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sentence">
+        <xsd:annotation>
+          <xsd:documentation>Refers to sentences.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="paragraph">
+        <xsd:annotation>
+          <xsd:documentation>Refers to paragraphs.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="segment">
+        <xsd:annotation>
+          <xsd:documentation>Refers to segments.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="placeable">
+        <xsd:annotation>
+          <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="priorityValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:positiveInteger">
+      <xsd:enumeration value="1">
+        <xsd:annotation>
+          <xsd:documentation>Highest priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="2">
+        <xsd:annotation>
+          <xsd:documentation>High priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="3">
+        <xsd:annotation>
+          <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="4">
+        <xsd:annotation>
+          <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="5">
+        <xsd:annotation>
+          <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="6">
+        <xsd:annotation>
+          <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="7">
+        <xsd:annotation>
+          <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="8">
+        <xsd:annotation>
+          <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="9">
+        <xsd:annotation>
+          <xsd:documentation>Low priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="10">
+        <xsd:annotation>
+          <xsd:documentation>Lowest priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="reformatValueYesNo">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="yes">
+        <xsd:annotation>
+          <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="no">
+        <xsd:annotation>
+          <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="reformatValueList">
+    <xsd:list>
+      <xsd:simpleType>
+        <xsd:union memberTypes="xlf:XTend">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="coord">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-x">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-y">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-cx">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-cy">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-name">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-size">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-weight">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="css-style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="ex-style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:union>
+      </xsd:simpleType>
+    </xsd:list>
+  </xsd:simpleType>
+  <xsd:simpleType name="purposeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="information">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="location">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="alttranstypeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="proposal">
+        <xsd:annotation>
+          <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="previous-version">
+        <xsd:annotation>
+          <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected">
+        <xsd:annotation>
+          <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="reference">
+        <xsd:annotation>
+          <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="accepted">
+        <xsd:annotation>
+          <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <!-- Other Types -->
+  <xsd:complexType name="ElemType_ExternalReference">
+    <xsd:choice>
+      <xsd:element ref="xlf:internal-file"/>
+      <xsd:element ref="xlf:external-file"/>
+    </xsd:choice>
+  </xsd:complexType>
+  <xsd:simpleType name="AttrType_purpose">
+    <xsd:list>
+      <xsd:simpleType>
+        <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
+      </xsd:simpleType>
+    </xsd:list>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_datatype">
+    <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_restype">
+    <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_alttranstype">
+    <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_context-type">
+    <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_state">
+    <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_state-qualifier">
+    <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_count-type">
+    <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_InlineDelimiters">
+    <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_InlinePlaceholders">
+    <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_size-unit">
+    <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_mtype">
+    <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_unit">
+    <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_priority">
+    <xsd:union memberTypes="xlf:priorityValueList"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_reformat">
+    <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_YesNo">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="yes"/>
+      <xsd:enumeration value="no"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Position">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="open"/>
+      <xsd:enumeration value="close"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_assoc">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="preceding"/>
+      <xsd:enumeration value="following"/>
+      <xsd:enumeration value="both"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_annotates">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="source"/>
+      <xsd:enumeration value="target"/>
+      <xsd:enumeration value="general"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Coordinates">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Version">
+    <xsd:annotation>
+      <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="1.2"/>
+      <xsd:enumeration value="1.1"/>
+      <xsd:enumeration value="1.0"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <!-- Groups -->
+  <xsd:group name="ElemGroup_TextContent">
+    <xsd:choice>
+      <xsd:element ref="xlf:g"/>
+      <xsd:element ref="xlf:bpt"/>
+      <xsd:element ref="xlf:ept"/>
+      <xsd:element ref="xlf:ph"/>
+      <xsd:element ref="xlf:it"/>
+      <xsd:element ref="xlf:mrk"/>
+      <xsd:element ref="xlf:x"/>
+      <xsd:element ref="xlf:bx"/>
+      <xsd:element ref="xlf:ex"/>
+    </xsd:choice>
+  </xsd:group>
+  <xsd:attributeGroup name="AttrGroup_TextContent">
+    <xsd:attribute name="id" type="xsd:string" use="required"/>
+    <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+    <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
+    <xsd:anyAttribute namespace="##other" processContents="strict"/>
+  </xsd:attributeGroup>
+  <!-- XLIFF Structure -->
+  <xsd:element name="xliff">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+        <xsd:element ref="xlf:file"/>
+      </xsd:sequence>
+      <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="file">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" ref="xlf:header"/>
+        <xsd:element ref="xlf:body"/>
+      </xsd:sequence>
+      <xsd:attribute name="original" type="xsd:string" use="required"/>
+      <xsd:attribute name="source-language" type="xsd:language" use="required"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute ref="xml:space" use="optional"/>
+      <xsd:attribute name="category" type="xsd:string" use="optional"/>
+      <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
+      <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
+      <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_group_id">
+      <xsd:selector xpath=".//xlf:group"/>
+      <xsd:field xpath="@id"/>
+    </xsd:unique>
+    <xsd:key name="K_unit_id">
+      <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
+      <xsd:field xpath="@id"/>
+    </xsd:key>
+    <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
+      <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
+      <xsd:field xpath="@xid"/>
+    </xsd:keyref>
+    <xsd:key name="K_tool-id">
+      <xsd:selector xpath="xlf:header/xlf:tool"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:key>
+    <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath="."/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:key name="K_count-group_name">
+      <xsd:selector xpath=".//xlf:count-group"/>
+      <xsd:field xpath="@name"/>
+    </xsd:key>
+    <xsd:unique name="U_context-group_name">
+      <xsd:selector xpath=".//xlf:context-group"/>
+      <xsd:field xpath="@name"/>
+    </xsd:unique>
+    <xsd:key name="K_phase-name">
+      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+      <xsd:field xpath="@phase-name"/>
+    </xsd:key>
+    <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
+      <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
+      <xsd:field xpath="@phase-name"/>
+    </xsd:keyref>
+    <xsd:unique name="U_uid">
+      <xsd:selector xpath=".//xlf:external-file"/>
+      <xsd:field xpath="@uid"/>
+    </xsd:unique>
+  </xsd:element>
+  <xsd:element name="header">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
+        <xsd:element minOccurs="0" ref="xlf:phase-group"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
+          <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:tool"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="internal-file">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="form" type="xsd:string"/>
+          <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="external-file">
+    <xsd:complexType>
+      <xsd:attribute name="href" type="xsd:string" use="required"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+      <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="note">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute ref="xml:lang" use="optional"/>
+          <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
+          <xsd:attribute name="from" type="xsd:string" use="optional"/>
+          <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="phase-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:element ref="xlf:phase"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="phase">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:note"/>
+      </xsd:sequence>
+      <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="process-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="count-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:count"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="count">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
+          <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+          <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="context-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:element ref="xlf:context"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="context">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
+          <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
+          <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="tool">
+    <xsd:complexType mixed="true">
+      <xsd:sequence>
+        <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
+      <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="body">
+    <xsd:complexType>
+      <xsd:choice maxOccurs="unbounded" minOccurs="0">
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+      </xsd:choice>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="group">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:sequence>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+          <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+        </xsd:sequence>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+        </xsd:choice>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+      <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="trans-unit">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="xlf:source"/>
+        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+        <xsd:element minOccurs="0" ref="xlf:target"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element ref="xlf:context-group"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:alt-trans"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="required"/>
+      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+      <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_tu_segsrc_mid">
+      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
+      <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="source">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_source_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_source_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="seg-source">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_segsrc_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_segsrc_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="target">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_target_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_target_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="alt-trans">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" ref="xlf:source"/>
+        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+        <xsd:element maxOccurs="1" ref="xlf:target"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:attribute name="origin" type="xsd:string" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_at_segsrc_mid">
+      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
+      <xsd:selector xpath="./xlf:target/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="bin-unit">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="xlf:bin-source"/>
+        <xsd:element minOccurs="0" ref="xlf:bin-target"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element ref="xlf:context-group"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:trans-unit"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="required"/>
+      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
+      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bin-source">
+    <xsd:complexType>
+      <xsd:choice>
+        <xsd:element ref="xlf:internal-file"/>
+        <xsd:element ref="xlf:external-file"/>
+      </xsd:choice>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bin-target">
+    <xsd:complexType>
+      <xsd:choice>
+        <xsd:element ref="xlf:internal-file"/>
+        <xsd:element ref="xlf:external-file"/>
+      </xsd:choice>
+      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
+      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <!-- Element for inline codes -->
+  <xsd:element name="g">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="x">
+    <xsd:complexType>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bx">
+    <xsd:complexType>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ex">
+    <xsd:complexType>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ph">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bpt">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ept">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="it">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="sub">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="mrk">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
+      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="comment" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-2.0.xsd b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-2.0.xsd
new file mode 100644
index 0000000..963232f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-2.0.xsd
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    XLIFF Version 2.0
+    OASIS Standard
+    05 August 2014
+    Copyright (c) OASIS Open 2014. All rights reserved.
+    Source: http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/
+     -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified"
+    xmlns:xlf="urn:oasis:names:tc:xliff:document:2.0"
+    targetNamespace="urn:oasis:names:tc:xliff:document:2.0">
+
+  <!-- Import -->
+
+  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+      schemaLocation="informativeCopiesOf3rdPartySchemas/w3c/xml.xsd"/>
+
+  <!-- Element Group -->
+
+  <xs:group name="inline">
+    <xs:choice>
+      <xs:element ref="xlf:cp"/>
+      <xs:element ref="xlf:ph"/>
+      <xs:element ref="xlf:pc"/>
+      <xs:element ref="xlf:sc"/>
+      <xs:element ref="xlf:ec"/>
+      <xs:element ref="xlf:mrk"/>
+      <xs:element ref="xlf:sm"/>
+      <xs:element ref="xlf:em"/>
+    </xs:choice>
+  </xs:group>
+
+  <!-- Attribute Types -->
+
+  <xs:simpleType name="yesNo">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="yes"/>
+      <xs:enumeration value="no"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="yesNoFirstNo">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="yes"/>
+      <xs:enumeration value="firstNo"/>
+      <xs:enumeration value="no"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="dirValue">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="ltr"/>
+      <xs:enumeration value="rtl"/>
+      <xs:enumeration value="auto"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="appliesTo">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="source"/>
+      <xs:enumeration value="target"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="userDefinedValue">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="[^\s:]+:[^\s:]+"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="attrType_type">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="fmt"/>
+      <xs:enumeration value="ui"/>
+      <xs:enumeration value="quote"/>
+      <xs:enumeration value="link"/>
+      <xs:enumeration value="image"/>
+      <xs:enumeration value="other"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="typeForMrkValues">
+    <xs:restriction base="xs:NMTOKEN">
+      <xs:enumeration value="generic"/>
+      <xs:enumeration value="comment"/>
+      <xs:enumeration value="term"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="attrType_typeForMrk">
+    <xs:union memberTypes="xlf:typeForMrkValues xlf:userDefinedValue"/>
+  </xs:simpleType>
+
+  <xs:simpleType name="priorityValue">
+    <xs:restriction base="xs:positiveInteger">
+      <xs:minInclusive value="1"/>
+      <xs:maxInclusive value="10"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="stateType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="initial"/>
+      <xs:enumeration value="translated"/>
+      <xs:enumeration value="reviewed"/>
+      <xs:enumeration value="final"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <!-- Structural Elements -->
+
+  <xs:element name="xliff">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:file"/>
+      </xs:sequence>
+      <xs:attribute name="version" use="required"/>
+      <xs:attribute name="srcLang" use="required"/>
+      <xs:attribute name="trgLang" use="optional"/>
+      <xs:attribute ref="xml:space" use="optional" default="default"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="file">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:skeleton"/>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
+        <xs:choice minOccurs="1" maxOccurs="unbounded">
+          <xs:element ref="xlf:unit"/>
+          <xs:element ref="xlf:group"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="original" use="optional"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue" default="auto"/>
+      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue" default="auto"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="skeleton">
+    <xs:complexType mixed="true">
+      <xs:sequence>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+      </xs:sequence>
+      <xs:attribute name="href" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="group">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element ref="xlf:unit"/>
+          <xs:element ref="xlf:group"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="name" use="optional"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="unit">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:originalData"/>
+        <xs:choice minOccurs="1" maxOccurs="unbounded">
+          <xs:element ref="xlf:segment"/>
+          <xs:element ref="xlf:ignorable"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="name" use="optional"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="segment">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
+      </xs:sequence>
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="state" use="optional" type="xlf:stateType" default="initial"/>
+      <xs:attribute name="subState" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="ignorable">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
+      </xs:sequence>
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="notes">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:note"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="note">
+    <xs:complexType mixed="true">
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="appliesTo" use="optional" type="xlf:appliesTo"/>
+      <xs:attribute name="category" use="optional"/>
+      <xs:attribute name="priority" use="optional" type="xlf:priorityValue" default="1"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="originalData">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:data"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="data">
+    <xs:complexType mixed="true">
+      <xs:sequence>
+        <xs:element minOccurs="0" maxOccurs="unbounded" ref="xlf:cp"/>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue" default="auto"/>
+      <xs:attribute ref="xml:space" use="optional" fixed="preserve"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="source">
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute ref="xml:lang" use="optional"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="target">
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute ref="xml:lang" use="optional"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:attribute name="order" use="optional" type="xs:positiveInteger"/>
+    </xs:complexType>
+  </xs:element>
+
+  <!-- Inline Elements -->
+
+  <xs:element name="cp">
+    <!-- Code Point -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="hex" use="required" type="xs:hexBinary"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="ph">
+    <!-- Placeholder -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="disp" use="optional"/>
+      <xs:attribute name="equiv" use="optional"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="pc">
+    <!-- Paired Code -->
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dispEnd" use="optional"/>
+      <xs:attribute name="dispStart" use="optional"/>
+      <xs:attribute name="equivEnd" use="optional"/>
+      <xs:attribute name="equivStart" use="optional"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRefEnd" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRefStart" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="subFlowsEnd" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subFlowsStart" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="sc">
+    <!-- Start Code -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="disp" use="optional"/>
+      <xs:attribute name="equiv" use="optional"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
+      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="ec">
+    <!-- End Code -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="disp" use="optional"/>
+      <xs:attribute name="equiv" use="optional"/>
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
+      <xs:attribute name="startRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="mrk">
+    <!-- Annotation Marker -->
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
+      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
+      <xs:attribute name="value" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="sm">
+    <!-- Start Annotation Marker -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
+      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
+      <xs:attribute name="value" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="em">
+    <!-- End Annotation Marker -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="startRef" use="required" type="xs:NMTOKEN"/>
+    </xs:complexType>
+  </xs:element>
+
+</xs:schema>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xml.xsd b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xml.xsd
new file mode 100644
index 0000000..a46162a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xml.xsd
@@ -0,0 +1,309 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+  xmlns ="http://www.w3.org/1999/xhtml"
+  xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+    <h1>About the XML namespace</h1>
+
+    <div class="bodytext">
+     <p>
+
+      This schema document describes the XML namespace, in a form
+      suitable for import by other schema documents.
+     </p>
+     <p>
+      See <a href="http://www.w3.org/XML/1998/namespace.html">
+      http://www.w3.org/XML/1998/namespace.html</a> and
+      <a href="http://www.w3.org/TR/REC-xml">
+      http://www.w3.org/TR/REC-xml</a> for information 
+      about this namespace.
+     </p>
+
+     <p>
+      Note that local names in this namespace are intended to be
+      defined only by the World Wide Web Consortium or its subgroups.
+      The names currently defined in this namespace are listed below.
+      They should not be used with conflicting semantics by any Working
+      Group, specification, or document instance.
+     </p>
+     <p>   
+      See further below in this document for more information about <a
+      href="#usage">how to refer to this schema document from your own
+      XSD schema documents</a> and about <a href="#nsversioning">the
+      namespace-versioning policy governing this schema document</a>.
+     </p>
+    </div>
+   </div>
+
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>lang (as an attribute name)</h3>
+      <p>
+
+       denotes an attribute whose value
+       is a language code for the natural language of the content of
+       any element; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML specification.</p>
+     
+    </div>
+    <div>
+     <h4>Notes</h4>
+     <p>
+      Attempting to install the relevant ISO 2- and 3-letter
+      codes as the enumerated possible values is probably never
+      going to be a realistic possibility.  
+     </p>
+     <p>
+
+      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+      and the IANA language subtag registry at
+      <a href="http://www.iana.org/assignments/language-subtag-registry">
+       http://www.iana.org/assignments/language-subtag-registry</a>
+      for further information.
+     </p>
+     <p>
+
+      The union allows for the 'un-declaration' of xml:lang with
+      the empty string.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:union memberTypes="xs:language">
+    <xs:simpleType>    
+     <xs:restriction base="xs:string">
+      <xs:enumeration value=""/>
+
+     </xs:restriction>
+    </xs:simpleType>
+   </xs:union>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+  <xs:annotation>
+   <xs:documentation>
+
+    <div>
+     
+      <h3>space (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose
+       value is a keyword indicating what whitespace processing
+       discipline is intended for the content of the element; its
+       value is inherited.  This name is reserved by virtue of its
+       definition in the XML specification.</p>
+     
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+
+   <xs:restriction base="xs:NCName">
+    <xs:enumeration value="default"/>
+    <xs:enumeration value="preserve"/>
+   </xs:restriction>
+  </xs:simpleType>
+ </xs:attribute>
+ 
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+   <xs:documentation>
+
+    <div>
+     
+      <h3>base (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose value
+       provides a URI to be used as the base for interpreting any
+       relative URIs in the scope of the element on which it
+       appears; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML Base specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+      for information about this attribute.
+     </p>
+
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ 
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>id (as an attribute name)</h3> 
+      <p>
+
+       denotes an attribute whose value
+       should be interpreted as if declared to be of type ID.
+       This name is reserved by virtue of its definition in the
+       xml:id specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+  <xs:attribute ref="xml:base"/>
+  <xs:attribute ref="xml:lang"/>
+  <xs:attribute ref="xml:space"/>
+  <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+
+  <xs:documentation>
+   <div>
+   
+    <h3>Father (in any context at all)</h3> 
+
+    <div class="bodytext">
+     <p>
+      denotes Jon Bosak, the chair of 
+      the original XML Working Group.  This name is reserved by 
+      the following decision of the W3C XML Plenary and 
+      XML Coordination groups:
+     </p>
+     <blockquote>
+       <p>
+
+	In appreciation for his vision, leadership and
+	dedication the W3C XML Plenary on this 10th day of
+	February, 2000, reserves for Jon Bosak in perpetuity
+	the XML name "xml:Father".
+       </p>
+     </blockquote>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+
+   <div xml:id="usage" id="usage">
+    <h2><a name="usage">About this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      This schema defines attributes and an attribute group suitable
+      for use by schemas wishing to allow <code>xml:base</code>,
+      <code>xml:lang</code>, <code>xml:space</code> or
+      <code>xml:id</code> attributes on elements they define.
+     </p>
+
+     <p>
+      To enable this, such a schema must import this schema for
+      the XML namespace, e.g. as follows:
+     </p>
+     <pre>
+          &lt;schema.. .>
+          .. .
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+     </pre>
+     <p>
+      or
+     </p>
+     <pre>
+
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+     </pre>
+     <p>
+      Subsequently, qualified reference to any of the attributes or the
+      group defined below will have the desired effect, e.g.
+     </p>
+     <pre>
+          &lt;type.. .>
+          .. .
+           &lt;attributeGroup ref="xml:specialAttrs"/>
+     </pre>
+     <p>
+      will define a type which will schema-validate an instance element
+      with any of those attributes.
+     </p>
+
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div id="nsversioning" xml:id="nsversioning">
+    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      In keeping with the XML Schema WG's standard versioning
+      policy, this schema document will persist at
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd</a>.
+     </p>
+     <p>
+      At the date of issue it can also be found at
+      <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd</a>.
+     </p>
+
+     <p>
+      The schema document at that URI may however change in the future,
+      in order to remain compatible with the latest version of XML
+      Schema itself, or with the XML namespace itself.  In other words,
+      if the XML Schema or XML namespaces change, the version of this
+      document at <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd 
+      </a> 
+      will change accordingly; the version at 
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd 
+      </a> 
+      will not change.
+     </p>
+     <p>
+
+      Previous dated (and unchanging) versions of this schema 
+      document are at:
+     </p>
+     <ul>
+      <li><a href="http://www.w3.org/2009/01/xml.xsd">
+	http://www.w3.org/2009/01/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2007/08/xml.xsd">
+	http://www.w3.org/2007/08/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2004/10/xml.xsd">
+
+	http://www.w3.org/2004/10/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2001/03/xml.xsd">
+	http://www.w3.org/2001/03/xml.xsd</a></li>
+     </ul>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderFactoryTestCase.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderFactoryTestCase.php
new file mode 100644
index 0000000..6d5f4b7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderFactoryTestCase.php
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Test;
+
+use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpClient\MockHttpClient;
+use Symfony\Component\Translation\Dumper\XliffFileDumper;
+use Symfony\Component\Translation\Exception\IncompleteDsnException;
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Provider\Dsn;
+use Symfony\Component\Translation\Provider\ProviderFactoryInterface;
+use Symfony\Contracts\HttpClient\HttpClientInterface;
+
+/**
+ * A test case to ease testing a translation provider factory.
+ *
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @internal
+ */
+abstract class ProviderFactoryTestCase extends TestCase
+{
+    protected $client;
+    protected $logger;
+    protected $defaultLocale;
+    protected $loader;
+    protected $xliffFileDumper;
+
+    abstract public function createFactory(): ProviderFactoryInterface;
+
+    /**
+     * @return iterable<array{0: bool, 1: string}>
+     */
+    abstract public function supportsProvider(): iterable;
+
+    /**
+     * @return iterable<array{0: string, 1: string, 2: TransportInterface}>
+     */
+    abstract public function createProvider(): iterable;
+
+    /**
+     * @return iterable<array{0: string, 1: string|null}>
+     */
+    public function unsupportedSchemeProvider(): iterable
+    {
+        return [];
+    }
+
+    /**
+     * @return iterable<array{0: string, 1: string|null}>
+     */
+    public function incompleteDsnProvider(): iterable
+    {
+        return [];
+    }
+
+    /**
+     * @dataProvider supportsProvider
+     */
+    public function testSupports(bool $expected, string $dsn)
+    {
+        $factory = $this->createFactory();
+
+        $this->assertSame($expected, $factory->supports(new Dsn($dsn)));
+    }
+
+    /**
+     * @dataProvider createProvider
+     */
+    public function testCreate(string $expected, string $dsn)
+    {
+        $factory = $this->createFactory();
+        $provider = $factory->create(new Dsn($dsn));
+
+        $this->assertSame($expected, (string) $provider);
+    }
+
+    /**
+     * @dataProvider unsupportedSchemeProvider
+     */
+    public function testUnsupportedSchemeException(string $dsn, string $message = null)
+    {
+        $factory = $this->createFactory();
+
+        $dsn = new Dsn($dsn);
+
+        $this->expectException(UnsupportedSchemeException::class);
+        if (null !== $message) {
+            $this->expectExceptionMessage($message);
+        }
+
+        $factory->create($dsn);
+    }
+
+    /**
+     * @dataProvider incompleteDsnProvider
+     */
+    public function testIncompleteDsnException(string $dsn, string $message = null)
+    {
+        $factory = $this->createFactory();
+
+        $dsn = new Dsn($dsn);
+
+        $this->expectException(IncompleteDsnException::class);
+        if (null !== $message) {
+            $this->expectExceptionMessage($message);
+        }
+
+        $factory->create($dsn);
+    }
+
+    protected function getClient(): HttpClientInterface
+    {
+        return $this->client ?? $this->client = new MockHttpClient();
+    }
+
+    protected function getLogger(): LoggerInterface
+    {
+        return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
+    }
+
+    protected function getDefaultLocale(): string
+    {
+        return $this->defaultLocale ?? $this->defaultLocale = 'en';
+    }
+
+    protected function getLoader(): LoaderInterface
+    {
+        return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class);
+    }
+
+    protected function getXliffFileDumper(): XliffFileDumper
+    {
+        return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderTestCase.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderTestCase.php
new file mode 100644
index 0000000..238fd96
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderTestCase.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Test;
+
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpClient\MockHttpClient;
+use Symfony\Component\Translation\Dumper\XliffFileDumper;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Provider\ProviderInterface;
+use Symfony\Contracts\HttpClient\HttpClientInterface;
+
+/**
+ * A test case to ease testing a translation provider.
+ *
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @internal
+ */
+abstract class ProviderTestCase extends TestCase
+{
+    protected $client;
+    protected $logger;
+    protected $defaultLocale;
+    protected $loader;
+    protected $xliffFileDumper;
+
+    abstract public function createProvider(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, string $defaultLocale, string $endpoint): ProviderInterface;
+
+    /**
+     * @return iterable<array{0: string, 1: ProviderInterface}>
+     */
+    abstract public function toStringProvider(): iterable;
+
+    /**
+     * @dataProvider toStringProvider
+     */
+    public function testToString(ProviderInterface $provider, string $expected)
+    {
+        $this->assertSame($expected, (string) $provider);
+    }
+
+    protected function getClient(): MockHttpClient
+    {
+        return $this->client ?? $this->client = new MockHttpClient();
+    }
+
+    /**
+     * @return LoaderInterface&MockObject
+     */
+    protected function getLoader(): LoaderInterface
+    {
+        return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class);
+    }
+
+    /**
+     * @return LoaderInterface&MockObject
+     */
+    protected function getLogger(): LoggerInterface
+    {
+        return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
+    }
+
+    protected function getDefaultLocale(): string
+    {
+        return $this->defaultLocale ?? $this->defaultLocale = 'en';
+    }
+
+    /**
+     * @return LoaderInterface&MockObject
+     */
+    protected function getXliffFileDumper(): XliffFileDumper
+    {
+        return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatableMessage.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatableMessage.php
new file mode 100644
index 0000000..82ae6d7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatableMessage.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Contracts\Translation\TranslatableInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Nate Wiebe <nate@northern.co>
+ */
+class TranslatableMessage implements TranslatableInterface
+{
+    private $message;
+    private $parameters;
+    private $domain;
+
+    public function __construct(string $message, array $parameters = [], string $domain = null)
+    {
+        $this->message = $message;
+        $this->parameters = $parameters;
+        $this->domain = $domain;
+    }
+
+    public function __toString(): string
+    {
+        return $this->getMessage();
+    }
+
+    public function getMessage(): string
+    {
+        return $this->message;
+    }
+
+    public function getParameters(): array
+    {
+        return $this->parameters;
+    }
+
+    public function getDomain(): ?string
+    {
+        return $this->domain;
+    }
+
+    public function trans(TranslatorInterface $translator, string $locale = null): string
+    {
+        return $translator->trans($this->getMessage(), $this->getParameters(), $this->getDomain(), $locale);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Translator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Translator.php
new file mode 100644
index 0000000..9a63956
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Translator.php
@@ -0,0 +1,490 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\ConfigCacheFactory;
+use Symfony\Component\Config\ConfigCacheFactoryInterface;
+use Symfony\Component\Config\ConfigCacheInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\Formatter\IntlFormatterInterface;
+use Symfony\Component\Translation\Formatter\MessageFormatter;
+use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+// Help opcache.preload discover always-needed symbols
+class_exists(MessageCatalogue::class);
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
+{
+    /**
+     * @var MessageCatalogueInterface[]
+     */
+    protected $catalogues = [];
+
+    /**
+     * @var string
+     */
+    private $locale;
+
+    /**
+     * @var array
+     */
+    private $fallbackLocales = [];
+
+    /**
+     * @var LoaderInterface[]
+     */
+    private $loaders = [];
+
+    /**
+     * @var array
+     */
+    private $resources = [];
+
+    /**
+     * @var MessageFormatterInterface
+     */
+    private $formatter;
+
+    /**
+     * @var string
+     */
+    private $cacheDir;
+
+    /**
+     * @var bool
+     */
+    private $debug;
+
+    private $cacheVary;
+
+    /**
+     * @var ConfigCacheFactoryInterface|null
+     */
+    private $configCacheFactory;
+
+    /**
+     * @var array|null
+     */
+    private $parentLocales;
+
+    private $hasIntlFormatter;
+
+    /**
+     * @throws InvalidArgumentException If a locale contains invalid characters
+     */
+    public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
+    {
+        $this->setLocale($locale);
+
+        if (null === $formatter) {
+            $formatter = new MessageFormatter();
+        }
+
+        $this->formatter = $formatter;
+        $this->cacheDir = $cacheDir;
+        $this->debug = $debug;
+        $this->cacheVary = $cacheVary;
+        $this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
+    }
+
+    public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
+    {
+        $this->configCacheFactory = $configCacheFactory;
+    }
+
+    /**
+     * Adds a Loader.
+     *
+     * @param string $format The name of the loader (@see addResource())
+     */
+    public function addLoader(string $format, LoaderInterface $loader)
+    {
+        $this->loaders[$format] = $loader;
+    }
+
+    /**
+     * Adds a Resource.
+     *
+     * @param string $format   The name of the loader (@see addLoader())
+     * @param mixed  $resource The resource name
+     *
+     * @throws InvalidArgumentException If the locale contains invalid characters
+     */
+    public function addResource(string $format, $resource, string $locale, string $domain = null)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $this->assertValidLocale($locale);
+        $locale ?: $locale = class_exists(\Locale::class) ? \Locale::getDefault() : 'en';
+
+        $this->resources[$locale][] = [$format, $resource, $domain];
+
+        if (\in_array($locale, $this->fallbackLocales)) {
+            $this->catalogues = [];
+        } else {
+            unset($this->catalogues[$locale]);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $this->assertValidLocale($locale);
+        $this->locale = $locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en');
+    }
+
+    /**
+     * Sets the fallback locales.
+     *
+     * @throws InvalidArgumentException If a locale contains invalid characters
+     */
+    public function setFallbackLocales(array $locales)
+    {
+        // needed as the fallback locales are linked to the already loaded catalogues
+        $this->catalogues = [];
+
+        foreach ($locales as $locale) {
+            $this->assertValidLocale($locale);
+        }
+
+        $this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @internal
+     */
+    public function getFallbackLocales(): array
+    {
+        return $this->fallbackLocales;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        if (null === $id || '' === $id) {
+            return '';
+        }
+
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $catalogue = $this->getCatalogue($locale);
+        $locale = $catalogue->getLocale();
+        while (!$catalogue->defines($id, $domain)) {
+            if ($cat = $catalogue->getFallbackCatalogue()) {
+                $catalogue = $cat;
+                $locale = $catalogue->getLocale();
+            } else {
+                break;
+            }
+        }
+
+        $len = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX);
+        if ($this->hasIntlFormatter
+            && ($catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)
+            || (\strlen($domain) > $len && 0 === substr_compare($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX, -$len, $len)))
+        ) {
+            return $this->formatter->formatIntl($catalogue->get($id, $domain), $locale, $parameters);
+        }
+
+        return $this->formatter->format($catalogue->get($id, $domain), $locale, $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        if (!$locale) {
+            $locale = $this->getLocale();
+        } else {
+            $this->assertValidLocale($locale);
+        }
+
+        if (!isset($this->catalogues[$locale])) {
+            $this->loadCatalogue($locale);
+        }
+
+        return $this->catalogues[$locale];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return array_values($this->catalogues);
+    }
+
+    /**
+     * Gets the loaders.
+     *
+     * @return array LoaderInterface[]
+     */
+    protected function getLoaders()
+    {
+        return $this->loaders;
+    }
+
+    protected function loadCatalogue(string $locale)
+    {
+        if (null === $this->cacheDir) {
+            $this->initializeCatalogue($locale);
+        } else {
+            $this->initializeCacheCatalogue($locale);
+        }
+    }
+
+    protected function initializeCatalogue(string $locale)
+    {
+        $this->assertValidLocale($locale);
+
+        try {
+            $this->doLoadCatalogue($locale);
+        } catch (NotFoundResourceException $e) {
+            if (!$this->computeFallbackLocales($locale)) {
+                throw $e;
+            }
+        }
+        $this->loadFallbackCatalogues($locale);
+    }
+
+    private function initializeCacheCatalogue(string $locale): void
+    {
+        if (isset($this->catalogues[$locale])) {
+            /* Catalogue already initialized. */
+            return;
+        }
+
+        $this->assertValidLocale($locale);
+        $cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale),
+            function (ConfigCacheInterface $cache) use ($locale) {
+                $this->dumpCatalogue($locale, $cache);
+            }
+        );
+
+        if (isset($this->catalogues[$locale])) {
+            /* Catalogue has been initialized as it was written out to cache. */
+            return;
+        }
+
+        /* Read catalogue from cache. */
+        $this->catalogues[$locale] = include $cache->getPath();
+    }
+
+    private function dumpCatalogue(string $locale, ConfigCacheInterface $cache): void
+    {
+        $this->initializeCatalogue($locale);
+        $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);
+
+        $content = sprintf(<<<EOF
+<?php
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+\$catalogue = new MessageCatalogue('%s', %s);
+
+%s
+return \$catalogue;
+
+EOF
+            ,
+            $locale,
+            var_export($this->getAllMessages($this->catalogues[$locale]), true),
+            $fallbackContent
+        );
+
+        $cache->write($content, $this->catalogues[$locale]->getResources());
+    }
+
+    private function getFallbackContent(MessageCatalogue $catalogue): string
+    {
+        $fallbackContent = '';
+        $current = '';
+        $replacementPattern = '/[^a-z0-9_]/i';
+        $fallbackCatalogue = $catalogue->getFallbackCatalogue();
+        while ($fallbackCatalogue) {
+            $fallback = $fallbackCatalogue->getLocale();
+            $fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
+            $currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
+
+            $fallbackContent .= sprintf(<<<'EOF'
+$catalogue%s = new MessageCatalogue('%s', %s);
+$catalogue%s->addFallbackCatalogue($catalogue%s);
+
+EOF
+                ,
+                $fallbackSuffix,
+                $fallback,
+                var_export($this->getAllMessages($fallbackCatalogue), true),
+                $currentSuffix,
+                $fallbackSuffix
+            );
+            $current = $fallbackCatalogue->getLocale();
+            $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
+        }
+
+        return $fallbackContent;
+    }
+
+    private function getCatalogueCachePath(string $locale): string
+    {
+        return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php';
+    }
+
+    /**
+     * @internal
+     */
+    protected function doLoadCatalogue(string $locale): void
+    {
+        $this->catalogues[$locale] = new MessageCatalogue($locale);
+
+        if (isset($this->resources[$locale])) {
+            foreach ($this->resources[$locale] as $resource) {
+                if (!isset($this->loaders[$resource[0]])) {
+                    if (\is_string($resource[1])) {
+                        throw new RuntimeException(sprintf('No loader is registered for the "%s" format when loading the "%s" resource.', $resource[0], $resource[1]));
+                    }
+
+                    throw new RuntimeException(sprintf('No loader is registered for the "%s" format.', $resource[0]));
+                }
+                $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
+            }
+        }
+    }
+
+    private function loadFallbackCatalogues(string $locale): void
+    {
+        $current = $this->catalogues[$locale];
+
+        foreach ($this->computeFallbackLocales($locale) as $fallback) {
+            if (!isset($this->catalogues[$fallback])) {
+                $this->initializeCatalogue($fallback);
+            }
+
+            $fallbackCatalogue = new MessageCatalogue($fallback, $this->getAllMessages($this->catalogues[$fallback]));
+            foreach ($this->catalogues[$fallback]->getResources() as $resource) {
+                $fallbackCatalogue->addResource($resource);
+            }
+            $current->addFallbackCatalogue($fallbackCatalogue);
+            $current = $fallbackCatalogue;
+        }
+    }
+
+    protected function computeFallbackLocales(string $locale)
+    {
+        if (null === $this->parentLocales) {
+            $this->parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
+        }
+
+        $locales = [];
+        foreach ($this->fallbackLocales as $fallback) {
+            if ($fallback === $locale) {
+                continue;
+            }
+
+            $locales[] = $fallback;
+        }
+
+        while ($locale) {
+            $parent = $this->parentLocales[$locale] ?? null;
+
+            if ($parent) {
+                $locale = 'root' !== $parent ? $parent : null;
+            } elseif (\function_exists('locale_parse')) {
+                $localeSubTags = locale_parse($locale);
+                $locale = null;
+                if (1 < \count($localeSubTags)) {
+                    array_pop($localeSubTags);
+                    $locale = locale_compose($localeSubTags) ?: null;
+                }
+            } elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
+                $locale = substr($locale, 0, $i);
+            } else {
+                $locale = null;
+            }
+
+            if (null !== $locale) {
+                array_unshift($locales, $locale);
+            }
+        }
+
+        return array_unique($locales);
+    }
+
+    /**
+     * Asserts that the locale is valid, throws an Exception if not.
+     *
+     * @throws InvalidArgumentException If the locale contains invalid characters
+     */
+    protected function assertValidLocale(string $locale)
+    {
+        if (!preg_match('/^[a-z0-9@_\\.\\-]*$/i', (string) $locale)) {
+            throw new InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
+        }
+    }
+
+    /**
+     * Provides the ConfigCache factory implementation, falling back to a
+     * default implementation if necessary.
+     */
+    private function getConfigCacheFactory(): ConfigCacheFactoryInterface
+    {
+        if (!$this->configCacheFactory) {
+            $this->configCacheFactory = new ConfigCacheFactory($this->debug);
+        }
+
+        return $this->configCacheFactory;
+    }
+
+    private function getAllMessages(MessageCatalogueInterface $catalogue): array
+    {
+        $allMessages = [];
+
+        foreach ($catalogue->all() as $domain => $messages) {
+            if ($intlMessages = $catalogue->all($domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
+                $allMessages[$domain.MessageCatalogue::INTL_DOMAIN_SUFFIX] = $intlMessages;
+                $messages = array_diff_key($messages, $intlMessages);
+            }
+            if ($messages) {
+                $allMessages[$domain] = $messages;
+            }
+        }
+
+        return $allMessages;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBag.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBag.php
new file mode 100644
index 0000000..c655578
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBag.php
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Translation\Catalogue\AbstractOperation;
+use Symfony\Component\Translation\Catalogue\TargetOperation;
+
+final class TranslatorBag implements TranslatorBagInterface
+{
+    /** @var MessageCatalogue[] */
+    private $catalogues = [];
+
+    public function addCatalogue(MessageCatalogue $catalogue): void
+    {
+        if (null !== $existingCatalogue = $this->getCatalogue($catalogue->getLocale())) {
+            $catalogue->addCatalogue($existingCatalogue);
+        }
+
+        $this->catalogues[$catalogue->getLocale()] = $catalogue;
+    }
+
+    public function addBag(TranslatorBagInterface $bag): void
+    {
+        foreach ($bag->getCatalogues() as $catalogue) {
+            $this->addCatalogue($catalogue);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        if (null === $locale || !isset($this->catalogues[$locale])) {
+            $this->catalogues[$locale] = new MessageCatalogue($locale);
+        }
+
+        return $this->catalogues[$locale];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return array_values($this->catalogues);
+    }
+
+    public function diff(TranslatorBagInterface $diffBag): self
+    {
+        $diff = new self();
+
+        foreach ($this->catalogues as $locale => $catalogue) {
+            if (null === $diffCatalogue = $diffBag->getCatalogue($locale)) {
+                $diff->addCatalogue($catalogue);
+
+                continue;
+            }
+
+            $operation = new TargetOperation($diffCatalogue, $catalogue);
+            $operation->moveMessagesToIntlDomainsIfPossible(AbstractOperation::NEW_BATCH);
+            $newCatalogue = new MessageCatalogue($locale);
+
+            foreach ($operation->getDomains() as $domain) {
+                $newCatalogue->add($operation->getNewMessages($domain), $domain);
+            }
+
+            $diff->addCatalogue($newCatalogue);
+        }
+
+        return $diff;
+    }
+
+    public function intersect(TranslatorBagInterface $intersectBag): self
+    {
+        $diff = new self();
+
+        foreach ($this->catalogues as $locale => $catalogue) {
+            if (null === $intersectCatalogue = $intersectBag->getCatalogue($locale)) {
+                continue;
+            }
+
+            $operation = new TargetOperation($catalogue, $intersectCatalogue);
+            $operation->moveMessagesToIntlDomainsIfPossible(AbstractOperation::OBSOLETE_BATCH);
+            $obsoleteCatalogue = new MessageCatalogue($locale);
+
+            foreach ($operation->getDomains() as $domain) {
+                $obsoleteCatalogue->add($operation->getObsoleteMessages($domain), $domain);
+            }
+
+            $diff->addCatalogue($obsoleteCatalogue);
+        }
+
+        return $diff;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBagInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBagInterface.php
new file mode 100644
index 0000000..4228977
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBagInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * TranslatorBagInterface.
+ *
+ * @method MessageCatalogueInterface[] getCatalogues() Returns all catalogues of the instance
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+interface TranslatorBagInterface
+{
+    /**
+     * Gets the catalogue by locale.
+     *
+     * @param string|null $locale The locale or null to use the default
+     *
+     * @return MessageCatalogueInterface
+     *
+     * @throws InvalidArgumentException If the locale contains invalid characters
+     */
+    public function getCatalogue(string $locale = null);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/ArrayConverter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/ArrayConverter.php
new file mode 100644
index 0000000..acfbfc3
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/ArrayConverter.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Util;
+
+/**
+ * ArrayConverter generates tree like structure from a message catalogue.
+ * e.g. this
+ *   'foo.bar1' => 'test1',
+ *   'foo.bar2' => 'test2'
+ * converts to follows:
+ *   foo:
+ *     bar1: test1
+ *     bar2: test2.
+ *
+ * @author Gennady Telegin <gtelegin@gmail.com>
+ */
+class ArrayConverter
+{
+    /**
+     * Converts linear messages array to tree-like array.
+     * For example this array('foo.bar' => 'value') will be converted to ['foo' => ['bar' => 'value']].
+     *
+     * @param array $messages Linear messages array
+     *
+     * @return array Tree-like messages array
+     */
+    public static function expandToTree(array $messages)
+    {
+        $tree = [];
+
+        foreach ($messages as $id => $value) {
+            $referenceToElement = &self::getElementByPath($tree, explode('.', $id));
+
+            $referenceToElement = $value;
+
+            unset($referenceToElement);
+        }
+
+        return $tree;
+    }
+
+    private static function &getElementByPath(array &$tree, array $parts)
+    {
+        $elem = &$tree;
+        $parentOfElem = null;
+
+        foreach ($parts as $i => $part) {
+            if (isset($elem[$part]) && \is_string($elem[$part])) {
+                /* Process next case:
+                 *    'foo': 'test1',
+                 *    'foo.bar': 'test2'
+                 *
+                 * $tree['foo'] was string before we found array {bar: test2}.
+                 *  Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2';
+                 */
+                $elem = &$elem[implode('.', \array_slice($parts, $i))];
+                break;
+            }
+            $parentOfElem = &$elem;
+            $elem = &$elem[$part];
+        }
+
+        if ($elem && \is_array($elem) && $parentOfElem) {
+            /* Process next case:
+             *    'foo.bar': 'test1'
+             *    'foo': 'test2'
+             *
+             * $tree['foo'] was array = {bar: 'test1'} before we found string constant `foo`.
+             * Cancel treating $tree['foo'] as array and cancel back it expansion,
+             *  e.g. make it $tree['foo.bar'] = 'test1' again.
+             */
+            self::cancelExpand($parentOfElem, $part, $elem);
+        }
+
+        return $elem;
+    }
+
+    private static function cancelExpand(array &$tree, string $prefix, array $node)
+    {
+        $prefix .= '.';
+
+        foreach ($node as $id => $value) {
+            if (\is_string($value)) {
+                $tree[$prefix.$id] = $value;
+            } else {
+                self::cancelExpand($tree, $prefix.$id, $value);
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/XliffUtils.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/XliffUtils.php
new file mode 100644
index 0000000..e4373a7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/XliffUtils.php
@@ -0,0 +1,196 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Util;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+
+/**
+ * Provides some utility methods for XLIFF translation files, such as validating
+ * their contents according to the XSD schema.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class XliffUtils
+{
+    /**
+     * Gets xliff file version based on the root "version" attribute.
+     *
+     * Defaults to 1.2 for backwards compatibility.
+     *
+     * @throws InvalidArgumentException
+     */
+    public static function getVersionNumber(\DOMDocument $dom): string
+    {
+        /** @var \DOMNode $xliff */
+        foreach ($dom->getElementsByTagName('xliff') as $xliff) {
+            $version = $xliff->attributes->getNamedItem('version');
+            if ($version) {
+                return $version->nodeValue;
+            }
+
+            $namespace = $xliff->attributes->getNamedItem('xmlns');
+            if ($namespace) {
+                if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) {
+                    throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s".', $namespace));
+                }
+
+                return substr($namespace, 34);
+            }
+        }
+
+        // Falls back to v1.2
+        return '1.2';
+    }
+
+    /**
+     * Validates and parses the given file into a DOMDocument.
+     *
+     * @throws InvalidResourceException
+     */
+    public static function validateSchema(\DOMDocument $dom): array
+    {
+        $xliffVersion = static::getVersionNumber($dom);
+        $internalErrors = libxml_use_internal_errors(true);
+        if ($shouldEnable = self::shouldEnableEntityLoader()) {
+            $disableEntities = libxml_disable_entity_loader(false);
+        }
+        try {
+            $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
+            if (!$isValid) {
+                return self::getXmlErrors($internalErrors);
+            }
+        } finally {
+            if ($shouldEnable) {
+                libxml_disable_entity_loader($disableEntities);
+            }
+        }
+
+        $dom->normalizeDocument();
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return [];
+    }
+
+    private static function shouldEnableEntityLoader(): bool
+    {
+        // Version prior to 8.0 can be enabled without deprecation
+        if (\PHP_VERSION_ID < 80000) {
+            return true;
+        }
+
+        static $dom, $schema;
+        if (null === $dom) {
+            $dom = new \DOMDocument();
+            $dom->loadXML('<?xml version="1.0"?><test/>');
+
+            $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+            register_shutdown_function(static function () use ($tmpfile) {
+                @unlink($tmpfile);
+            });
+            $schema = '<?xml version="1.0" encoding="utf-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:include schemaLocation="file:///'.str_replace('\\', '/', $tmpfile).'" />
+</xsd:schema>';
+            file_put_contents($tmpfile, '<?xml version="1.0" encoding="utf-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:element name="test" type="testType" />
+  <xsd:complexType name="testType"/>
+</xsd:schema>');
+        }
+
+        return !@$dom->schemaValidateSource($schema);
+    }
+
+    public static function getErrorsAsString(array $xmlErrors): string
+    {
+        $errorsAsString = '';
+
+        foreach ($xmlErrors as $error) {
+            $errorsAsString .= sprintf("[%s %s] %s (in %s - line %d, column %d)\n",
+                \LIBXML_ERR_WARNING === $error['level'] ? 'WARNING' : 'ERROR',
+                $error['code'],
+                $error['message'],
+                $error['file'],
+                $error['line'],
+                $error['column']
+            );
+        }
+
+        return $errorsAsString;
+    }
+
+    private static function getSchema(string $xliffVersion): string
+    {
+        if ('1.2' === $xliffVersion) {
+            $schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-1.2-strict.xsd');
+            $xmlUri = 'http://www.w3.org/2001/xml.xsd';
+        } elseif ('2.0' === $xliffVersion) {
+            $schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-2.0.xsd');
+            $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd';
+        } else {
+            throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
+        }
+
+        return self::fixXmlLocation($schemaSource, $xmlUri);
+    }
+
+    /**
+     * Internally changes the URI of a dependent xsd to be loaded locally.
+     */
+    private static function fixXmlLocation(string $schemaSource, string $xmlUri): string
+    {
+        $newPath = str_replace('\\', '/', __DIR__).'/../Resources/schemas/xml.xsd';
+        $parts = explode('/', $newPath);
+        $locationstart = 'file:///';
+        if (0 === stripos($newPath, 'phar://')) {
+            $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+            if ($tmpfile) {
+                copy($newPath, $tmpfile);
+                $parts = explode('/', str_replace('\\', '/', $tmpfile));
+            } else {
+                array_shift($parts);
+                $locationstart = 'phar:///';
+            }
+        }
+
+        $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
+        $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));
+
+        return str_replace($xmlUri, $newPath, $schemaSource);
+    }
+
+    /**
+     * Returns the XML errors of the internal XML parser.
+     */
+    private static function getXmlErrors(bool $internalErrors): array
+    {
+        $errors = [];
+        foreach (libxml_get_errors() as $error) {
+            $errors[] = [
+                'level' => \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+                'code' => $error->code,
+                'message' => trim($error->message),
+                'file' => $error->file ?: 'n/a',
+                'line' => $error->line,
+                'column' => $error->column,
+            ];
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return $errors;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriter.php
new file mode 100644
index 0000000..0a349b8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriter.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Writer;
+
+use Symfony\Component\Translation\Dumper\DumperInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationWriter writes translation messages.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class TranslationWriter implements TranslationWriterInterface
+{
+    private $dumpers = [];
+
+    /**
+     * Adds a dumper to the writer.
+     */
+    public function addDumper(string $format, DumperInterface $dumper)
+    {
+        $this->dumpers[$format] = $dumper;
+    }
+
+    /**
+     * Obtains the list of supported formats.
+     *
+     * @return array
+     */
+    public function getFormats()
+    {
+        return array_keys($this->dumpers);
+    }
+
+    /**
+     * Writes translation from the catalogue according to the selected format.
+     *
+     * @param string $format  The format to use to dump the messages
+     * @param array  $options Options that are passed to the dumper
+     *
+     * @throws InvalidArgumentException
+     */
+    public function write(MessageCatalogue $catalogue, string $format, array $options = [])
+    {
+        if (!isset($this->dumpers[$format])) {
+            throw new InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format));
+        }
+
+        // get the right dumper
+        $dumper = $this->dumpers[$format];
+
+        if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) {
+            throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s".', $options['path']));
+        }
+
+        // save
+        $dumper->dump($catalogue, $options);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriterInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriterInterface.php
new file mode 100644
index 0000000..4321309
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriterInterface.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Writer;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationWriter writes translation messages.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface TranslationWriterInterface
+{
+    /**
+     * Writes translation from the catalogue according to the selected format.
+     *
+     * @param string $format  The format to use to dump the messages
+     * @param array  $options Options that are passed to the dumper
+     *
+     * @throws InvalidArgumentException
+     */
+    public function write(MessageCatalogue $catalogue, string $format, array $options = []);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/composer.json
new file mode 100644
index 0000000..de84e16
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/composer.json
@@ -0,0 +1,60 @@
+{
+    "name": "symfony/translation",
+    "type": "library",
+    "description": "Provides tools to internationalize your application",
+    "keywords": [],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.2.5",
+        "symfony/deprecation-contracts": "^2.1",
+        "symfony/polyfill-mbstring": "~1.0",
+        "symfony/polyfill-php80": "^1.16",
+        "symfony/translation-contracts": "^2.3"
+    },
+    "require-dev": {
+        "symfony/config": "^4.4|^5.0",
+        "symfony/console": "^4.4|^5.0",
+        "symfony/dependency-injection": "^5.0",
+        "symfony/http-kernel": "^5.0",
+        "symfony/intl": "^4.4|^5.0",
+        "symfony/polyfill-intl-icu": "^1.21",
+        "symfony/service-contracts": "^1.1.2|^2",
+        "symfony/yaml": "^4.4|^5.0",
+        "symfony/finder": "^4.4|^5.0",
+        "psr/log": "^1|^2|^3"
+    },
+    "conflict": {
+        "symfony/config": "<4.4",
+        "symfony/dependency-injection": "<5.0",
+        "symfony/http-kernel": "<5.0",
+        "symfony/twig-bundle": "<5.0",
+        "symfony/yaml": "<4.4"
+    },
+    "provide": {
+        "symfony/translation-implementation": "2.3"
+    },
+    "suggest": {
+        "symfony/config": "",
+        "symfony/yaml": "",
+        "psr/log-implementation": "To use logging capability in translator"
+    },
+    "autoload": {
+        "files": [ "Resources/functions.php" ],
+        "psr-4": { "Symfony\\Component\\Translation\\": "" },
+        "exclude-from-classmap": [
+            "/Tests/"
+        ]
+    },
+    "minimum-stability": "dev"
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/CHANGELOG.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/CHANGELOG.md
new file mode 100644
index 0000000..f3956e6
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/CHANGELOG.md
@@ -0,0 +1,65 @@
+CHANGELOG
+=========
+
+5.2.0
+-----
+
+ * added support for PHPUnit `--colors` option
+ * added `VAR_DUMPER_FORMAT=server` env var value support
+ * prevent replacing the handler when the `VAR_DUMPER_FORMAT` env var is set
+
+5.1.0
+-----
+
+ * added `RdKafka` support
+
+4.4.0
+-----
+
+ * added `VarDumperTestTrait::setUpVarDumper()` and `VarDumperTestTrait::tearDownVarDumper()`
+   to configure casters & flags to use in tests
+ * added `ImagineCaster` and infrastructure to dump images
+ * added the stamps of a message after it is dispatched in `TraceableMessageBus` and `MessengerDataCollector` collected data
+ * added `UuidCaster`
+ * made all casters final
+ * added support for the `NO_COLOR` env var (https://no-color.org/)
+
+4.3.0
+-----
+
+ * added `DsCaster` to support dumping the contents of data structures from the Ds extension
+
+4.2.0
+-----
+
+ * support selecting the format to use by setting the environment variable `VAR_DUMPER_FORMAT` to `html` or `cli`
+
+4.1.0
+-----
+
+ * added a `ServerDumper` to send serialized Data clones to a server
+ * added a `ServerDumpCommand` and `DumpServer` to run a server collecting
+   and displaying dumps on a single place with multiple formats support
+ * added `CliDescriptor` and `HtmlDescriptor` descriptors for `server:dump` CLI and HTML formats support
+
+4.0.0
+-----
+
+ * support for passing `\ReflectionClass` instances to the `Caster::castObject()`
+   method has been dropped, pass class names as strings instead
+ * the `Data::getRawData()` method has been removed
+ * the `VarDumperTestTrait::assertDumpEquals()` method expects a 3rd `$filter = 0`
+   argument and moves `$message = ''` argument at 4th position.
+ * the `VarDumperTestTrait::assertDumpMatchesFormat()` method expects a 3rd `$filter = 0`
+   argument and moves `$message = ''` argument at 4th position.
+
+3.4.0
+-----
+
+ * added `AbstractCloner::setMinDepth()` function to ensure minimum tree depth
+ * deprecated `MongoCaster`
+
+2.7.0
+-----
+
+ * deprecated `Cloner\Data::getLimitedClone()`. Use `withMaxDepth`, `withMaxItemsPerDepth` or `withRefHandles` instead.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/AmqpCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/AmqpCaster.php
new file mode 100644
index 0000000..dc3b621
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/AmqpCaster.php
@@ -0,0 +1,212 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Amqp related classes to array representation.
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ *
+ * @final
+ */
+class AmqpCaster
+{
+    private const FLAGS = [
+        \AMQP_DURABLE => 'AMQP_DURABLE',
+        \AMQP_PASSIVE => 'AMQP_PASSIVE',
+        \AMQP_EXCLUSIVE => 'AMQP_EXCLUSIVE',
+        \AMQP_AUTODELETE => 'AMQP_AUTODELETE',
+        \AMQP_INTERNAL => 'AMQP_INTERNAL',
+        \AMQP_NOLOCAL => 'AMQP_NOLOCAL',
+        \AMQP_AUTOACK => 'AMQP_AUTOACK',
+        \AMQP_IFEMPTY => 'AMQP_IFEMPTY',
+        \AMQP_IFUNUSED => 'AMQP_IFUNUSED',
+        \AMQP_MANDATORY => 'AMQP_MANDATORY',
+        \AMQP_IMMEDIATE => 'AMQP_IMMEDIATE',
+        \AMQP_MULTIPLE => 'AMQP_MULTIPLE',
+        \AMQP_NOWAIT => 'AMQP_NOWAIT',
+        \AMQP_REQUEUE => 'AMQP_REQUEUE',
+    ];
+
+    private const EXCHANGE_TYPES = [
+        \AMQP_EX_TYPE_DIRECT => 'AMQP_EX_TYPE_DIRECT',
+        \AMQP_EX_TYPE_FANOUT => 'AMQP_EX_TYPE_FANOUT',
+        \AMQP_EX_TYPE_TOPIC => 'AMQP_EX_TYPE_TOPIC',
+        \AMQP_EX_TYPE_HEADERS => 'AMQP_EX_TYPE_HEADERS',
+    ];
+
+    public static function castConnection(\AMQPConnection $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'is_connected' => $c->isConnected(),
+        ];
+
+        // Recent version of the extension already expose private properties
+        if (isset($a["\x00AMQPConnection\x00login"])) {
+            return $a;
+        }
+
+        // BC layer in the amqp lib
+        if (method_exists($c, 'getReadTimeout')) {
+            $timeout = $c->getReadTimeout();
+        } else {
+            $timeout = $c->getTimeout();
+        }
+
+        $a += [
+            $prefix.'is_connected' => $c->isConnected(),
+            $prefix.'login' => $c->getLogin(),
+            $prefix.'password' => $c->getPassword(),
+            $prefix.'host' => $c->getHost(),
+            $prefix.'vhost' => $c->getVhost(),
+            $prefix.'port' => $c->getPort(),
+            $prefix.'read_timeout' => $timeout,
+        ];
+
+        return $a;
+    }
+
+    public static function castChannel(\AMQPChannel $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'is_connected' => $c->isConnected(),
+            $prefix.'channel_id' => $c->getChannelId(),
+        ];
+
+        // Recent version of the extension already expose private properties
+        if (isset($a["\x00AMQPChannel\x00connection"])) {
+            return $a;
+        }
+
+        $a += [
+            $prefix.'connection' => $c->getConnection(),
+            $prefix.'prefetch_size' => $c->getPrefetchSize(),
+            $prefix.'prefetch_count' => $c->getPrefetchCount(),
+        ];
+
+        return $a;
+    }
+
+    public static function castQueue(\AMQPQueue $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'flags' => self::extractFlags($c->getFlags()),
+        ];
+
+        // Recent version of the extension already expose private properties
+        if (isset($a["\x00AMQPQueue\x00name"])) {
+            return $a;
+        }
+
+        $a += [
+            $prefix.'connection' => $c->getConnection(),
+            $prefix.'channel' => $c->getChannel(),
+            $prefix.'name' => $c->getName(),
+            $prefix.'arguments' => $c->getArguments(),
+        ];
+
+        return $a;
+    }
+
+    public static function castExchange(\AMQPExchange $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'flags' => self::extractFlags($c->getFlags()),
+        ];
+
+        $type = isset(self::EXCHANGE_TYPES[$c->getType()]) ? new ConstStub(self::EXCHANGE_TYPES[$c->getType()], $c->getType()) : $c->getType();
+
+        // Recent version of the extension already expose private properties
+        if (isset($a["\x00AMQPExchange\x00name"])) {
+            $a["\x00AMQPExchange\x00type"] = $type;
+
+            return $a;
+        }
+
+        $a += [
+            $prefix.'connection' => $c->getConnection(),
+            $prefix.'channel' => $c->getChannel(),
+            $prefix.'name' => $c->getName(),
+            $prefix.'type' => $type,
+            $prefix.'arguments' => $c->getArguments(),
+        ];
+
+        return $a;
+    }
+
+    public static function castEnvelope(\AMQPEnvelope $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $deliveryMode = new ConstStub($c->getDeliveryMode().(2 === $c->getDeliveryMode() ? ' (persistent)' : ' (non-persistent)'), $c->getDeliveryMode());
+
+        // Recent version of the extension already expose private properties
+        if (isset($a["\x00AMQPEnvelope\x00body"])) {
+            $a["\0AMQPEnvelope\0delivery_mode"] = $deliveryMode;
+
+            return $a;
+        }
+
+        if (!($filter & Caster::EXCLUDE_VERBOSE)) {
+            $a += [$prefix.'body' => $c->getBody()];
+        }
+
+        $a += [
+            $prefix.'delivery_tag' => $c->getDeliveryTag(),
+            $prefix.'is_redelivery' => $c->isRedelivery(),
+            $prefix.'exchange_name' => $c->getExchangeName(),
+            $prefix.'routing_key' => $c->getRoutingKey(),
+            $prefix.'content_type' => $c->getContentType(),
+            $prefix.'content_encoding' => $c->getContentEncoding(),
+            $prefix.'headers' => $c->getHeaders(),
+            $prefix.'delivery_mode' => $deliveryMode,
+            $prefix.'priority' => $c->getPriority(),
+            $prefix.'correlation_id' => $c->getCorrelationId(),
+            $prefix.'reply_to' => $c->getReplyTo(),
+            $prefix.'expiration' => $c->getExpiration(),
+            $prefix.'message_id' => $c->getMessageId(),
+            $prefix.'timestamp' => $c->getTimeStamp(),
+            $prefix.'type' => $c->getType(),
+            $prefix.'user_id' => $c->getUserId(),
+            $prefix.'app_id' => $c->getAppId(),
+        ];
+
+        return $a;
+    }
+
+    private static function extractFlags(int $flags): ConstStub
+    {
+        $flagsArray = [];
+
+        foreach (self::FLAGS as $value => $name) {
+            if ($flags & $value) {
+                $flagsArray[] = $name;
+            }
+        }
+
+        if (!$flagsArray) {
+            $flagsArray = ['AMQP_NOPARAM'];
+        }
+
+        return new ConstStub(implode('|', $flagsArray), $flags);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ArgsStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ArgsStub.php
new file mode 100644
index 0000000..f8b485b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ArgsStub.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents a list of function arguments.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ArgsStub extends EnumStub
+{
+    private static $parameters = [];
+
+    public function __construct(array $args, string $function, ?string $class)
+    {
+        [$variadic, $params] = self::getParameters($function, $class);
+
+        $values = [];
+        foreach ($args as $k => $v) {
+            $values[$k] = !is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v;
+        }
+        if (null === $params) {
+            parent::__construct($values, false);
+
+            return;
+        }
+        if (\count($values) < \count($params)) {
+            $params = \array_slice($params, 0, \count($values));
+        } elseif (\count($values) > \count($params)) {
+            $values[] = new EnumStub(array_splice($values, \count($params)), false);
+            $params[] = $variadic;
+        }
+        if (['...'] === $params) {
+            $this->dumpKeys = false;
+            $this->value = $values[0]->value;
+        } else {
+            $this->value = array_combine($params, $values);
+        }
+    }
+
+    private static function getParameters(string $function, ?string $class): array
+    {
+        if (isset(self::$parameters[$k = $class.'::'.$function])) {
+            return self::$parameters[$k];
+        }
+
+        try {
+            $r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function);
+        } catch (\ReflectionException $e) {
+            return [null, null];
+        }
+
+        $variadic = '...';
+        $params = [];
+        foreach ($r->getParameters() as $v) {
+            $k = '$'.$v->name;
+            if ($v->isPassedByReference()) {
+                $k = '&'.$k;
+            }
+            if ($v->isVariadic()) {
+                $variadic .= $k;
+            } else {
+                $params[] = $k;
+            }
+        }
+
+        return self::$parameters[$k] = [$variadic, $params];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/Caster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/Caster.php
new file mode 100644
index 0000000..612b21f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/Caster.php
@@ -0,0 +1,174 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Helper for filtering out properties in casters.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class Caster
+{
+    public const EXCLUDE_VERBOSE = 1;
+    public const EXCLUDE_VIRTUAL = 2;
+    public const EXCLUDE_DYNAMIC = 4;
+    public const EXCLUDE_PUBLIC = 8;
+    public const EXCLUDE_PROTECTED = 16;
+    public const EXCLUDE_PRIVATE = 32;
+    public const EXCLUDE_NULL = 64;
+    public const EXCLUDE_EMPTY = 128;
+    public const EXCLUDE_NOT_IMPORTANT = 256;
+    public const EXCLUDE_STRICT = 512;
+
+    public const PREFIX_VIRTUAL = "\0~\0";
+    public const PREFIX_DYNAMIC = "\0+\0";
+    public const PREFIX_PROTECTED = "\0*\0";
+
+    /**
+     * Casts objects to arrays and adds the dynamic property prefix.
+     *
+     * @param bool $hasDebugInfo Whether the __debugInfo method exists on $obj or not
+     *
+     * @return array The array-cast of the object, with prefixed dynamic properties
+     */
+    public static function castObject(object $obj, string $class, bool $hasDebugInfo = false, string $debugClass = null): array
+    {
+        if ($hasDebugInfo) {
+            try {
+                $debugInfo = $obj->__debugInfo();
+            } catch (\Exception $e) {
+                // ignore failing __debugInfo()
+                $hasDebugInfo = false;
+            }
+        }
+
+        $a = $obj instanceof \Closure ? [] : (array) $obj;
+
+        if ($obj instanceof \__PHP_Incomplete_Class) {
+            return $a;
+        }
+
+        if ($a) {
+            static $publicProperties = [];
+            $debugClass = $debugClass ?? get_debug_type($obj);
+
+            $i = 0;
+            $prefixedKeys = [];
+            foreach ($a as $k => $v) {
+                if ("\0" !== ($k[0] ?? '')) {
+                    if (!isset($publicProperties[$class])) {
+                        foreach ((new \ReflectionClass($class))->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
+                            $publicProperties[$class][$prop->name] = true;
+                        }
+                    }
+                    if (!isset($publicProperties[$class][$k])) {
+                        $prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k;
+                    }
+                } elseif ($debugClass !== $class && 1 === strpos($k, $class)) {
+                    $prefixedKeys[$i] = "\0".$debugClass.strrchr($k, "\0");
+                }
+                ++$i;
+            }
+            if ($prefixedKeys) {
+                $keys = array_keys($a);
+                foreach ($prefixedKeys as $i => $k) {
+                    $keys[$i] = $k;
+                }
+                $a = array_combine($keys, $a);
+            }
+        }
+
+        if ($hasDebugInfo && \is_array($debugInfo)) {
+            foreach ($debugInfo as $k => $v) {
+                if (!isset($k[0]) || "\0" !== $k[0]) {
+                    if (\array_key_exists(self::PREFIX_DYNAMIC.$k, $a)) {
+                        continue;
+                    }
+                    $k = self::PREFIX_VIRTUAL.$k;
+                }
+
+                unset($a[$k]);
+                $a[$k] = $v;
+            }
+        }
+
+        return $a;
+    }
+
+    /**
+     * Filters out the specified properties.
+     *
+     * By default, a single match in the $filter bit field filters properties out, following an "or" logic.
+     * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed.
+     *
+     * @param array    $a                The array containing the properties to filter
+     * @param int      $filter           A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out
+     * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set
+     * @param int      &$count           Set to the number of removed properties
+     *
+     * @return array The filtered array
+     */
+    public static function filter(array $a, int $filter, array $listedProperties = [], ?int &$count = 0): array
+    {
+        $count = 0;
+
+        foreach ($a as $k => $v) {
+            $type = self::EXCLUDE_STRICT & $filter;
+
+            if (null === $v) {
+                $type |= self::EXCLUDE_NULL & $filter;
+                $type |= self::EXCLUDE_EMPTY & $filter;
+            } elseif (false === $v || '' === $v || '0' === $v || 0 === $v || 0.0 === $v || [] === $v) {
+                $type |= self::EXCLUDE_EMPTY & $filter;
+            }
+            if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !\in_array($k, $listedProperties, true)) {
+                $type |= self::EXCLUDE_NOT_IMPORTANT;
+            }
+            if ((self::EXCLUDE_VERBOSE & $filter) && \in_array($k, $listedProperties, true)) {
+                $type |= self::EXCLUDE_VERBOSE;
+            }
+
+            if (!isset($k[1]) || "\0" !== $k[0]) {
+                $type |= self::EXCLUDE_PUBLIC & $filter;
+            } elseif ('~' === $k[1]) {
+                $type |= self::EXCLUDE_VIRTUAL & $filter;
+            } elseif ('+' === $k[1]) {
+                $type |= self::EXCLUDE_DYNAMIC & $filter;
+            } elseif ('*' === $k[1]) {
+                $type |= self::EXCLUDE_PROTECTED & $filter;
+            } else {
+                $type |= self::EXCLUDE_PRIVATE & $filter;
+            }
+
+            if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) {
+                unset($a[$k]);
+                ++$count;
+            }
+        }
+
+        return $a;
+    }
+
+    public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, bool $isNested): array
+    {
+        if (isset($a['__PHP_Incomplete_Class_Name'])) {
+            $stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')';
+            unset($a['__PHP_Incomplete_Class_Name']);
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ClassStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ClassStub.php
new file mode 100644
index 0000000..48f8483
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ClassStub.php
@@ -0,0 +1,106 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents a PHP class identifier.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ClassStub extends ConstStub
+{
+    /**
+     * @param string   $identifier A PHP identifier, e.g. a class, method, interface, etc. name
+     * @param callable $callable   The callable targeted by the identifier when it is ambiguous or not a real PHP identifier
+     */
+    public function __construct(string $identifier, $callable = null)
+    {
+        $this->value = $identifier;
+
+        try {
+            if (null !== $callable) {
+                if ($callable instanceof \Closure) {
+                    $r = new \ReflectionFunction($callable);
+                } elseif (\is_object($callable)) {
+                    $r = [$callable, '__invoke'];
+                } elseif (\is_array($callable)) {
+                    $r = $callable;
+                } elseif (false !== $i = strpos($callable, '::')) {
+                    $r = [substr($callable, 0, $i), substr($callable, 2 + $i)];
+                } else {
+                    $r = new \ReflectionFunction($callable);
+                }
+            } elseif (0 < $i = strpos($identifier, '::') ?: strpos($identifier, '->')) {
+                $r = [substr($identifier, 0, $i), substr($identifier, 2 + $i)];
+            } else {
+                $r = new \ReflectionClass($identifier);
+            }
+
+            if (\is_array($r)) {
+                try {
+                    $r = new \ReflectionMethod($r[0], $r[1]);
+                } catch (\ReflectionException $e) {
+                    $r = new \ReflectionClass($r[0]);
+                }
+            }
+
+            if (str_contains($identifier, "@anonymous\0")) {
+                $this->value = $identifier = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
+                    return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
+                }, $identifier);
+            }
+
+            if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) {
+                $s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true, Caster::EXCLUDE_VERBOSE);
+                $s = ReflectionCaster::getSignature($s);
+
+                if (str_ends_with($identifier, '()')) {
+                    $this->value = substr_replace($identifier, $s, -2);
+                } else {
+                    $this->value .= $s;
+                }
+            }
+        } catch (\ReflectionException $e) {
+            return;
+        } finally {
+            if (0 < $i = strrpos($this->value, '\\')) {
+                $this->attr['ellipsis'] = \strlen($this->value) - $i;
+                $this->attr['ellipsis-type'] = 'class';
+                $this->attr['ellipsis-tail'] = 1;
+            }
+        }
+
+        if ($f = $r->getFileName()) {
+            $this->attr['file'] = $f;
+            $this->attr['line'] = $r->getStartLine();
+        }
+    }
+
+    public static function wrapCallable($callable)
+    {
+        if (\is_object($callable) || !\is_callable($callable)) {
+            return $callable;
+        }
+
+        if (!\is_array($callable)) {
+            $callable = new static($callable, $callable);
+        } elseif (\is_string($callable[0])) {
+            $callable[0] = new static($callable[0], $callable);
+        } else {
+            $callable[1] = new static($callable[1], $callable);
+        }
+
+        return $callable;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ConstStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ConstStub.php
new file mode 100644
index 0000000..8b01797
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ConstStub.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents a PHP constant and its value.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ConstStub extends Stub
+{
+    public function __construct(string $name, $value = null)
+    {
+        $this->class = $name;
+        $this->value = 1 < \func_num_args() ? $value : $name;
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return (string) $this->value;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutArrayStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutArrayStub.php
new file mode 100644
index 0000000..0e4fb36
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutArrayStub.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+/**
+ * Represents a cut array.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class CutArrayStub extends CutStub
+{
+    public $preservedSubset;
+
+    public function __construct(array $value, array $preservedKeys)
+    {
+        parent::__construct($value);
+
+        $this->preservedSubset = array_intersect_key($value, array_flip($preservedKeys));
+        $this->cut -= \count($this->preservedSubset);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutStub.php
new file mode 100644
index 0000000..464c6db
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutStub.php
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents the main properties of a PHP variable, pre-casted by a caster.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class CutStub extends Stub
+{
+    public function __construct($value)
+    {
+        $this->value = $value;
+
+        switch (\gettype($value)) {
+            case 'object':
+                $this->type = self::TYPE_OBJECT;
+                $this->class = \get_class($value);
+
+                if ($value instanceof \Closure) {
+                    ReflectionCaster::castClosure($value, [], $this, true, Caster::EXCLUDE_VERBOSE);
+                }
+
+                $this->cut = -1;
+                break;
+
+            case 'array':
+                $this->type = self::TYPE_ARRAY;
+                $this->class = self::ARRAY_ASSOC;
+                $this->cut = $this->value = \count($value);
+                break;
+
+            case 'resource':
+            case 'unknown type':
+            case 'resource (closed)':
+                $this->type = self::TYPE_RESOURCE;
+                $this->handle = (int) $value;
+                if ('Unknown' === $this->class = @get_resource_type($value)) {
+                    $this->class = 'Closed';
+                }
+                $this->cut = -1;
+                break;
+
+            case 'string':
+                $this->type = self::TYPE_STRING;
+                $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY;
+                $this->cut = self::STRING_BINARY === $this->class ? \strlen($value) : mb_strlen($value, 'UTF-8');
+                $this->value = '';
+                break;
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DOMCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DOMCaster.php
new file mode 100644
index 0000000..4dd16e0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DOMCaster.php
@@ -0,0 +1,304 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts DOM related classes to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class DOMCaster
+{
+    private const ERROR_CODES = [
+        \DOM_PHP_ERR => 'DOM_PHP_ERR',
+        \DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR',
+        \DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR',
+        \DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR',
+        \DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR',
+        \DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR',
+        \DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR',
+        \DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR',
+        \DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR',
+        \DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR',
+        \DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR',
+        \DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR',
+        \DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR',
+        \DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR',
+        \DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR',
+        \DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR',
+        \DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR',
+    ];
+
+    private const NODE_TYPES = [
+        \XML_ELEMENT_NODE => 'XML_ELEMENT_NODE',
+        \XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE',
+        \XML_TEXT_NODE => 'XML_TEXT_NODE',
+        \XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE',
+        \XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE',
+        \XML_ENTITY_NODE => 'XML_ENTITY_NODE',
+        \XML_PI_NODE => 'XML_PI_NODE',
+        \XML_COMMENT_NODE => 'XML_COMMENT_NODE',
+        \XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE',
+        \XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE',
+        \XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE',
+        \XML_NOTATION_NODE => 'XML_NOTATION_NODE',
+        \XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE',
+        \XML_DTD_NODE => 'XML_DTD_NODE',
+        \XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE',
+        \XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE',
+        \XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE',
+        \XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE',
+    ];
+
+    public static function castException(\DOMException $e, array $a, Stub $stub, bool $isNested)
+    {
+        $k = Caster::PREFIX_PROTECTED.'code';
+        if (isset($a[$k], self::ERROR_CODES[$a[$k]])) {
+            $a[$k] = new ConstStub(self::ERROR_CODES[$a[$k]], $a[$k]);
+        }
+
+        return $a;
+    }
+
+    public static function castLength($dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'length' => $dom->length,
+        ];
+
+        return $a;
+    }
+
+    public static function castImplementation(\DOMImplementation $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'Core' => '1.0',
+            Caster::PREFIX_VIRTUAL.'XML' => '2.0',
+        ];
+
+        return $a;
+    }
+
+    public static function castNode(\DOMNode $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'nodeName' => $dom->nodeName,
+            'nodeValue' => new CutStub($dom->nodeValue),
+            'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType),
+            'parentNode' => new CutStub($dom->parentNode),
+            'childNodes' => $dom->childNodes,
+            'firstChild' => new CutStub($dom->firstChild),
+            'lastChild' => new CutStub($dom->lastChild),
+            'previousSibling' => new CutStub($dom->previousSibling),
+            'nextSibling' => new CutStub($dom->nextSibling),
+            'attributes' => $dom->attributes,
+            'ownerDocument' => new CutStub($dom->ownerDocument),
+            'namespaceURI' => $dom->namespaceURI,
+            'prefix' => $dom->prefix,
+            'localName' => $dom->localName,
+            'baseURI' => $dom->baseURI ? new LinkStub($dom->baseURI) : $dom->baseURI,
+            'textContent' => new CutStub($dom->textContent),
+        ];
+
+        return $a;
+    }
+
+    public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'nodeName' => $dom->nodeName,
+            'nodeValue' => new CutStub($dom->nodeValue),
+            'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType),
+            'prefix' => $dom->prefix,
+            'localName' => $dom->localName,
+            'namespaceURI' => $dom->namespaceURI,
+            'ownerDocument' => new CutStub($dom->ownerDocument),
+            'parentNode' => new CutStub($dom->parentNode),
+        ];
+
+        return $a;
+    }
+
+    public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $a += [
+            'doctype' => $dom->doctype,
+            'implementation' => $dom->implementation,
+            'documentElement' => new CutStub($dom->documentElement),
+            'actualEncoding' => $dom->actualEncoding,
+            'encoding' => $dom->encoding,
+            'xmlEncoding' => $dom->xmlEncoding,
+            'standalone' => $dom->standalone,
+            'xmlStandalone' => $dom->xmlStandalone,
+            'version' => $dom->version,
+            'xmlVersion' => $dom->xmlVersion,
+            'strictErrorChecking' => $dom->strictErrorChecking,
+            'documentURI' => $dom->documentURI ? new LinkStub($dom->documentURI) : $dom->documentURI,
+            'config' => $dom->config,
+            'formatOutput' => $dom->formatOutput,
+            'validateOnParse' => $dom->validateOnParse,
+            'resolveExternals' => $dom->resolveExternals,
+            'preserveWhiteSpace' => $dom->preserveWhiteSpace,
+            'recover' => $dom->recover,
+            'substituteEntities' => $dom->substituteEntities,
+        ];
+
+        if (!($filter & Caster::EXCLUDE_VERBOSE)) {
+            $formatOutput = $dom->formatOutput;
+            $dom->formatOutput = true;
+            $a += [Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()];
+            $dom->formatOutput = $formatOutput;
+        }
+
+        return $a;
+    }
+
+    public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'data' => $dom->data,
+            'length' => $dom->length,
+        ];
+
+        return $a;
+    }
+
+    public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'name' => $dom->name,
+            'specified' => $dom->specified,
+            'value' => $dom->value,
+            'ownerElement' => $dom->ownerElement,
+            'schemaTypeInfo' => $dom->schemaTypeInfo,
+        ];
+
+        return $a;
+    }
+
+    public static function castElement(\DOMElement $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'tagName' => $dom->tagName,
+            'schemaTypeInfo' => $dom->schemaTypeInfo,
+        ];
+
+        return $a;
+    }
+
+    public static function castText(\DOMText $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'wholeText' => $dom->wholeText,
+        ];
+
+        return $a;
+    }
+
+    public static function castTypeinfo(\DOMTypeinfo $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'typeName' => $dom->typeName,
+            'typeNamespace' => $dom->typeNamespace,
+        ];
+
+        return $a;
+    }
+
+    public static function castDomError(\DOMDomError $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'severity' => $dom->severity,
+            'message' => $dom->message,
+            'type' => $dom->type,
+            'relatedException' => $dom->relatedException,
+            'related_data' => $dom->related_data,
+            'location' => $dom->location,
+        ];
+
+        return $a;
+    }
+
+    public static function castLocator(\DOMLocator $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'lineNumber' => $dom->lineNumber,
+            'columnNumber' => $dom->columnNumber,
+            'offset' => $dom->offset,
+            'relatedNode' => $dom->relatedNode,
+            'uri' => $dom->uri ? new LinkStub($dom->uri, $dom->lineNumber) : $dom->uri,
+        ];
+
+        return $a;
+    }
+
+    public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'name' => $dom->name,
+            'entities' => $dom->entities,
+            'notations' => $dom->notations,
+            'publicId' => $dom->publicId,
+            'systemId' => $dom->systemId,
+            'internalSubset' => $dom->internalSubset,
+        ];
+
+        return $a;
+    }
+
+    public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'publicId' => $dom->publicId,
+            'systemId' => $dom->systemId,
+        ];
+
+        return $a;
+    }
+
+    public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'publicId' => $dom->publicId,
+            'systemId' => $dom->systemId,
+            'notationName' => $dom->notationName,
+            'actualEncoding' => $dom->actualEncoding,
+            'encoding' => $dom->encoding,
+            'version' => $dom->version,
+        ];
+
+        return $a;
+    }
+
+    public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'target' => $dom->target,
+            'data' => $dom->data,
+        ];
+
+        return $a;
+    }
+
+    public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            'document' => $dom->document,
+        ];
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DateCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DateCaster.php
new file mode 100644
index 0000000..1f61c32
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DateCaster.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts DateTimeInterface related classes to array representation.
+ *
+ * @author Dany Maillard <danymaillard93b@gmail.com>
+ *
+ * @final
+ */
+class DateCaster
+{
+    private const PERIOD_LIMIT = 3;
+
+    public static function castDateTime(\DateTimeInterface $d, array $a, Stub $stub, bool $isNested, int $filter)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $location = $d->getTimezone()->getLocation();
+        $fromNow = (new \DateTime())->diff($d);
+
+        $title = $d->format('l, F j, Y')
+            ."\n".self::formatInterval($fromNow).' from now'
+            .($location ? ($d->format('I') ? "\nDST On" : "\nDST Off") : '')
+        ;
+
+        unset(
+            $a[Caster::PREFIX_DYNAMIC.'date'],
+            $a[Caster::PREFIX_DYNAMIC.'timezone'],
+            $a[Caster::PREFIX_DYNAMIC.'timezone_type']
+        );
+        $a[$prefix.'date'] = new ConstStub(self::formatDateTime($d, $location ? ' e (P)' : ' P'), $title);
+
+        $stub->class .= $d->format(' @U');
+
+        return $a;
+    }
+
+    public static function castInterval(\DateInterval $interval, array $a, Stub $stub, bool $isNested, int $filter)
+    {
+        $now = new \DateTimeImmutable();
+        $numberOfSeconds = $now->add($interval)->getTimestamp() - $now->getTimestamp();
+        $title = number_format($numberOfSeconds, 0, '.', ' ').'s';
+
+        $i = [Caster::PREFIX_VIRTUAL.'interval' => new ConstStub(self::formatInterval($interval), $title)];
+
+        return $filter & Caster::EXCLUDE_VERBOSE ? $i : $i + $a;
+    }
+
+    private static function formatInterval(\DateInterval $i): string
+    {
+        $format = '%R ';
+
+        if (0 === $i->y && 0 === $i->m && ($i->h >= 24 || $i->i >= 60 || $i->s >= 60)) {
+            $i = date_diff($d = new \DateTime(), date_add(clone $d, $i)); // recalculate carry over points
+            $format .= 0 < $i->days ? '%ad ' : '';
+        } else {
+            $format .= ($i->y ? '%yy ' : '').($i->m ? '%mm ' : '').($i->d ? '%dd ' : '');
+        }
+
+        $format .= $i->h || $i->i || $i->s || $i->f ? '%H:%I:'.self::formatSeconds($i->s, substr($i->f, 2)) : '';
+        $format = '%R ' === $format ? '0s' : $format;
+
+        return $i->format(rtrim($format));
+    }
+
+    public static function castTimeZone(\DateTimeZone $timeZone, array $a, Stub $stub, bool $isNested, int $filter)
+    {
+        $location = $timeZone->getLocation();
+        $formatted = (new \DateTime('now', $timeZone))->format($location ? 'e (P)' : 'P');
+        $title = $location && \extension_loaded('intl') ? \Locale::getDisplayRegion('-'.$location['country_code']) : '';
+
+        $z = [Caster::PREFIX_VIRTUAL.'timezone' => new ConstStub($formatted, $title)];
+
+        return $filter & Caster::EXCLUDE_VERBOSE ? $z : $z + $a;
+    }
+
+    public static function castPeriod(\DatePeriod $p, array $a, Stub $stub, bool $isNested, int $filter)
+    {
+        $dates = [];
+        foreach (clone $p as $i => $d) {
+            if (self::PERIOD_LIMIT === $i) {
+                $now = new \DateTimeImmutable('now', new \DateTimeZone('UTC'));
+                $dates[] = sprintf('%s more', ($end = $p->getEndDate())
+                    ? ceil(($end->format('U.u') - $d->format('U.u')) / ((int) $now->add($p->getDateInterval())->format('U.u') - (int) $now->format('U.u')))
+                    : $p->recurrences - $i
+                );
+                break;
+            }
+            $dates[] = sprintf('%s) %s', $i + 1, self::formatDateTime($d));
+        }
+
+        $period = sprintf(
+            'every %s, from %s (%s) %s',
+            self::formatInterval($p->getDateInterval()),
+            self::formatDateTime($p->getStartDate()),
+            $p->include_start_date ? 'included' : 'excluded',
+            ($end = $p->getEndDate()) ? 'to '.self::formatDateTime($end) : 'recurring '.$p->recurrences.' time/s'
+        );
+
+        $p = [Caster::PREFIX_VIRTUAL.'period' => new ConstStub($period, implode("\n", $dates))];
+
+        return $filter & Caster::EXCLUDE_VERBOSE ? $p : $p + $a;
+    }
+
+    private static function formatDateTime(\DateTimeInterface $d, string $extra = ''): string
+    {
+        return $d->format('Y-m-d H:i:'.self::formatSeconds($d->format('s'), $d->format('u')).$extra);
+    }
+
+    private static function formatSeconds(string $s, string $us): string
+    {
+        return sprintf('%02d.%s', $s, 0 === ($len = \strlen($t = rtrim($us, '0'))) ? '0' : ($len <= 3 ? str_pad($t, 3, '0') : $us));
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DoctrineCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DoctrineCaster.php
new file mode 100644
index 0000000..129b2cb
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DoctrineCaster.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Doctrine\Common\Proxy\Proxy as CommonProxy;
+use Doctrine\ORM\PersistentCollection;
+use Doctrine\ORM\Proxy\Proxy as OrmProxy;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Doctrine related classes to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class DoctrineCaster
+{
+    public static function castCommonProxy(CommonProxy $proxy, array $a, Stub $stub, bool $isNested)
+    {
+        foreach (['__cloner__', '__initializer__'] as $k) {
+            if (\array_key_exists($k, $a)) {
+                unset($a[$k]);
+                ++$stub->cut;
+            }
+        }
+
+        return $a;
+    }
+
+    public static function castOrmProxy(OrmProxy $proxy, array $a, Stub $stub, bool $isNested)
+    {
+        foreach (['_entityPersister', '_identifier'] as $k) {
+            if (\array_key_exists($k = "\0Doctrine\\ORM\\Proxy\\Proxy\0".$k, $a)) {
+                unset($a[$k]);
+                ++$stub->cut;
+            }
+        }
+
+        return $a;
+    }
+
+    public static function castPersistentCollection(PersistentCollection $coll, array $a, Stub $stub, bool $isNested)
+    {
+        foreach (['snapshot', 'association', 'typeClass'] as $k) {
+            if (\array_key_exists($k = "\0Doctrine\\ORM\\PersistentCollection\0".$k, $a)) {
+                $a[$k] = new CutStub($a[$k]);
+            }
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsCaster.php
new file mode 100644
index 0000000..b34b670
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsCaster.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Ds\Collection;
+use Ds\Map;
+use Ds\Pair;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Ds extension classes to array representation.
+ *
+ * @author Jáchym Toušek <enumag@gmail.com>
+ *
+ * @final
+ */
+class DsCaster
+{
+    public static function castCollection(Collection $c, array $a, Stub $stub, bool $isNested): array
+    {
+        $a[Caster::PREFIX_VIRTUAL.'count'] = $c->count();
+        $a[Caster::PREFIX_VIRTUAL.'capacity'] = $c->capacity();
+
+        if (!$c instanceof Map) {
+            $a += $c->toArray();
+        }
+
+        return $a;
+    }
+
+    public static function castMap(Map $c, array $a, Stub $stub, bool $isNested): array
+    {
+        foreach ($c as $k => $v) {
+            $a[] = new DsPairStub($k, $v);
+        }
+
+        return $a;
+    }
+
+    public static function castPair(Pair $c, array $a, Stub $stub, bool $isNested): array
+    {
+        foreach ($c->toArray() as $k => $v) {
+            $a[Caster::PREFIX_VIRTUAL.$k] = $v;
+        }
+
+        return $a;
+    }
+
+    public static function castPairStub(DsPairStub $c, array $a, Stub $stub, bool $isNested): array
+    {
+        if ($isNested) {
+            $stub->class = Pair::class;
+            $stub->value = null;
+            $stub->handle = 0;
+
+            $a = $c->value;
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsPairStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsPairStub.php
new file mode 100644
index 0000000..a1dcc15
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsPairStub.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class DsPairStub extends Stub
+{
+    public function __construct($key, $value)
+    {
+        $this->value = [
+            Caster::PREFIX_VIRTUAL.'key' => $key,
+            Caster::PREFIX_VIRTUAL.'value' => $value,
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/EnumStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/EnumStub.php
new file mode 100644
index 0000000..7a4e98a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/EnumStub.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents an enumeration of values.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class EnumStub extends Stub
+{
+    public $dumpKeys = true;
+
+    public function __construct(array $values, bool $dumpKeys = true)
+    {
+        $this->value = $values;
+        $this->dumpKeys = $dumpKeys;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ExceptionCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ExceptionCaster.php
new file mode 100644
index 0000000..baa7a18
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ExceptionCaster.php
@@ -0,0 +1,382 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext;
+use Symfony\Component\VarDumper\Cloner\Stub;
+use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
+
+/**
+ * Casts common Exception classes to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class ExceptionCaster
+{
+    public static $srcContext = 1;
+    public static $traceArgs = true;
+    public static $errorTypes = [
+        \E_DEPRECATED => 'E_DEPRECATED',
+        \E_USER_DEPRECATED => 'E_USER_DEPRECATED',
+        \E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
+        \E_ERROR => 'E_ERROR',
+        \E_WARNING => 'E_WARNING',
+        \E_PARSE => 'E_PARSE',
+        \E_NOTICE => 'E_NOTICE',
+        \E_CORE_ERROR => 'E_CORE_ERROR',
+        \E_CORE_WARNING => 'E_CORE_WARNING',
+        \E_COMPILE_ERROR => 'E_COMPILE_ERROR',
+        \E_COMPILE_WARNING => 'E_COMPILE_WARNING',
+        \E_USER_ERROR => 'E_USER_ERROR',
+        \E_USER_WARNING => 'E_USER_WARNING',
+        \E_USER_NOTICE => 'E_USER_NOTICE',
+        \E_STRICT => 'E_STRICT',
+    ];
+
+    private static $framesCache = [];
+
+    public static function castError(\Error $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter);
+    }
+
+    public static function castException(\Exception $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter);
+    }
+
+    public static function castErrorException(\ErrorException $e, array $a, Stub $stub, bool $isNested)
+    {
+        if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) {
+            $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
+        }
+
+        return $a;
+    }
+
+    public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, bool $isNested)
+    {
+        $trace = Caster::PREFIX_VIRTUAL.'trace';
+        $prefix = Caster::PREFIX_PROTECTED;
+        $xPrefix = "\0Exception\0";
+
+        if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) {
+            $b = (array) $a[$xPrefix.'previous'];
+            $class = get_debug_type($a[$xPrefix.'previous']);
+            self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']);
+            $a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value));
+        }
+
+        unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
+
+        return $a;
+    }
+
+    public static function castSilencedErrorContext(SilencedErrorContext $e, array $a, Stub $stub, bool $isNested)
+    {
+        $sPrefix = "\0".SilencedErrorContext::class."\0";
+
+        if (!isset($a[$s = $sPrefix.'severity'])) {
+            return $a;
+        }
+
+        if (isset(self::$errorTypes[$a[$s]])) {
+            $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
+        }
+
+        $trace = [[
+            'file' => $a[$sPrefix.'file'],
+            'line' => $a[$sPrefix.'line'],
+        ]];
+
+        if (isset($a[$sPrefix.'trace'])) {
+            $trace = array_merge($trace, $a[$sPrefix.'trace']);
+        }
+
+        unset($a[$sPrefix.'file'], $a[$sPrefix.'line'], $a[$sPrefix.'trace']);
+        $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);
+
+        return $a;
+    }
+
+    public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, bool $isNested)
+    {
+        if (!$isNested) {
+            return $a;
+        }
+        $stub->class = '';
+        $stub->handle = 0;
+        $frames = $trace->value;
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a = [];
+        $j = \count($frames);
+        if (0 > $i = $trace->sliceOffset) {
+            $i = max(0, $j + $i);
+        }
+        if (!isset($trace->value[$i])) {
+            return [];
+        }
+        $lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
+        $frames[] = ['function' => ''];
+        $collapse = false;
+
+        for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
+            $f = $frames[$i];
+            $call = isset($f['function']) ? (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'] : '???';
+
+            $frame = new FrameStub(
+                [
+                    'object' => $f['object'] ?? null,
+                    'class' => $f['class'] ?? null,
+                    'type' => $f['type'] ?? null,
+                    'function' => $f['function'] ?? null,
+                ] + $frames[$i - 1],
+                false,
+                true
+            );
+            $f = self::castFrameStub($frame, [], $frame, true);
+            if (isset($f[$prefix.'src'])) {
+                foreach ($f[$prefix.'src']->value as $label => $frame) {
+                    if (str_starts_with($label, "\0~collapse=0")) {
+                        if ($collapse) {
+                            $label = substr_replace($label, '1', 11, 1);
+                        } else {
+                            $collapse = true;
+                        }
+                    }
+                    $label = substr_replace($label, "title=Stack level $j.&", 2, 0);
+                }
+                $f = $frames[$i - 1];
+                if ($trace->keepArgs && !empty($f['args']) && $frame instanceof EnumStub) {
+                    $frame->value['arguments'] = new ArgsStub($f['args'], $f['function'] ?? null, $f['class'] ?? null);
+                }
+            } elseif ('???' !== $lastCall) {
+                $label = new ClassStub($lastCall);
+                if (isset($label->attr['ellipsis'])) {
+                    $label->attr['ellipsis'] += 2;
+                    $label = substr_replace($prefix, "ellipsis-type=class&ellipsis={$label->attr['ellipsis']}&ellipsis-tail=1&title=Stack level $j.", 2, 0).$label->value.'()';
+                } else {
+                    $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$label->value.'()';
+                }
+            } else {
+                $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall;
+            }
+            $a[substr_replace($label, sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame;
+
+            $lastCall = $call;
+        }
+        if (null !== $trace->sliceLength) {
+            $a = \array_slice($a, 0, $trace->sliceLength, true);
+        }
+
+        return $a;
+    }
+
+    public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, bool $isNested)
+    {
+        if (!$isNested) {
+            return $a;
+        }
+        $f = $frame->value;
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        if (isset($f['file'], $f['line'])) {
+            $cacheKey = $f;
+            unset($cacheKey['object'], $cacheKey['args']);
+            $cacheKey[] = self::$srcContext;
+            $cacheKey = implode('-', $cacheKey);
+
+            if (isset(self::$framesCache[$cacheKey])) {
+                $a[$prefix.'src'] = self::$framesCache[$cacheKey];
+            } else {
+                if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) {
+                    $f['file'] = substr($f['file'], 0, -\strlen($match[0]));
+                    $f['line'] = (int) $match[1];
+                }
+                $src = $f['line'];
+                $srcKey = $f['file'];
+                $ellipsis = new LinkStub($srcKey, 0);
+                $srcAttr = 'collapse='.(int) $ellipsis->inVendor;
+                $ellipsisTail = $ellipsis->attr['ellipsis-tail'] ?? 0;
+                $ellipsis = $ellipsis->attr['ellipsis'] ?? 0;
+
+                if (is_file($f['file']) && 0 <= self::$srcContext) {
+                    if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
+                        $template = $f['object'] ?? unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
+
+                        $ellipsis = 0;
+                        $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
+                        $templateInfo = $template->getDebugInfo();
+                        if (isset($templateInfo[$f['line']])) {
+                            if (!method_exists($template, 'getSourceContext') || !is_file($templatePath = $template->getSourceContext()->getPath())) {
+                                $templatePath = null;
+                            }
+                            if ($templateSrc) {
+                                $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
+                                $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
+                            }
+                        }
+                    }
+                    if ($srcKey == $f['file']) {
+                        $src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, 'php', $f['file'], $f);
+                        $srcKey .= ':'.$f['line'];
+                        if ($ellipsis) {
+                            $ellipsis += 1 + \strlen($f['line']);
+                        }
+                    }
+                    $srcAttr .= sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']);
+                } else {
+                    $srcAttr .= '&separator=:';
+                }
+                $srcAttr .= $ellipsis ? '&ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : '';
+                self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(["\0~$srcAttr\0$srcKey" => $src]);
+            }
+        }
+
+        unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']);
+        if ($frame->inTraceStub) {
+            unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']);
+        }
+        foreach ($a as $k => $v) {
+            if (!$v) {
+                unset($a[$k]);
+            }
+        }
+        if ($frame->keepArgs && !empty($f['args'])) {
+            $a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']);
+        }
+
+        return $a;
+    }
+
+    private static function filterExceptionArray(string $xClass, array $a, string $xPrefix, int $filter): array
+    {
+        if (isset($a[$xPrefix.'trace'])) {
+            $trace = $a[$xPrefix.'trace'];
+            unset($a[$xPrefix.'trace']); // Ensures the trace is always last
+        } else {
+            $trace = [];
+        }
+
+        if (!($filter & Caster::EXCLUDE_VERBOSE) && $trace) {
+            if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
+                self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
+            }
+            $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);
+        }
+        if (empty($a[$xPrefix.'previous'])) {
+            unset($a[$xPrefix.'previous']);
+        }
+        unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']);
+
+        if (isset($a[Caster::PREFIX_PROTECTED.'message']) && str_contains($a[Caster::PREFIX_PROTECTED.'message'], "@anonymous\0")) {
+            $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
+                return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
+            }, $a[Caster::PREFIX_PROTECTED.'message']);
+        }
+
+        if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
+            $a[Caster::PREFIX_PROTECTED.'file'] = new LinkStub($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
+        }
+
+        return $a;
+    }
+
+    private static function traceUnshift(array &$trace, ?string $class, string $file, int $line): void
+    {
+        if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) {
+            return;
+        }
+        array_unshift($trace, [
+            'function' => $class ? 'new '.$class : null,
+            'file' => $file,
+            'line' => $line,
+        ]);
+    }
+
+    private static function extractSource(string $srcLines, int $line, int $srcContext, string $lang, ?string $file, array $frame): EnumStub
+    {
+        $srcLines = explode("\n", $srcLines);
+        $src = [];
+
+        for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
+            $src[] = ($srcLines[$i] ?? '')."\n";
+        }
+
+        if ($frame['function'] ?? false) {
+            $stub = new CutStub(new \stdClass());
+            $stub->class = (isset($frame['class']) ? $frame['class'].$frame['type'] : '').$frame['function'];
+            $stub->type = Stub::TYPE_OBJECT;
+            $stub->attr['cut_hash'] = true;
+            $stub->attr['file'] = $frame['file'];
+            $stub->attr['line'] = $frame['line'];
+
+            try {
+                $caller = isset($frame['class']) ? new \ReflectionMethod($frame['class'], $frame['function']) : new \ReflectionFunction($frame['function']);
+                $stub->class .= ReflectionCaster::getSignature(ReflectionCaster::castFunctionAbstract($caller, [], $stub, true, Caster::EXCLUDE_VERBOSE));
+
+                if ($f = $caller->getFileName()) {
+                    $stub->attr['file'] = $f;
+                    $stub->attr['line'] = $caller->getStartLine();
+                }
+            } catch (\ReflectionException $e) {
+                // ignore fake class/function
+            }
+
+            $srcLines = ["\0~separator=\0" => $stub];
+        } else {
+            $stub = null;
+            $srcLines = [];
+        }
+
+        $ltrim = 0;
+        do {
+            $pad = null;
+            for ($i = $srcContext << 1; $i >= 0; --$i) {
+                if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) {
+                    if (null === $pad) {
+                        $pad = $c;
+                    }
+                    if ((' ' !== $c && "\t" !== $c) || $pad !== $c) {
+                        break;
+                    }
+                }
+            }
+            ++$ltrim;
+        } while (0 > $i && null !== $pad);
+
+        --$ltrim;
+
+        foreach ($src as $i => $c) {
+            if ($ltrim) {
+                $c = isset($c[$ltrim]) && "\r" !== $c[$ltrim] ? substr($c, $ltrim) : ltrim($c, " \t");
+            }
+            $c = substr($c, 0, -1);
+            if ($i !== $srcContext) {
+                $c = new ConstStub('default', $c);
+            } else {
+                $c = new ConstStub($c, $stub ? 'in '.$stub->class : '');
+                if (null !== $file) {
+                    $c->attr['file'] = $file;
+                    $c->attr['line'] = $line;
+                }
+            }
+            $c->attr['lang'] = $lang;
+            $srcLines[sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c;
+        }
+
+        return new EnumStub($srcLines);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FrameStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FrameStub.php
new file mode 100644
index 0000000..8786755
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FrameStub.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+/**
+ * Represents a single backtrace frame as returned by debug_backtrace() or Exception->getTrace().
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class FrameStub extends EnumStub
+{
+    public $keepArgs;
+    public $inTraceStub;
+
+    public function __construct(array $frame, bool $keepArgs = true, bool $inTraceStub = false)
+    {
+        $this->value = $frame;
+        $this->keepArgs = $keepArgs;
+        $this->inTraceStub = $inTraceStub;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/GmpCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/GmpCaster.php
new file mode 100644
index 0000000..b018cc7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/GmpCaster.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts GMP objects to array representation.
+ *
+ * @author Hamza Amrouche <hamza.simperfit@gmail.com>
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class GmpCaster
+{
+    public static function castGmp(\GMP $gmp, array $a, Stub $stub, bool $isNested, int $filter): array
+    {
+        $a[Caster::PREFIX_VIRTUAL.'value'] = new ConstStub(gmp_strval($gmp), gmp_strval($gmp));
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImagineCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImagineCaster.php
new file mode 100644
index 0000000..d1289da
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImagineCaster.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Imagine\Image\ImageInterface;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ */
+final class ImagineCaster
+{
+    public static function castImage(ImageInterface $c, array $a, Stub $stub, bool $isNested): array
+    {
+        $imgData = $c->get('png');
+        if (\strlen($imgData) > 1 * 1000 * 1000) {
+            $a += [
+                Caster::PREFIX_VIRTUAL.'image' => new ConstStub($c->getSize()),
+            ];
+        } else {
+            $a += [
+                Caster::PREFIX_VIRTUAL.'image' => new ImgStub($imgData, 'image/png', $c->getSize()),
+            ];
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImgStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImgStub.php
new file mode 100644
index 0000000..a16681f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImgStub.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+/**
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ */
+class ImgStub extends ConstStub
+{
+    public function __construct(string $data, string $contentType, string $size = '')
+    {
+        $this->value = '';
+        $this->attr['img-data'] = $data;
+        $this->attr['img-size'] = $size;
+        $this->attr['content-type'] = $contentType;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/IntlCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/IntlCaster.php
new file mode 100644
index 0000000..23b9d5d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/IntlCaster.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
+ *
+ * @final
+ */
+class IntlCaster
+{
+    public static function castMessageFormatter(\MessageFormatter $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(),
+            Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(),
+        ];
+
+        return self::castError($c, $a);
+    }
+
+    public static function castNumberFormatter(\NumberFormatter $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(),
+            Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(),
+        ];
+
+        if ($filter & Caster::EXCLUDE_VERBOSE) {
+            $stub->cut += 3;
+
+            return self::castError($c, $a);
+        }
+
+        $a += [
+            Caster::PREFIX_VIRTUAL.'attributes' => new EnumStub(
+                [
+                    'PARSE_INT_ONLY' => $c->getAttribute(\NumberFormatter::PARSE_INT_ONLY),
+                    'GROUPING_USED' => $c->getAttribute(\NumberFormatter::GROUPING_USED),
+                    'DECIMAL_ALWAYS_SHOWN' => $c->getAttribute(\NumberFormatter::DECIMAL_ALWAYS_SHOWN),
+                    'MAX_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_INTEGER_DIGITS),
+                    'MIN_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_INTEGER_DIGITS),
+                    'INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::INTEGER_DIGITS),
+                    'MAX_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_FRACTION_DIGITS),
+                    'MIN_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_FRACTION_DIGITS),
+                    'FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::FRACTION_DIGITS),
+                    'MULTIPLIER' => $c->getAttribute(\NumberFormatter::MULTIPLIER),
+                    'GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::GROUPING_SIZE),
+                    'ROUNDING_MODE' => $c->getAttribute(\NumberFormatter::ROUNDING_MODE),
+                    'ROUNDING_INCREMENT' => $c->getAttribute(\NumberFormatter::ROUNDING_INCREMENT),
+                    'FORMAT_WIDTH' => $c->getAttribute(\NumberFormatter::FORMAT_WIDTH),
+                    'PADDING_POSITION' => $c->getAttribute(\NumberFormatter::PADDING_POSITION),
+                    'SECONDARY_GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::SECONDARY_GROUPING_SIZE),
+                    'SIGNIFICANT_DIGITS_USED' => $c->getAttribute(\NumberFormatter::SIGNIFICANT_DIGITS_USED),
+                    'MIN_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS),
+                    'MAX_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS),
+                    'LENIENT_PARSE' => $c->getAttribute(\NumberFormatter::LENIENT_PARSE),
+                ]
+            ),
+            Caster::PREFIX_VIRTUAL.'text_attributes' => new EnumStub(
+                [
+                    'POSITIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_PREFIX),
+                    'POSITIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_SUFFIX),
+                    'NEGATIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_PREFIX),
+                    'NEGATIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_SUFFIX),
+                    'PADDING_CHARACTER' => $c->getTextAttribute(\NumberFormatter::PADDING_CHARACTER),
+                    'CURRENCY_CODE' => $c->getTextAttribute(\NumberFormatter::CURRENCY_CODE),
+                    'DEFAULT_RULESET' => $c->getTextAttribute(\NumberFormatter::DEFAULT_RULESET),
+                    'PUBLIC_RULESETS' => $c->getTextAttribute(\NumberFormatter::PUBLIC_RULESETS),
+                ]
+            ),
+            Caster::PREFIX_VIRTUAL.'symbols' => new EnumStub(
+                [
+                    'DECIMAL_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL),
+                    'GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL),
+                    'PATTERN_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::PATTERN_SEPARATOR_SYMBOL),
+                    'PERCENT_SYMBOL' => $c->getSymbol(\NumberFormatter::PERCENT_SYMBOL),
+                    'ZERO_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::ZERO_DIGIT_SYMBOL),
+                    'DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::DIGIT_SYMBOL),
+                    'MINUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::MINUS_SIGN_SYMBOL),
+                    'PLUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::PLUS_SIGN_SYMBOL),
+                    'CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::CURRENCY_SYMBOL),
+                    'INTL_CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL),
+                    'MONETARY_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL),
+                    'EXPONENTIAL_SYMBOL' => $c->getSymbol(\NumberFormatter::EXPONENTIAL_SYMBOL),
+                    'PERMILL_SYMBOL' => $c->getSymbol(\NumberFormatter::PERMILL_SYMBOL),
+                    'PAD_ESCAPE_SYMBOL' => $c->getSymbol(\NumberFormatter::PAD_ESCAPE_SYMBOL),
+                    'INFINITY_SYMBOL' => $c->getSymbol(\NumberFormatter::INFINITY_SYMBOL),
+                    'NAN_SYMBOL' => $c->getSymbol(\NumberFormatter::NAN_SYMBOL),
+                    'SIGNIFICANT_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL),
+                    'MONETARY_GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL),
+                ]
+             ),
+        ];
+
+        return self::castError($c, $a);
+    }
+
+    public static function castIntlTimeZone(\IntlTimeZone $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'display_name' => $c->getDisplayName(),
+            Caster::PREFIX_VIRTUAL.'id' => $c->getID(),
+            Caster::PREFIX_VIRTUAL.'raw_offset' => $c->getRawOffset(),
+        ];
+
+        if ($c->useDaylightTime()) {
+            $a += [
+                Caster::PREFIX_VIRTUAL.'dst_savings' => $c->getDSTSavings(),
+            ];
+        }
+
+        return self::castError($c, $a);
+    }
+
+    public static function castIntlCalendar(\IntlCalendar $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'type' => $c->getType(),
+            Caster::PREFIX_VIRTUAL.'first_day_of_week' => $c->getFirstDayOfWeek(),
+            Caster::PREFIX_VIRTUAL.'minimal_days_in_first_week' => $c->getMinimalDaysInFirstWeek(),
+            Caster::PREFIX_VIRTUAL.'repeated_wall_time_option' => $c->getRepeatedWallTimeOption(),
+            Caster::PREFIX_VIRTUAL.'skipped_wall_time_option' => $c->getSkippedWallTimeOption(),
+            Caster::PREFIX_VIRTUAL.'time' => $c->getTime(),
+            Caster::PREFIX_VIRTUAL.'in_daylight_time' => $c->inDaylightTime(),
+            Caster::PREFIX_VIRTUAL.'is_lenient' => $c->isLenient(),
+            Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(),
+        ];
+
+        return self::castError($c, $a);
+    }
+
+    public static function castIntlDateFormatter(\IntlDateFormatter $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(),
+            Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(),
+            Caster::PREFIX_VIRTUAL.'calendar' => $c->getCalendar(),
+            Caster::PREFIX_VIRTUAL.'time_zone_id' => $c->getTimeZoneId(),
+            Caster::PREFIX_VIRTUAL.'time_type' => $c->getTimeType(),
+            Caster::PREFIX_VIRTUAL.'date_type' => $c->getDateType(),
+            Caster::PREFIX_VIRTUAL.'calendar_object' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getCalendarObject()) : $c->getCalendarObject(),
+            Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(),
+        ];
+
+        return self::castError($c, $a);
+    }
+
+    private static function castError(object $c, array $a): array
+    {
+        if ($errorCode = $c->getErrorCode()) {
+            $a += [
+                Caster::PREFIX_VIRTUAL.'error_code' => $errorCode,
+                Caster::PREFIX_VIRTUAL.'error_message' => $c->getErrorMessage(),
+            ];
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/LinkStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/LinkStub.php
new file mode 100644
index 0000000..7e07803
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/LinkStub.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+/**
+ * Represents a file or a URL.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class LinkStub extends ConstStub
+{
+    public $inVendor = false;
+
+    private static $vendorRoots;
+    private static $composerRoots;
+
+    public function __construct(string $label, int $line = 0, string $href = null)
+    {
+        $this->value = $label;
+
+        if (null === $href) {
+            $href = $label;
+        }
+        if (!\is_string($href)) {
+            return;
+        }
+        if (str_starts_with($href, 'file://')) {
+            if ($href === $label) {
+                $label = substr($label, 7);
+            }
+            $href = substr($href, 7);
+        } elseif (str_contains($href, '://')) {
+            $this->attr['href'] = $href;
+
+            return;
+        }
+        if (!is_file($href)) {
+            return;
+        }
+        if ($line) {
+            $this->attr['line'] = $line;
+        }
+        if ($label !== $this->attr['file'] = realpath($href) ?: $href) {
+            return;
+        }
+        if ($composerRoot = $this->getComposerRoot($href, $this->inVendor)) {
+            $this->attr['ellipsis'] = \strlen($href) - \strlen($composerRoot) + 1;
+            $this->attr['ellipsis-type'] = 'path';
+            $this->attr['ellipsis-tail'] = 1 + ($this->inVendor ? 2 + \strlen(implode('', \array_slice(explode(\DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0);
+        } elseif (3 < \count($ellipsis = explode(\DIRECTORY_SEPARATOR, $href))) {
+            $this->attr['ellipsis'] = 2 + \strlen(implode('', \array_slice($ellipsis, -2)));
+            $this->attr['ellipsis-type'] = 'path';
+            $this->attr['ellipsis-tail'] = 1;
+        }
+    }
+
+    private function getComposerRoot(string $file, bool &$inVendor)
+    {
+        if (null === self::$vendorRoots) {
+            self::$vendorRoots = [];
+
+            foreach (get_declared_classes() as $class) {
+                if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) {
+                    $r = new \ReflectionClass($class);
+                    $v = \dirname($r->getFileName(), 2);
+                    if (is_file($v.'/composer/installed.json')) {
+                        self::$vendorRoots[] = $v.\DIRECTORY_SEPARATOR;
+                    }
+                }
+            }
+        }
+        $inVendor = false;
+
+        if (isset(self::$composerRoots[$dir = \dirname($file)])) {
+            return self::$composerRoots[$dir];
+        }
+
+        foreach (self::$vendorRoots as $root) {
+            if ($inVendor = str_starts_with($file, $root)) {
+                return $root;
+            }
+        }
+
+        $parent = $dir;
+        while (!@is_file($parent.'/composer.json')) {
+            if (!@file_exists($parent)) {
+                // open_basedir restriction in effect
+                break;
+            }
+            if ($parent === \dirname($parent)) {
+                return self::$composerRoots[$dir] = false;
+            }
+
+            $parent = \dirname($parent);
+        }
+
+        return self::$composerRoots[$dir] = $parent.\DIRECTORY_SEPARATOR;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MemcachedCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MemcachedCaster.php
new file mode 100644
index 0000000..cfef19a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MemcachedCaster.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
+ *
+ * @final
+ */
+class MemcachedCaster
+{
+    private static $optionConstants;
+    private static $defaultOptions;
+
+    public static function castMemcached(\Memcached $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'servers' => $c->getServerList(),
+            Caster::PREFIX_VIRTUAL.'options' => new EnumStub(
+                self::getNonDefaultOptions($c)
+            ),
+        ];
+
+        return $a;
+    }
+
+    private static function getNonDefaultOptions(\Memcached $c): array
+    {
+        self::$defaultOptions = self::$defaultOptions ?? self::discoverDefaultOptions();
+        self::$optionConstants = self::$optionConstants ?? self::getOptionConstants();
+
+        $nonDefaultOptions = [];
+        foreach (self::$optionConstants as $constantKey => $value) {
+            if (self::$defaultOptions[$constantKey] !== $option = $c->getOption($value)) {
+                $nonDefaultOptions[$constantKey] = $option;
+            }
+        }
+
+        return $nonDefaultOptions;
+    }
+
+    private static function discoverDefaultOptions(): array
+    {
+        $defaultMemcached = new \Memcached();
+        $defaultMemcached->addServer('127.0.0.1', 11211);
+
+        $defaultOptions = [];
+        self::$optionConstants = self::$optionConstants ?? self::getOptionConstants();
+
+        foreach (self::$optionConstants as $constantKey => $value) {
+            $defaultOptions[$constantKey] = $defaultMemcached->getOption($value);
+        }
+
+        return $defaultOptions;
+    }
+
+    private static function getOptionConstants(): array
+    {
+        $reflectedMemcached = new \ReflectionClass(\Memcached::class);
+
+        $optionConstants = [];
+        foreach ($reflectedMemcached->getConstants() as $constantKey => $value) {
+            if (str_starts_with($constantKey, 'OPT_')) {
+                $optionConstants[$constantKey] = $value;
+            }
+        }
+
+        return $optionConstants;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PdoCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PdoCaster.php
new file mode 100644
index 0000000..140473b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PdoCaster.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts PDO related classes to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class PdoCaster
+{
+    private const PDO_ATTRIBUTES = [
+        'CASE' => [
+            \PDO::CASE_LOWER => 'LOWER',
+            \PDO::CASE_NATURAL => 'NATURAL',
+            \PDO::CASE_UPPER => 'UPPER',
+        ],
+        'ERRMODE' => [
+            \PDO::ERRMODE_SILENT => 'SILENT',
+            \PDO::ERRMODE_WARNING => 'WARNING',
+            \PDO::ERRMODE_EXCEPTION => 'EXCEPTION',
+        ],
+        'TIMEOUT',
+        'PREFETCH',
+        'AUTOCOMMIT',
+        'PERSISTENT',
+        'DRIVER_NAME',
+        'SERVER_INFO',
+        'ORACLE_NULLS' => [
+            \PDO::NULL_NATURAL => 'NATURAL',
+            \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING',
+            \PDO::NULL_TO_STRING => 'TO_STRING',
+        ],
+        'CLIENT_VERSION',
+        'SERVER_VERSION',
+        'STATEMENT_CLASS',
+        'EMULATE_PREPARES',
+        'CONNECTION_STATUS',
+        'STRINGIFY_FETCHES',
+        'DEFAULT_FETCH_MODE' => [
+            \PDO::FETCH_ASSOC => 'ASSOC',
+            \PDO::FETCH_BOTH => 'BOTH',
+            \PDO::FETCH_LAZY => 'LAZY',
+            \PDO::FETCH_NUM => 'NUM',
+            \PDO::FETCH_OBJ => 'OBJ',
+        ],
+    ];
+
+    public static function castPdo(\PDO $c, array $a, Stub $stub, bool $isNested)
+    {
+        $attr = [];
+        $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE);
+        $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+        foreach (self::PDO_ATTRIBUTES as $k => $v) {
+            if (!isset($k[0])) {
+                $k = $v;
+                $v = [];
+            }
+
+            try {
+                $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(\constant('PDO::ATTR_'.$k));
+                if ($v && isset($v[$attr[$k]])) {
+                    $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]);
+                }
+            } catch (\Exception $e) {
+            }
+        }
+        if (isset($attr[$k = 'STATEMENT_CLASS'][1])) {
+            if ($attr[$k][1]) {
+                $attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]);
+            }
+            $attr[$k][0] = new ClassStub($attr[$k][0]);
+        }
+
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $a += [
+            $prefix.'inTransaction' => method_exists($c, 'inTransaction'),
+            $prefix.'errorInfo' => $c->errorInfo(),
+            $prefix.'attributes' => new EnumStub($attr),
+        ];
+
+        if ($a[$prefix.'inTransaction']) {
+            $a[$prefix.'inTransaction'] = $c->inTransaction();
+        } else {
+            unset($a[$prefix.'inTransaction']);
+        }
+
+        if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
+            unset($a[$prefix.'errorInfo']);
+        }
+
+        $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode);
+
+        return $a;
+    }
+
+    public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $a[$prefix.'errorInfo'] = $c->errorInfo();
+
+        if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
+            unset($a[$prefix.'errorInfo']);
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PgSqlCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PgSqlCaster.php
new file mode 100644
index 0000000..d8e5b52
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PgSqlCaster.php
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts pqsql resources to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class PgSqlCaster
+{
+    private const PARAM_CODES = [
+        'server_encoding',
+        'client_encoding',
+        'is_superuser',
+        'session_authorization',
+        'DateStyle',
+        'TimeZone',
+        'IntervalStyle',
+        'integer_datetimes',
+        'application_name',
+        'standard_conforming_strings',
+    ];
+
+    private const TRANSACTION_STATUS = [
+        \PGSQL_TRANSACTION_IDLE => 'PGSQL_TRANSACTION_IDLE',
+        \PGSQL_TRANSACTION_ACTIVE => 'PGSQL_TRANSACTION_ACTIVE',
+        \PGSQL_TRANSACTION_INTRANS => 'PGSQL_TRANSACTION_INTRANS',
+        \PGSQL_TRANSACTION_INERROR => 'PGSQL_TRANSACTION_INERROR',
+        \PGSQL_TRANSACTION_UNKNOWN => 'PGSQL_TRANSACTION_UNKNOWN',
+    ];
+
+    private const RESULT_STATUS = [
+        \PGSQL_EMPTY_QUERY => 'PGSQL_EMPTY_QUERY',
+        \PGSQL_COMMAND_OK => 'PGSQL_COMMAND_OK',
+        \PGSQL_TUPLES_OK => 'PGSQL_TUPLES_OK',
+        \PGSQL_COPY_OUT => 'PGSQL_COPY_OUT',
+        \PGSQL_COPY_IN => 'PGSQL_COPY_IN',
+        \PGSQL_BAD_RESPONSE => 'PGSQL_BAD_RESPONSE',
+        \PGSQL_NONFATAL_ERROR => 'PGSQL_NONFATAL_ERROR',
+        \PGSQL_FATAL_ERROR => 'PGSQL_FATAL_ERROR',
+    ];
+
+    private const DIAG_CODES = [
+        'severity' => \PGSQL_DIAG_SEVERITY,
+        'sqlstate' => \PGSQL_DIAG_SQLSTATE,
+        'message' => \PGSQL_DIAG_MESSAGE_PRIMARY,
+        'detail' => \PGSQL_DIAG_MESSAGE_DETAIL,
+        'hint' => \PGSQL_DIAG_MESSAGE_HINT,
+        'statement position' => \PGSQL_DIAG_STATEMENT_POSITION,
+        'internal position' => \PGSQL_DIAG_INTERNAL_POSITION,
+        'internal query' => \PGSQL_DIAG_INTERNAL_QUERY,
+        'context' => \PGSQL_DIAG_CONTEXT,
+        'file' => \PGSQL_DIAG_SOURCE_FILE,
+        'line' => \PGSQL_DIAG_SOURCE_LINE,
+        'function' => \PGSQL_DIAG_SOURCE_FUNCTION,
+    ];
+
+    public static function castLargeObject($lo, array $a, Stub $stub, bool $isNested)
+    {
+        $a['seek position'] = pg_lo_tell($lo);
+
+        return $a;
+    }
+
+    public static function castLink($link, array $a, Stub $stub, bool $isNested)
+    {
+        $a['status'] = pg_connection_status($link);
+        $a['status'] = new ConstStub(\PGSQL_CONNECTION_OK === $a['status'] ? 'PGSQL_CONNECTION_OK' : 'PGSQL_CONNECTION_BAD', $a['status']);
+        $a['busy'] = pg_connection_busy($link);
+
+        $a['transaction'] = pg_transaction_status($link);
+        if (isset(self::TRANSACTION_STATUS[$a['transaction']])) {
+            $a['transaction'] = new ConstStub(self::TRANSACTION_STATUS[$a['transaction']], $a['transaction']);
+        }
+
+        $a['pid'] = pg_get_pid($link);
+        $a['last error'] = pg_last_error($link);
+        $a['last notice'] = pg_last_notice($link);
+        $a['host'] = pg_host($link);
+        $a['port'] = pg_port($link);
+        $a['dbname'] = pg_dbname($link);
+        $a['options'] = pg_options($link);
+        $a['version'] = pg_version($link);
+
+        foreach (self::PARAM_CODES as $v) {
+            if (false !== $s = pg_parameter_status($link, $v)) {
+                $a['param'][$v] = $s;
+            }
+        }
+
+        $a['param']['client_encoding'] = pg_client_encoding($link);
+        $a['param'] = new EnumStub($a['param']);
+
+        return $a;
+    }
+
+    public static function castResult($result, array $a, Stub $stub, bool $isNested)
+    {
+        $a['num rows'] = pg_num_rows($result);
+        $a['status'] = pg_result_status($result);
+        if (isset(self::RESULT_STATUS[$a['status']])) {
+            $a['status'] = new ConstStub(self::RESULT_STATUS[$a['status']], $a['status']);
+        }
+        $a['command-completion tag'] = pg_result_status($result, \PGSQL_STATUS_STRING);
+
+        if (-1 === $a['num rows']) {
+            foreach (self::DIAG_CODES as $k => $v) {
+                $a['error'][$k] = pg_result_error_field($result, $v);
+            }
+        }
+
+        $a['affected rows'] = pg_affected_rows($result);
+        $a['last OID'] = pg_last_oid($result);
+
+        $fields = pg_num_fields($result);
+
+        for ($i = 0; $i < $fields; ++$i) {
+            $field = [
+                'name' => pg_field_name($result, $i),
+                'table' => sprintf('%s (OID: %s)', pg_field_table($result, $i), pg_field_table($result, $i, true)),
+                'type' => sprintf('%s (OID: %s)', pg_field_type($result, $i), pg_field_type_oid($result, $i)),
+                'nullable' => (bool) pg_field_is_null($result, $i),
+                'storage' => pg_field_size($result, $i).' bytes',
+                'display' => pg_field_prtlen($result, $i).' chars',
+            ];
+            if (' (OID: )' === $field['table']) {
+                $field['table'] = null;
+            }
+            if ('-1 bytes' === $field['storage']) {
+                $field['storage'] = 'variable size';
+            } elseif ('1 bytes' === $field['storage']) {
+                $field['storage'] = '1 byte';
+            }
+            if ('1 chars' === $field['display']) {
+                $field['display'] = '1 char';
+            }
+            $a['fields'][] = new EnumStub($field);
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php
new file mode 100644
index 0000000..e712019
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use ProxyManager\Proxy\ProxyInterface;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class ProxyManagerCaster
+{
+    public static function castProxy(ProxyInterface $c, array $a, Stub $stub, bool $isNested)
+    {
+        if ($parent = get_parent_class($c)) {
+            $stub->class .= ' - '.$parent;
+        }
+        $stub->class .= '@proxy';
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php
new file mode 100644
index 0000000..db4bba8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php
@@ -0,0 +1,186 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use RdKafka\Conf;
+use RdKafka\Exception as RdKafkaException;
+use RdKafka\KafkaConsumer;
+use RdKafka\Message;
+use RdKafka\Metadata\Broker as BrokerMetadata;
+use RdKafka\Metadata\Collection as CollectionMetadata;
+use RdKafka\Metadata\Partition as PartitionMetadata;
+use RdKafka\Metadata\Topic as TopicMetadata;
+use RdKafka\Topic;
+use RdKafka\TopicConf;
+use RdKafka\TopicPartition;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts RdKafka related classes to array representation.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ */
+class RdKafkaCaster
+{
+    public static function castKafkaConsumer(KafkaConsumer $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        try {
+            $assignment = $c->getAssignment();
+        } catch (RdKafkaException $e) {
+            $assignment = [];
+        }
+
+        $a += [
+            $prefix.'subscription' => $c->getSubscription(),
+            $prefix.'assignment' => $assignment,
+        ];
+
+        $a += self::extractMetadata($c);
+
+        return $a;
+    }
+
+    public static function castTopic(Topic $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'name' => $c->getName(),
+        ];
+
+        return $a;
+    }
+
+    public static function castTopicPartition(TopicPartition $c, array $a)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'offset' => $c->getOffset(),
+            $prefix.'partition' => $c->getPartition(),
+            $prefix.'topic' => $c->getTopic(),
+        ];
+
+        return $a;
+    }
+
+    public static function castMessage(Message $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'errstr' => $c->errstr(),
+        ];
+
+        return $a;
+    }
+
+    public static function castConf(Conf $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        foreach ($c->dump() as $key => $value) {
+            $a[$prefix.$key] = $value;
+        }
+
+        return $a;
+    }
+
+    public static function castTopicConf(TopicConf $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        foreach ($c->dump() as $key => $value) {
+            $a[$prefix.$key] = $value;
+        }
+
+        return $a;
+    }
+
+    public static function castRdKafka(\RdKafka $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'out_q_len' => $c->getOutQLen(),
+        ];
+
+        $a += self::extractMetadata($c);
+
+        return $a;
+    }
+
+    public static function castCollectionMetadata(CollectionMetadata $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a += iterator_to_array($c);
+
+        return $a;
+    }
+
+    public static function castTopicMetadata(TopicMetadata $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'name' => $c->getTopic(),
+            $prefix.'partitions' => $c->getPartitions(),
+        ];
+
+        return $a;
+    }
+
+    public static function castPartitionMetadata(PartitionMetadata $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'id' => $c->getId(),
+            $prefix.'err' => $c->getErr(),
+            $prefix.'leader' => $c->getLeader(),
+        ];
+
+        return $a;
+    }
+
+    public static function castBrokerMetadata(BrokerMetadata $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        $a += [
+            $prefix.'id' => $c->getId(),
+            $prefix.'host' => $c->getHost(),
+            $prefix.'port' => $c->getPort(),
+        ];
+
+        return $a;
+    }
+
+    private static function extractMetadata($c)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        try {
+            $m = $c->getMetadata(true, null, 500);
+        } catch (RdKafkaException $e) {
+            return [];
+        }
+
+        return [
+            $prefix.'orig_broker_id' => $m->getOrigBrokerId(),
+            $prefix.'orig_broker_name' => $m->getOrigBrokerName(),
+            $prefix.'brokers' => $m->getBrokers(),
+            $prefix.'topics' => $m->getTopics(),
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RedisCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RedisCaster.php
new file mode 100644
index 0000000..8f97eaa
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RedisCaster.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Redis class from ext-redis to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class RedisCaster
+{
+    private const SERIALIZERS = [
+        \Redis::SERIALIZER_NONE => 'NONE',
+        \Redis::SERIALIZER_PHP => 'PHP',
+        2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY
+    ];
+
+    private const MODES = [
+        \Redis::ATOMIC => 'ATOMIC',
+        \Redis::MULTI => 'MULTI',
+        \Redis::PIPELINE => 'PIPELINE',
+    ];
+
+    private const COMPRESSION_MODES = [
+        0 => 'NONE', // Redis::COMPRESSION_NONE
+        1 => 'LZF',  // Redis::COMPRESSION_LZF
+    ];
+
+    private const FAILOVER_OPTIONS = [
+        \RedisCluster::FAILOVER_NONE => 'NONE',
+        \RedisCluster::FAILOVER_ERROR => 'ERROR',
+        \RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE',
+        \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES',
+    ];
+
+    public static function castRedis(\Redis $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        if (!$connected = $c->isConnected()) {
+            return $a + [
+                $prefix.'isConnected' => $connected,
+            ];
+        }
+
+        $mode = $c->getMode();
+
+        return $a + [
+            $prefix.'isConnected' => $connected,
+            $prefix.'host' => $c->getHost(),
+            $prefix.'port' => $c->getPort(),
+            $prefix.'auth' => $c->getAuth(),
+            $prefix.'mode' => isset(self::MODES[$mode]) ? new ConstStub(self::MODES[$mode], $mode) : $mode,
+            $prefix.'dbNum' => $c->getDbNum(),
+            $prefix.'timeout' => $c->getTimeout(),
+            $prefix.'lastError' => $c->getLastError(),
+            $prefix.'persistentId' => $c->getPersistentID(),
+            $prefix.'options' => self::getRedisOptions($c),
+        ];
+    }
+
+    public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        return $a + [
+            $prefix.'hosts' => $c->_hosts(),
+            $prefix.'function' => ClassStub::wrapCallable($c->_function()),
+            $prefix.'lastError' => $c->getLastError(),
+            $prefix.'options' => self::getRedisOptions($c),
+        ];
+    }
+
+    public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER);
+
+        $a += [
+            $prefix.'_masters' => $c->_masters(),
+            $prefix.'_redir' => $c->_redir(),
+            $prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()),
+            $prefix.'lastError' => $c->getLastError(),
+            $prefix.'options' => self::getRedisOptions($c, [
+                'SLAVE_FAILOVER' => isset(self::FAILOVER_OPTIONS[$failover]) ? new ConstStub(self::FAILOVER_OPTIONS[$failover], $failover) : $failover,
+            ]),
+        ];
+
+        return $a;
+    }
+
+    /**
+     * @param \Redis|\RedisArray|\RedisCluster $redis
+     */
+    private static function getRedisOptions($redis, array $options = []): EnumStub
+    {
+        $serializer = $redis->getOption(\Redis::OPT_SERIALIZER);
+        if (\is_array($serializer)) {
+            foreach ($serializer as &$v) {
+                if (isset(self::SERIALIZERS[$v])) {
+                    $v = new ConstStub(self::SERIALIZERS[$v], $v);
+                }
+            }
+        } elseif (isset(self::SERIALIZERS[$serializer])) {
+            $serializer = new ConstStub(self::SERIALIZERS[$serializer], $serializer);
+        }
+
+        $compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0;
+        if (\is_array($compression)) {
+            foreach ($compression as &$v) {
+                if (isset(self::COMPRESSION_MODES[$v])) {
+                    $v = new ConstStub(self::COMPRESSION_MODES[$v], $v);
+                }
+            }
+        } elseif (isset(self::COMPRESSION_MODES[$compression])) {
+            $compression = new ConstStub(self::COMPRESSION_MODES[$compression], $compression);
+        }
+
+        $retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0;
+        if (\is_array($retry)) {
+            foreach ($retry as &$v) {
+                $v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v);
+            }
+        } else {
+            $retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry);
+        }
+
+        $options += [
+            'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : 0,
+            'READ_TIMEOUT' => $redis->getOption(\Redis::OPT_READ_TIMEOUT),
+            'COMPRESSION' => $compression,
+            'SERIALIZER' => $serializer,
+            'PREFIX' => $redis->getOption(\Redis::OPT_PREFIX),
+            'SCAN' => $retry,
+        ];
+
+        return new EnumStub($options);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ReflectionCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ReflectionCaster.php
new file mode 100644
index 0000000..1781f46
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ReflectionCaster.php
@@ -0,0 +1,438 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Reflector related classes to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class ReflectionCaster
+{
+    public const UNSET_CLOSURE_FILE_INFO = ['Closure' => __CLASS__.'::unsetClosureFileInfo'];
+
+    private const EXTRA_MAP = [
+        'docComment' => 'getDocComment',
+        'extension' => 'getExtensionName',
+        'isDisabled' => 'isDisabled',
+        'isDeprecated' => 'isDeprecated',
+        'isInternal' => 'isInternal',
+        'isUserDefined' => 'isUserDefined',
+        'isGenerator' => 'isGenerator',
+        'isVariadic' => 'isVariadic',
+    ];
+
+    public static function castClosure(\Closure $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $c = new \ReflectionFunction($c);
+
+        $a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
+
+        if (!str_contains($c->name, '{closure}')) {
+            $stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name;
+            unset($a[$prefix.'class']);
+        }
+        unset($a[$prefix.'extra']);
+
+        $stub->class .= self::getSignature($a);
+
+        if ($f = $c->getFileName()) {
+            $stub->attr['file'] = $f;
+            $stub->attr['line'] = $c->getStartLine();
+        }
+
+        unset($a[$prefix.'parameters']);
+
+        if ($filter & Caster::EXCLUDE_VERBOSE) {
+            $stub->cut += ($c->getFileName() ? 2 : 0) + \count($a);
+
+            return [];
+        }
+
+        if ($f) {
+            $a[$prefix.'file'] = new LinkStub($f, $c->getStartLine());
+            $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine();
+        }
+
+        return $a;
+    }
+
+    public static function unsetClosureFileInfo(\Closure $c, array $a)
+    {
+        unset($a[Caster::PREFIX_VIRTUAL.'file'], $a[Caster::PREFIX_VIRTUAL.'line']);
+
+        return $a;
+    }
+
+    public static function castGenerator(\Generator $c, array $a, Stub $stub, bool $isNested)
+    {
+        // Cannot create ReflectionGenerator based on a terminated Generator
+        try {
+            $reflectionGenerator = new \ReflectionGenerator($c);
+        } catch (\Exception $e) {
+            $a[Caster::PREFIX_VIRTUAL.'closed'] = true;
+
+            return $a;
+        }
+
+        return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested);
+    }
+
+    public static function castType(\ReflectionType $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        if ($c instanceof \ReflectionNamedType || \PHP_VERSION_ID < 80000) {
+            $a += [
+                $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
+                $prefix.'allowsNull' => $c->allowsNull(),
+                $prefix.'isBuiltin' => $c->isBuiltin(),
+            ];
+        } elseif ($c instanceof \ReflectionUnionType || $c instanceof \ReflectionIntersectionType) {
+            $a[$prefix.'allowsNull'] = $c->allowsNull();
+            self::addMap($a, $c, [
+                'types' => 'getTypes',
+            ]);
+        } else {
+            $a[$prefix.'allowsNull'] = $c->allowsNull();
+        }
+
+        return $a;
+    }
+
+    public static function castAttribute(\ReflectionAttribute $c, array $a, Stub $stub, bool $isNested)
+    {
+        self::addMap($a, $c, [
+            'name' => 'getName',
+            'arguments' => 'getArguments',
+        ]);
+
+        return $a;
+    }
+
+    public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        if ($c->getThis()) {
+            $a[$prefix.'this'] = new CutStub($c->getThis());
+        }
+        $function = $c->getFunction();
+        $frame = [
+            'class' => $function->class ?? null,
+            'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null,
+            'function' => $function->name,
+            'file' => $c->getExecutingFile(),
+            'line' => $c->getExecutingLine(),
+        ];
+        if ($trace = $c->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)) {
+            $function = new \ReflectionGenerator($c->getExecutingGenerator());
+            array_unshift($trace, [
+                'function' => 'yield',
+                'file' => $function->getExecutingFile(),
+                'line' => $function->getExecutingLine() - 1,
+            ]);
+            $trace[] = $frame;
+            $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
+        } else {
+            $function = new FrameStub($frame, false, true);
+            $function = ExceptionCaster::castFrameStub($function, [], $function, true);
+            $a[$prefix.'executing'] = $function[$prefix.'src'];
+        }
+
+        $a[Caster::PREFIX_VIRTUAL.'closed'] = false;
+
+        return $a;
+    }
+
+    public static function castClass(\ReflectionClass $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        if ($n = \Reflection::getModifierNames($c->getModifiers())) {
+            $a[$prefix.'modifiers'] = implode(' ', $n);
+        }
+
+        self::addMap($a, $c, [
+            'extends' => 'getParentClass',
+            'implements' => 'getInterfaceNames',
+            'constants' => 'getReflectionConstants',
+        ]);
+
+        foreach ($c->getProperties() as $n) {
+            $a[$prefix.'properties'][$n->name] = $n;
+        }
+
+        foreach ($c->getMethods() as $n) {
+            $a[$prefix.'methods'][$n->name] = $n;
+        }
+
+        self::addAttributes($a, $c, $prefix);
+
+        if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
+            self::addExtra($a, $c);
+        }
+
+        return $a;
+    }
+
+    public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        self::addMap($a, $c, [
+            'returnsReference' => 'returnsReference',
+            'returnType' => 'getReturnType',
+            'class' => 'getClosureScopeClass',
+            'this' => 'getClosureThis',
+        ]);
+
+        if (isset($a[$prefix.'returnType'])) {
+            $v = $a[$prefix.'returnType'];
+            $v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
+            $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
+        }
+        if (isset($a[$prefix.'class'])) {
+            $a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
+        }
+        if (isset($a[$prefix.'this'])) {
+            $a[$prefix.'this'] = new CutStub($a[$prefix.'this']);
+        }
+
+        foreach ($c->getParameters() as $v) {
+            $k = '$'.$v->name;
+            if ($v->isVariadic()) {
+                $k = '...'.$k;
+            }
+            if ($v->isPassedByReference()) {
+                $k = '&'.$k;
+            }
+            $a[$prefix.'parameters'][$k] = $v;
+        }
+        if (isset($a[$prefix.'parameters'])) {
+            $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']);
+        }
+
+        self::addAttributes($a, $c, $prefix);
+
+        if (!($filter & Caster::EXCLUDE_VERBOSE) && $v = $c->getStaticVariables()) {
+            foreach ($v as $k => &$v) {
+                if (\is_object($v)) {
+                    $a[$prefix.'use']['$'.$k] = new CutStub($v);
+                } else {
+                    $a[$prefix.'use']['$'.$k] = &$v;
+                }
+            }
+            unset($v);
+            $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']);
+        }
+
+        if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
+            self::addExtra($a, $c);
+        }
+
+        return $a;
+    }
+
+    public static function castClassConstant(\ReflectionClassConstant $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
+        $a[Caster::PREFIX_VIRTUAL.'value'] = $c->getValue();
+
+        self::addAttributes($a, $c);
+
+        return $a;
+    }
+
+    public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
+
+        return $a;
+    }
+
+    public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        self::addMap($a, $c, [
+            'position' => 'getPosition',
+            'isVariadic' => 'isVariadic',
+            'byReference' => 'isPassedByReference',
+            'allowsNull' => 'allowsNull',
+        ]);
+
+        self::addAttributes($a, $c, $prefix);
+
+        if ($v = $c->getType()) {
+            $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
+        }
+
+        if (isset($a[$prefix.'typeHint'])) {
+            $v = $a[$prefix.'typeHint'];
+            $a[$prefix.'typeHint'] = new ClassStub($v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
+        } else {
+            unset($a[$prefix.'allowsNull']);
+        }
+
+        try {
+            $a[$prefix.'default'] = $v = $c->getDefaultValue();
+            if ($c->isDefaultValueConstant()) {
+                $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
+            }
+            if (null === $v) {
+                unset($a[$prefix.'allowsNull']);
+            }
+        } catch (\ReflectionException $e) {
+        }
+
+        return $a;
+    }
+
+    public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
+
+        self::addAttributes($a, $c);
+        self::addExtra($a, $c);
+
+        return $a;
+    }
+
+    public static function castReference(\ReflectionReference $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a[Caster::PREFIX_VIRTUAL.'id'] = $c->getId();
+
+        return $a;
+    }
+
+    public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, bool $isNested)
+    {
+        self::addMap($a, $c, [
+            'version' => 'getVersion',
+            'dependencies' => 'getDependencies',
+            'iniEntries' => 'getIniEntries',
+            'isPersistent' => 'isPersistent',
+            'isTemporary' => 'isTemporary',
+            'constants' => 'getConstants',
+            'functions' => 'getFunctions',
+            'classes' => 'getClasses',
+        ]);
+
+        return $a;
+    }
+
+    public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, bool $isNested)
+    {
+        self::addMap($a, $c, [
+            'version' => 'getVersion',
+            'author' => 'getAuthor',
+            'copyright' => 'getCopyright',
+            'url' => 'getURL',
+        ]);
+
+        return $a;
+    }
+
+    public static function getSignature(array $a)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $signature = '';
+
+        if (isset($a[$prefix.'parameters'])) {
+            foreach ($a[$prefix.'parameters']->value as $k => $param) {
+                $signature .= ', ';
+                if ($type = $param->getType()) {
+                    if (!$type instanceof \ReflectionNamedType) {
+                        $signature .= $type.' ';
+                    } else {
+                        if (!$param->isOptional() && $param->allowsNull() && 'mixed' !== $type->getName()) {
+                            $signature .= '?';
+                        }
+                        $signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
+                    }
+                }
+                $signature .= $k;
+
+                if (!$param->isDefaultValueAvailable()) {
+                    continue;
+                }
+                $v = $param->getDefaultValue();
+                $signature .= ' = ';
+
+                if ($param->isDefaultValueConstant()) {
+                    $signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1);
+                } elseif (null === $v) {
+                    $signature .= 'null';
+                } elseif (\is_array($v)) {
+                    $signature .= $v ? '[…'.\count($v).']' : '[]';
+                } elseif (\is_string($v)) {
+                    $signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
+                } elseif (\is_bool($v)) {
+                    $signature .= $v ? 'true' : 'false';
+                } else {
+                    $signature .= $v;
+                }
+            }
+        }
+        $signature = (empty($a[$prefix.'returnsReference']) ? '' : '&').'('.substr($signature, 2).')';
+
+        if (isset($a[$prefix.'returnType'])) {
+            $signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1);
+        }
+
+        return $signature;
+    }
+
+    private static function addExtra(array &$a, \Reflector $c)
+    {
+        $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : [];
+
+        if (method_exists($c, 'getFileName') && $m = $c->getFileName()) {
+            $x['file'] = new LinkStub($m, $c->getStartLine());
+            $x['line'] = $c->getStartLine().' to '.$c->getEndLine();
+        }
+
+        self::addMap($x, $c, self::EXTRA_MAP, '');
+
+        if ($x) {
+            $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x);
+        }
+    }
+
+    private static function addMap(array &$a, object $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL)
+    {
+        foreach ($map as $k => $m) {
+            if (\PHP_VERSION_ID >= 80000 && 'isDisabled' === $k) {
+                continue;
+            }
+
+            if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) {
+                $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m;
+            }
+        }
+    }
+
+    private static function addAttributes(array &$a, \Reflector $c, string $prefix = Caster::PREFIX_VIRTUAL): void
+    {
+        if (\PHP_VERSION_ID >= 80000) {
+            foreach ($c->getAttributes() as $n) {
+                $a[$prefix.'attributes'][] = $n;
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ResourceCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ResourceCaster.php
new file mode 100644
index 0000000..6ae9085
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ResourceCaster.php
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts common resource types to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class ResourceCaster
+{
+    /**
+     * @param \CurlHandle|resource $h
+     *
+     * @return array
+     */
+    public static function castCurl($h, array $a, Stub $stub, bool $isNested)
+    {
+        return curl_getinfo($h);
+    }
+
+    public static function castDba($dba, array $a, Stub $stub, bool $isNested)
+    {
+        $list = dba_list();
+        $a['file'] = $list[(int) $dba];
+
+        return $a;
+    }
+
+    public static function castProcess($process, array $a, Stub $stub, bool $isNested)
+    {
+        return proc_get_status($process);
+    }
+
+    public static function castStream($stream, array $a, Stub $stub, bool $isNested)
+    {
+        $a = stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested);
+        if ($a['uri'] ?? false) {
+            $a['uri'] = new LinkStub($a['uri']);
+        }
+
+        return $a;
+    }
+
+    public static function castStreamContext($stream, array $a, Stub $stub, bool $isNested)
+    {
+        return @stream_context_get_params($stream) ?: $a;
+    }
+
+    public static function castGd($gd, array $a, Stub $stub, bool $isNested)
+    {
+        $a['size'] = imagesx($gd).'x'.imagesy($gd);
+        $a['trueColor'] = imageistruecolor($gd);
+
+        return $a;
+    }
+
+    public static function castMysqlLink($h, array $a, Stub $stub, bool $isNested)
+    {
+        $a['host'] = mysql_get_host_info($h);
+        $a['protocol'] = mysql_get_proto_info($h);
+        $a['server'] = mysql_get_server_info($h);
+
+        return $a;
+    }
+
+    public static function castOpensslX509($h, array $a, Stub $stub, bool $isNested)
+    {
+        $stub->cut = -1;
+        $info = openssl_x509_parse($h, false);
+
+        $pin = openssl_pkey_get_public($h);
+        $pin = openssl_pkey_get_details($pin)['key'];
+        $pin = \array_slice(explode("\n", $pin), 1, -2);
+        $pin = base64_decode(implode('', $pin));
+        $pin = base64_encode(hash('sha256', $pin, true));
+
+        $a += [
+            'subject' => new EnumStub(array_intersect_key($info['subject'], ['organizationName' => true, 'commonName' => true])),
+            'issuer' => new EnumStub(array_intersect_key($info['issuer'], ['organizationName' => true, 'commonName' => true])),
+            'expiry' => new ConstStub(date(\DateTime::ISO8601, $info['validTo_time_t']), $info['validTo_time_t']),
+            'fingerprint' => new EnumStub([
+                'md5' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'md5')), 2, ':', true)),
+                'sha1' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha1')), 2, ':', true)),
+                'sha256' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha256')), 2, ':', true)),
+                'pin-sha256' => new ConstStub($pin),
+            ]),
+        ];
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SplCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SplCaster.php
new file mode 100644
index 0000000..07f4451
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SplCaster.php
@@ -0,0 +1,245 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts SPL related classes to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class SplCaster
+{
+    private const SPL_FILE_OBJECT_FLAGS = [
+        \SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE',
+        \SplFileObject::READ_AHEAD => 'READ_AHEAD',
+        \SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY',
+        \SplFileObject::READ_CSV => 'READ_CSV',
+    ];
+
+    public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, bool $isNested)
+    {
+        return self::castSplArray($c, $a, $stub, $isNested);
+    }
+
+    public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, bool $isNested)
+    {
+        return self::castSplArray($c, $a, $stub, $isNested);
+    }
+
+    public static function castHeap(\Iterator $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c),
+        ];
+
+        return $a;
+    }
+
+    public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, bool $isNested)
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $mode = $c->getIteratorMode();
+        $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE);
+
+        $a += [
+            $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode),
+            $prefix.'dllist' => iterator_to_array($c),
+        ];
+        $c->setIteratorMode($mode);
+
+        return $a;
+    }
+
+    public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, bool $isNested)
+    {
+        static $map = [
+            'path' => 'getPath',
+            'filename' => 'getFilename',
+            'basename' => 'getBasename',
+            'pathname' => 'getPathname',
+            'extension' => 'getExtension',
+            'realPath' => 'getRealPath',
+            'aTime' => 'getATime',
+            'mTime' => 'getMTime',
+            'cTime' => 'getCTime',
+            'inode' => 'getInode',
+            'size' => 'getSize',
+            'perms' => 'getPerms',
+            'owner' => 'getOwner',
+            'group' => 'getGroup',
+            'type' => 'getType',
+            'writable' => 'isWritable',
+            'readable' => 'isReadable',
+            'executable' => 'isExecutable',
+            'file' => 'isFile',
+            'dir' => 'isDir',
+            'link' => 'isLink',
+            'linkTarget' => 'getLinkTarget',
+        ];
+
+        $prefix = Caster::PREFIX_VIRTUAL;
+        unset($a["\0SplFileInfo\0fileName"]);
+        unset($a["\0SplFileInfo\0pathName"]);
+
+        if (\PHP_VERSION_ID < 80000) {
+            if (false === $c->getPathname()) {
+                $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
+
+                return $a;
+            }
+        } else {
+            try {
+                $c->isReadable();
+            } catch (\RuntimeException $e) {
+                if ('Object not initialized' !== $e->getMessage()) {
+                    throw $e;
+                }
+
+                $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
+
+                return $a;
+            } catch (\Error $e) {
+                if ('Object not initialized' !== $e->getMessage()) {
+                    throw $e;
+                }
+
+                $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
+
+                return $a;
+            }
+        }
+
+        foreach ($map as $key => $accessor) {
+            try {
+                $a[$prefix.$key] = $c->$accessor();
+            } catch (\Exception $e) {
+            }
+        }
+
+        if ($a[$prefix.'realPath'] ?? false) {
+            $a[$prefix.'realPath'] = new LinkStub($a[$prefix.'realPath']);
+        }
+
+        if (isset($a[$prefix.'perms'])) {
+            $a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']);
+        }
+
+        static $mapDate = ['aTime', 'mTime', 'cTime'];
+        foreach ($mapDate as $key) {
+            if (isset($a[$prefix.$key])) {
+                $a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]);
+            }
+        }
+
+        return $a;
+    }
+
+    public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, bool $isNested)
+    {
+        static $map = [
+            'csvControl' => 'getCsvControl',
+            'flags' => 'getFlags',
+            'maxLineLen' => 'getMaxLineLen',
+            'fstat' => 'fstat',
+            'eof' => 'eof',
+            'key' => 'key',
+        ];
+
+        $prefix = Caster::PREFIX_VIRTUAL;
+
+        foreach ($map as $key => $accessor) {
+            try {
+                $a[$prefix.$key] = $c->$accessor();
+            } catch (\Exception $e) {
+            }
+        }
+
+        if (isset($a[$prefix.'flags'])) {
+            $flagsArray = [];
+            foreach (self::SPL_FILE_OBJECT_FLAGS as $value => $name) {
+                if ($a[$prefix.'flags'] & $value) {
+                    $flagsArray[] = $name;
+                }
+            }
+            $a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']);
+        }
+
+        if (isset($a[$prefix.'fstat'])) {
+            $a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], ['dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks']);
+        }
+
+        return $a;
+    }
+
+    public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, bool $isNested)
+    {
+        $storage = [];
+        unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967
+        unset($a["\0SplObjectStorage\0storage"]);
+
+        $clone = clone $c;
+        foreach ($clone as $obj) {
+            $storage[] = [
+                'object' => $obj,
+                'info' => $clone->getInfo(),
+             ];
+        }
+
+        $a += [
+            Caster::PREFIX_VIRTUAL.'storage' => $storage,
+        ];
+
+        return $a;
+    }
+
+    public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator();
+
+        return $a;
+    }
+
+    public static function castWeakReference(\WeakReference $c, array $a, Stub $stub, bool $isNested)
+    {
+        $a[Caster::PREFIX_VIRTUAL.'object'] = $c->get();
+
+        return $a;
+    }
+
+    private static function castSplArray($c, array $a, Stub $stub, bool $isNested): array
+    {
+        $prefix = Caster::PREFIX_VIRTUAL;
+        $flags = $c->getFlags();
+
+        if (!($flags & \ArrayObject::STD_PROP_LIST)) {
+            $c->setFlags(\ArrayObject::STD_PROP_LIST);
+            $a = Caster::castObject($c, \get_class($c), method_exists($c, '__debugInfo'), $stub->class);
+            $c->setFlags($flags);
+        }
+        if (\PHP_VERSION_ID < 70400) {
+            $a[$prefix.'storage'] = $c->getArrayCopy();
+        }
+        $a += [
+            $prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
+            $prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
+        ];
+        if ($c instanceof \ArrayObject) {
+            $a[$prefix.'iteratorClass'] = new ClassStub($c->getIteratorClass());
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/StubCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/StubCaster.php
new file mode 100644
index 0000000..32ead7c
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/StubCaster.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts a caster's Stub.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class StubCaster
+{
+    public static function castStub(Stub $c, array $a, Stub $stub, bool $isNested)
+    {
+        if ($isNested) {
+            $stub->type = $c->type;
+            $stub->class = $c->class;
+            $stub->value = $c->value;
+            $stub->handle = $c->handle;
+            $stub->cut = $c->cut;
+            $stub->attr = $c->attr;
+
+            if (Stub::TYPE_REF === $c->type && !$c->class && \is_string($c->value) && !preg_match('//u', $c->value)) {
+                $stub->type = Stub::TYPE_STRING;
+                $stub->class = Stub::STRING_BINARY;
+            }
+
+            $a = [];
+        }
+
+        return $a;
+    }
+
+    public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, bool $isNested)
+    {
+        return $isNested ? $c->preservedSubset : $a;
+    }
+
+    public static function cutInternals($obj, array $a, Stub $stub, bool $isNested)
+    {
+        if ($isNested) {
+            $stub->cut += \count($a);
+
+            return [];
+        }
+
+        return $a;
+    }
+
+    public static function castEnum(EnumStub $c, array $a, Stub $stub, bool $isNested)
+    {
+        if ($isNested) {
+            $stub->class = $c->dumpKeys ? '' : null;
+            $stub->handle = 0;
+            $stub->value = null;
+            $stub->cut = $c->cut;
+            $stub->attr = $c->attr;
+
+            $a = [];
+
+            if ($c->value) {
+                foreach (array_keys($c->value) as $k) {
+                    $keys[] = !isset($k[0]) || "\0" !== $k[0] ? Caster::PREFIX_VIRTUAL.$k : $k;
+                }
+                // Preserve references with array_combine()
+                $a = array_combine($keys, $c->value);
+            }
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SymfonyCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SymfonyCaster.php
new file mode 100644
index 0000000..b7e1dd4
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SymfonyCaster.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @final
+ */
+class SymfonyCaster
+{
+    private const REQUEST_GETTERS = [
+        'pathInfo' => 'getPathInfo',
+        'requestUri' => 'getRequestUri',
+        'baseUrl' => 'getBaseUrl',
+        'basePath' => 'getBasePath',
+        'method' => 'getMethod',
+        'format' => 'getRequestFormat',
+    ];
+
+    public static function castRequest(Request $request, array $a, Stub $stub, bool $isNested)
+    {
+        $clone = null;
+
+        foreach (self::REQUEST_GETTERS as $prop => $getter) {
+            $key = Caster::PREFIX_PROTECTED.$prop;
+            if (\array_key_exists($key, $a) && null === $a[$key]) {
+                if (null === $clone) {
+                    $clone = clone $request;
+                }
+                $a[Caster::PREFIX_VIRTUAL.$prop] = $clone->{$getter}();
+            }
+        }
+
+        return $a;
+    }
+
+    public static function castHttpClient($client, array $a, Stub $stub, bool $isNested)
+    {
+        $multiKey = sprintf("\0%s\0multi", \get_class($client));
+        if (isset($a[$multiKey])) {
+            $a[$multiKey] = new CutStub($a[$multiKey]);
+        }
+
+        return $a;
+    }
+
+    public static function castHttpClientResponse($response, array $a, Stub $stub, bool $isNested)
+    {
+        $stub->cut += \count($a);
+        $a = [];
+
+        foreach ($response->getInfo() as $k => $v) {
+            $a[Caster::PREFIX_VIRTUAL.$k] = $v;
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/TraceStub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/TraceStub.php
new file mode 100644
index 0000000..5eea1c8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/TraceStub.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents a backtrace as returned by debug_backtrace() or Exception->getTrace().
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class TraceStub extends Stub
+{
+    public $keepArgs;
+    public $sliceOffset;
+    public $sliceLength;
+    public $numberingOffset;
+
+    public function __construct(array $trace, bool $keepArgs = true, int $sliceOffset = 0, int $sliceLength = null, int $numberingOffset = 0)
+    {
+        $this->value = $trace;
+        $this->keepArgs = $keepArgs;
+        $this->sliceOffset = $sliceOffset;
+        $this->sliceLength = $sliceLength;
+        $this->numberingOffset = $numberingOffset;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UuidCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UuidCaster.php
new file mode 100644
index 0000000..b102774
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UuidCaster.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Ramsey\Uuid\UuidInterface;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ */
+final class UuidCaster
+{
+    public static function castRamseyUuid(UuidInterface $c, array $a, Stub $stub, bool $isNested): array
+    {
+        $a += [
+            Caster::PREFIX_VIRTUAL.'uuid' => (string) $c,
+        ];
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php
new file mode 100644
index 0000000..fa0b55d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php
@@ -0,0 +1,79 @@
+<?php
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts XmlReader class to array representation.
+ *
+ * @author Baptiste Clavié <clavie.b@gmail.com>
+ *
+ * @final
+ */
+class XmlReaderCaster
+{
+    private const NODE_TYPES = [
+        \XMLReader::NONE => 'NONE',
+        \XMLReader::ELEMENT => 'ELEMENT',
+        \XMLReader::ATTRIBUTE => 'ATTRIBUTE',
+        \XMLReader::TEXT => 'TEXT',
+        \XMLReader::CDATA => 'CDATA',
+        \XMLReader::ENTITY_REF => 'ENTITY_REF',
+        \XMLReader::ENTITY => 'ENTITY',
+        \XMLReader::PI => 'PI (Processing Instruction)',
+        \XMLReader::COMMENT => 'COMMENT',
+        \XMLReader::DOC => 'DOC',
+        \XMLReader::DOC_TYPE => 'DOC_TYPE',
+        \XMLReader::DOC_FRAGMENT => 'DOC_FRAGMENT',
+        \XMLReader::NOTATION => 'NOTATION',
+        \XMLReader::WHITESPACE => 'WHITESPACE',
+        \XMLReader::SIGNIFICANT_WHITESPACE => 'SIGNIFICANT_WHITESPACE',
+        \XMLReader::END_ELEMENT => 'END_ELEMENT',
+        \XMLReader::END_ENTITY => 'END_ENTITY',
+        \XMLReader::XML_DECLARATION => 'XML_DECLARATION',
+    ];
+
+    public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, bool $isNested)
+    {
+        $props = Caster::PREFIX_VIRTUAL.'parserProperties';
+        $info = [
+            'localName' => $reader->localName,
+            'prefix' => $reader->prefix,
+            'nodeType' => new ConstStub(self::NODE_TYPES[$reader->nodeType], $reader->nodeType),
+            'depth' => $reader->depth,
+            'isDefault' => $reader->isDefault,
+            'isEmptyElement' => \XMLReader::NONE === $reader->nodeType ? null : $reader->isEmptyElement,
+            'xmlLang' => $reader->xmlLang,
+            'attributeCount' => $reader->attributeCount,
+            'value' => $reader->value,
+            'namespaceURI' => $reader->namespaceURI,
+            'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI,
+            $props => [
+                'LOADDTD' => $reader->getParserProperty(\XMLReader::LOADDTD),
+                'DEFAULTATTRS' => $reader->getParserProperty(\XMLReader::DEFAULTATTRS),
+                'VALIDATE' => $reader->getParserProperty(\XMLReader::VALIDATE),
+                'SUBST_ENTITIES' => $reader->getParserProperty(\XMLReader::SUBST_ENTITIES),
+            ],
+        ];
+
+        if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) {
+            $info[$props] = new EnumStub($info[$props]);
+            $info[$props]->cut = $count;
+        }
+
+        $info = Caster::filter($info, Caster::EXCLUDE_EMPTY, [], $count);
+        // +2 because hasValue and hasAttributes are always filtered
+        $stub->cut += $count + 2;
+
+        return $a + $info;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php
new file mode 100644
index 0000000..ba55fce
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts XML resources to array representation.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @final
+ */
+class XmlResourceCaster
+{
+    private const XML_ERRORS = [
+        \XML_ERROR_NONE => 'XML_ERROR_NONE',
+        \XML_ERROR_NO_MEMORY => 'XML_ERROR_NO_MEMORY',
+        \XML_ERROR_SYNTAX => 'XML_ERROR_SYNTAX',
+        \XML_ERROR_NO_ELEMENTS => 'XML_ERROR_NO_ELEMENTS',
+        \XML_ERROR_INVALID_TOKEN => 'XML_ERROR_INVALID_TOKEN',
+        \XML_ERROR_UNCLOSED_TOKEN => 'XML_ERROR_UNCLOSED_TOKEN',
+        \XML_ERROR_PARTIAL_CHAR => 'XML_ERROR_PARTIAL_CHAR',
+        \XML_ERROR_TAG_MISMATCH => 'XML_ERROR_TAG_MISMATCH',
+        \XML_ERROR_DUPLICATE_ATTRIBUTE => 'XML_ERROR_DUPLICATE_ATTRIBUTE',
+        \XML_ERROR_JUNK_AFTER_DOC_ELEMENT => 'XML_ERROR_JUNK_AFTER_DOC_ELEMENT',
+        \XML_ERROR_PARAM_ENTITY_REF => 'XML_ERROR_PARAM_ENTITY_REF',
+        \XML_ERROR_UNDEFINED_ENTITY => 'XML_ERROR_UNDEFINED_ENTITY',
+        \XML_ERROR_RECURSIVE_ENTITY_REF => 'XML_ERROR_RECURSIVE_ENTITY_REF',
+        \XML_ERROR_ASYNC_ENTITY => 'XML_ERROR_ASYNC_ENTITY',
+        \XML_ERROR_BAD_CHAR_REF => 'XML_ERROR_BAD_CHAR_REF',
+        \XML_ERROR_BINARY_ENTITY_REF => 'XML_ERROR_BINARY_ENTITY_REF',
+        \XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF => 'XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF',
+        \XML_ERROR_MISPLACED_XML_PI => 'XML_ERROR_MISPLACED_XML_PI',
+        \XML_ERROR_UNKNOWN_ENCODING => 'XML_ERROR_UNKNOWN_ENCODING',
+        \XML_ERROR_INCORRECT_ENCODING => 'XML_ERROR_INCORRECT_ENCODING',
+        \XML_ERROR_UNCLOSED_CDATA_SECTION => 'XML_ERROR_UNCLOSED_CDATA_SECTION',
+        \XML_ERROR_EXTERNAL_ENTITY_HANDLING => 'XML_ERROR_EXTERNAL_ENTITY_HANDLING',
+    ];
+
+    public static function castXml($h, array $a, Stub $stub, bool $isNested)
+    {
+        $a['current_byte_index'] = xml_get_current_byte_index($h);
+        $a['current_column_number'] = xml_get_current_column_number($h);
+        $a['current_line_number'] = xml_get_current_line_number($h);
+        $a['error_code'] = xml_get_error_code($h);
+
+        if (isset(self::XML_ERRORS[$a['error_code']])) {
+            $a['error_code'] = new ConstStub(self::XML_ERRORS[$a['error_code']], $a['error_code']);
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/AbstractCloner.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/AbstractCloner.php
new file mode 100644
index 0000000..ac55da5
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/AbstractCloner.php
@@ -0,0 +1,384 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+use Symfony\Component\VarDumper\Caster\Caster;
+use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
+
+/**
+ * AbstractCloner implements a generic caster mechanism for objects and resources.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+abstract class AbstractCloner implements ClonerInterface
+{
+    public static $defaultCasters = [
+        '__PHP_Incomplete_Class' => ['Symfony\Component\VarDumper\Caster\Caster', 'castPhpIncompleteClass'],
+
+        'Symfony\Component\VarDumper\Caster\CutStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
+        'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castCutArray'],
+        'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
+        'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castEnum'],
+
+        'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClosure'],
+        'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castGenerator'],
+        'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castType'],
+        'ReflectionAttribute' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castAttribute'],
+        'ReflectionGenerator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReflectionGenerator'],
+        'ReflectionClass' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClass'],
+        'ReflectionClassConstant' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClassConstant'],
+        'ReflectionFunctionAbstract' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castFunctionAbstract'],
+        'ReflectionMethod' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castMethod'],
+        'ReflectionParameter' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castParameter'],
+        'ReflectionProperty' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castProperty'],
+        'ReflectionReference' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReference'],
+        'ReflectionExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castExtension'],
+        'ReflectionZendExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castZendExtension'],
+
+        'Doctrine\Common\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Doctrine\Common\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castCommonProxy'],
+        'Doctrine\ORM\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castOrmProxy'],
+        'Doctrine\ORM\PersistentCollection' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castPersistentCollection'],
+        'Doctrine\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+
+        'DOMException' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castException'],
+        'DOMStringList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+        'DOMNameList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+        'DOMImplementation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castImplementation'],
+        'DOMImplementationList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+        'DOMNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNode'],
+        'DOMNameSpaceNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNameSpaceNode'],
+        'DOMDocument' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocument'],
+        'DOMNodeList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+        'DOMNamedNodeMap' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+        'DOMCharacterData' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castCharacterData'],
+        'DOMAttr' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castAttr'],
+        'DOMElement' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castElement'],
+        'DOMText' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castText'],
+        'DOMTypeinfo' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castTypeinfo'],
+        'DOMDomError' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDomError'],
+        'DOMLocator' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLocator'],
+        'DOMDocumentType' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocumentType'],
+        'DOMNotation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNotation'],
+        'DOMEntity' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castEntity'],
+        'DOMProcessingInstruction' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castProcessingInstruction'],
+        'DOMXPath' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castXPath'],
+
+        'XMLReader' => ['Symfony\Component\VarDumper\Caster\XmlReaderCaster', 'castXmlReader'],
+
+        'ErrorException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castErrorException'],
+        'Exception' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castException'],
+        'Error' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castError'],
+        'Symfony\Bridge\Monolog\Logger' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Symfony\Component\DependencyInjection\ContainerInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Symfony\Component\EventDispatcher\EventDispatcherInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
+        'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
+        'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
+        'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
+        'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'],
+        'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castThrowingCasterException'],
+        'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castTraceStub'],
+        'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFrameStub'],
+        'Symfony\Component\VarDumper\Cloner\AbstractCloner' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Symfony\Component\ErrorHandler\Exception\SilencedErrorContext' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castSilencedErrorContext'],
+
+        'Imagine\Image\ImageInterface' => ['Symfony\Component\VarDumper\Caster\ImagineCaster', 'castImage'],
+
+        'Ramsey\Uuid\UuidInterface' => ['Symfony\Component\VarDumper\Caster\UuidCaster', 'castRamseyUuid'],
+
+        'ProxyManager\Proxy\ProxyInterface' => ['Symfony\Component\VarDumper\Caster\ProxyManagerCaster', 'castProxy'],
+        'PHPUnit_Framework_MockObject_MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'PHPUnit\Framework\MockObject\MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'PHPUnit\Framework\MockObject\Stub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Prophecy\Prophecy\ProphecySubjectInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+        'Mockery\MockInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+
+        'PDO' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdo'],
+        'PDOStatement' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdoStatement'],
+
+        'AMQPConnection' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castConnection'],
+        'AMQPChannel' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castChannel'],
+        'AMQPQueue' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castQueue'],
+        'AMQPExchange' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castExchange'],
+        'AMQPEnvelope' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castEnvelope'],
+
+        'ArrayObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayObject'],
+        'ArrayIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayIterator'],
+        'SplDoublyLinkedList' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castDoublyLinkedList'],
+        'SplFileInfo' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileInfo'],
+        'SplFileObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileObject'],
+        'SplHeap' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'],
+        'SplObjectStorage' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castObjectStorage'],
+        'SplPriorityQueue' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'],
+        'OuterIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castOuterIterator'],
+        'WeakReference' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakReference'],
+
+        'Redis' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'],
+        'RedisArray' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisArray'],
+        'RedisCluster' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisCluster'],
+
+        'DateTimeInterface' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castDateTime'],
+        'DateInterval' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castInterval'],
+        'DateTimeZone' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castTimeZone'],
+        'DatePeriod' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castPeriod'],
+
+        'GMP' => ['Symfony\Component\VarDumper\Caster\GmpCaster', 'castGmp'],
+
+        'MessageFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castMessageFormatter'],
+        'NumberFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castNumberFormatter'],
+        'IntlTimeZone' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlTimeZone'],
+        'IntlCalendar' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlCalendar'],
+        'IntlDateFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlDateFormatter'],
+
+        'Memcached' => ['Symfony\Component\VarDumper\Caster\MemcachedCaster', 'castMemcached'],
+
+        'Ds\Collection' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castCollection'],
+        'Ds\Map' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castMap'],
+        'Ds\Pair' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPair'],
+        'Symfony\Component\VarDumper\Caster\DsPairStub' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPairStub'],
+
+        'CurlHandle' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
+        ':curl' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
+
+        ':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
+        ':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
+
+        'GdImage' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'],
+        ':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'],
+
+        ':mysql link' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castMysqlLink'],
+        ':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLargeObject'],
+        ':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'],
+        ':pgsql link persistent' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'],
+        ':pgsql result' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castResult'],
+        ':process' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castProcess'],
+        ':stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'],
+
+        'OpenSSLCertificate' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'],
+        ':OpenSSL X.509' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'],
+
+        ':persistent stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'],
+        ':stream-context' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStreamContext'],
+
+        'XmlParser' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'],
+        ':xml' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'],
+
+        'RdKafka' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castRdKafka'],
+        'RdKafka\Conf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castConf'],
+        'RdKafka\KafkaConsumer' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castKafkaConsumer'],
+        'RdKafka\Metadata\Broker' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castBrokerMetadata'],
+        'RdKafka\Metadata\Collection' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castCollectionMetadata'],
+        'RdKafka\Metadata\Partition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castPartitionMetadata'],
+        'RdKafka\Metadata\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicMetadata'],
+        'RdKafka\Message' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castMessage'],
+        'RdKafka\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopic'],
+        'RdKafka\TopicPartition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicPartition'],
+        'RdKafka\TopicConf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicConf'],
+    ];
+
+    protected $maxItems = 2500;
+    protected $maxString = -1;
+    protected $minDepth = 1;
+
+    private $casters = [];
+    private $prevErrorHandler;
+    private $classInfo = [];
+    private $filter = 0;
+
+    /**
+     * @param callable[]|null $casters A map of casters
+     *
+     * @see addCasters
+     */
+    public function __construct(array $casters = null)
+    {
+        if (null === $casters) {
+            $casters = static::$defaultCasters;
+        }
+        $this->addCasters($casters);
+    }
+
+    /**
+     * Adds casters for resources and objects.
+     *
+     * Maps resources or objects types to a callback.
+     * Types are in the key, with a callable caster for value.
+     * Resource types are to be prefixed with a `:`,
+     * see e.g. static::$defaultCasters.
+     *
+     * @param callable[] $casters A map of casters
+     */
+    public function addCasters(array $casters)
+    {
+        foreach ($casters as $type => $callback) {
+            $this->casters[$type][] = $callback;
+        }
+    }
+
+    /**
+     * Sets the maximum number of items to clone past the minimum depth in nested structures.
+     */
+    public function setMaxItems(int $maxItems)
+    {
+        $this->maxItems = $maxItems;
+    }
+
+    /**
+     * Sets the maximum cloned length for strings.
+     */
+    public function setMaxString(int $maxString)
+    {
+        $this->maxString = $maxString;
+    }
+
+    /**
+     * Sets the minimum tree depth where we are guaranteed to clone all the items.  After this
+     * depth is reached, only setMaxItems items will be cloned.
+     */
+    public function setMinDepth(int $minDepth)
+    {
+        $this->minDepth = $minDepth;
+    }
+
+    /**
+     * Clones a PHP variable.
+     *
+     * @param mixed $var    Any PHP variable
+     * @param int   $filter A bit field of Caster::EXCLUDE_* constants
+     *
+     * @return Data The cloned variable represented by a Data object
+     */
+    public function cloneVar($var, int $filter = 0)
+    {
+        $this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) {
+            if (\E_RECOVERABLE_ERROR === $type || \E_USER_ERROR === $type) {
+                // Cloner never dies
+                throw new \ErrorException($msg, 0, $type, $file, $line);
+            }
+
+            if ($this->prevErrorHandler) {
+                return ($this->prevErrorHandler)($type, $msg, $file, $line, $context);
+            }
+
+            return false;
+        });
+        $this->filter = $filter;
+
+        if ($gc = gc_enabled()) {
+            gc_disable();
+        }
+        try {
+            return new Data($this->doClone($var));
+        } finally {
+            if ($gc) {
+                gc_enable();
+            }
+            restore_error_handler();
+            $this->prevErrorHandler = null;
+        }
+    }
+
+    /**
+     * Effectively clones the PHP variable.
+     *
+     * @param mixed $var Any PHP variable
+     *
+     * @return array The cloned variable represented in an array
+     */
+    abstract protected function doClone($var);
+
+    /**
+     * Casts an object to an array representation.
+     *
+     * @param bool $isNested True if the object is nested in the dumped structure
+     *
+     * @return array The object casted as array
+     */
+    protected function castObject(Stub $stub, bool $isNested)
+    {
+        $obj = $stub->value;
+        $class = $stub->class;
+
+        if (\PHP_VERSION_ID < 80000 ? "\0" === ($class[15] ?? null) : str_contains($class, "@anonymous\0")) {
+            $stub->class = get_debug_type($obj);
+        }
+        if (isset($this->classInfo[$class])) {
+            [$i, $parents, $hasDebugInfo, $fileInfo] = $this->classInfo[$class];
+        } else {
+            $i = 2;
+            $parents = [$class];
+            $hasDebugInfo = method_exists($class, '__debugInfo');
+
+            foreach (class_parents($class) as $p) {
+                $parents[] = $p;
+                ++$i;
+            }
+            foreach (class_implements($class) as $p) {
+                $parents[] = $p;
+                ++$i;
+            }
+            $parents[] = '*';
+
+            $r = new \ReflectionClass($class);
+            $fileInfo = $r->isInternal() || $r->isSubclassOf(Stub::class) ? [] : [
+                'file' => $r->getFileName(),
+                'line' => $r->getStartLine(),
+            ];
+
+            $this->classInfo[$class] = [$i, $parents, $hasDebugInfo, $fileInfo];
+        }
+
+        $stub->attr += $fileInfo;
+        $a = Caster::castObject($obj, $class, $hasDebugInfo, $stub->class);
+
+        try {
+            while ($i--) {
+                if (!empty($this->casters[$p = $parents[$i]])) {
+                    foreach ($this->casters[$p] as $callback) {
+                        $a = $callback($obj, $a, $stub, $isNested, $this->filter);
+                    }
+                }
+            }
+        } catch (\Exception $e) {
+            $a = [(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)] + $a;
+        }
+
+        return $a;
+    }
+
+    /**
+     * Casts a resource to an array representation.
+     *
+     * @param bool $isNested True if the object is nested in the dumped structure
+     *
+     * @return array The resource casted as array
+     */
+    protected function castResource(Stub $stub, bool $isNested)
+    {
+        $a = [];
+        $res = $stub->value;
+        $type = $stub->class;
+
+        try {
+            if (!empty($this->casters[':'.$type])) {
+                foreach ($this->casters[':'.$type] as $callback) {
+                    $a = $callback($res, $a, $stub, $isNested, $this->filter);
+                }
+            }
+        } catch (\Exception $e) {
+            $a = [(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)] + $a;
+        }
+
+        return $a;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/ClonerInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/ClonerInterface.php
new file mode 100644
index 0000000..7ed287a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/ClonerInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+interface ClonerInterface
+{
+    /**
+     * Clones a PHP variable.
+     *
+     * @param mixed $var Any PHP variable
+     *
+     * @return Data The cloned variable represented by a Data object
+     */
+    public function cloneVar($var);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Cursor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Cursor.php
new file mode 100644
index 0000000..1fd796d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Cursor.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * Represents the current state of a dumper while dumping.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class Cursor
+{
+    public const HASH_INDEXED = Stub::ARRAY_INDEXED;
+    public const HASH_ASSOC = Stub::ARRAY_ASSOC;
+    public const HASH_OBJECT = Stub::TYPE_OBJECT;
+    public const HASH_RESOURCE = Stub::TYPE_RESOURCE;
+
+    public $depth = 0;
+    public $refIndex = 0;
+    public $softRefTo = 0;
+    public $softRefCount = 0;
+    public $softRefHandle = 0;
+    public $hardRefTo = 0;
+    public $hardRefCount = 0;
+    public $hardRefHandle = 0;
+    public $hashType;
+    public $hashKey;
+    public $hashKeyIsBinary;
+    public $hashIndex = 0;
+    public $hashLength = 0;
+    public $hashCut = 0;
+    public $stop = false;
+    public $attr = [];
+    public $skipChildren = false;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Data.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Data.php
new file mode 100644
index 0000000..c868862
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Data.php
@@ -0,0 +1,460 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+use Symfony\Component\VarDumper\Caster\Caster;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class Data implements \ArrayAccess, \Countable, \IteratorAggregate
+{
+    private $data;
+    private $position = 0;
+    private $key = 0;
+    private $maxDepth = 20;
+    private $maxItemsPerDepth = -1;
+    private $useRefHandles = -1;
+    private $context = [];
+
+    /**
+     * @param array $data An array as returned by ClonerInterface::cloneVar()
+     */
+    public function __construct(array $data)
+    {
+        $this->data = $data;
+    }
+
+    /**
+     * @return string|null The type of the value
+     */
+    public function getType()
+    {
+        $item = $this->data[$this->position][$this->key];
+
+        if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) {
+            $item = $item->value;
+        }
+        if (!$item instanceof Stub) {
+            return \gettype($item);
+        }
+        if (Stub::TYPE_STRING === $item->type) {
+            return 'string';
+        }
+        if (Stub::TYPE_ARRAY === $item->type) {
+            return 'array';
+        }
+        if (Stub::TYPE_OBJECT === $item->type) {
+            return $item->class;
+        }
+        if (Stub::TYPE_RESOURCE === $item->type) {
+            return $item->class.' resource';
+        }
+
+        return null;
+    }
+
+    /**
+     * @param array|bool $recursive Whether values should be resolved recursively or not
+     *
+     * @return string|int|float|bool|array|Data[]|null A native representation of the original value
+     */
+    public function getValue($recursive = false)
+    {
+        $item = $this->data[$this->position][$this->key];
+
+        if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) {
+            $item = $item->value;
+        }
+        if (!($item = $this->getStub($item)) instanceof Stub) {
+            return $item;
+        }
+        if (Stub::TYPE_STRING === $item->type) {
+            return $item->value;
+        }
+
+        $children = $item->position ? $this->data[$item->position] : [];
+
+        foreach ($children as $k => $v) {
+            if ($recursive && !($v = $this->getStub($v)) instanceof Stub) {
+                continue;
+            }
+            $children[$k] = clone $this;
+            $children[$k]->key = $k;
+            $children[$k]->position = $item->position;
+
+            if ($recursive) {
+                if (Stub::TYPE_REF === $v->type && ($v = $this->getStub($v->value)) instanceof Stub) {
+                    $recursive = (array) $recursive;
+                    if (isset($recursive[$v->position])) {
+                        continue;
+                    }
+                    $recursive[$v->position] = true;
+                }
+                $children[$k] = $children[$k]->getValue($recursive);
+            }
+        }
+
+        return $children;
+    }
+
+    /**
+     * @return int
+     */
+    public function count()
+    {
+        return \count($this->getValue());
+    }
+
+    /**
+     * @return \Traversable
+     */
+    public function getIterator()
+    {
+        if (!\is_array($value = $this->getValue())) {
+            throw new \LogicException(sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value)));
+        }
+
+        yield from $value;
+    }
+
+    public function __get(string $key)
+    {
+        if (null !== $data = $this->seek($key)) {
+            $item = $this->getStub($data->data[$data->position][$data->key]);
+
+            return $item instanceof Stub || [] === $item ? $data : $item;
+        }
+
+        return null;
+    }
+
+    /**
+     * @return bool
+     */
+    public function __isset(string $key)
+    {
+        return null !== $this->seek($key);
+    }
+
+    /**
+     * @return bool
+     */
+    public function offsetExists($key)
+    {
+        return $this->__isset($key);
+    }
+
+    /**
+     * @return mixed
+     */
+    public function offsetGet($key)
+    {
+        return $this->__get($key);
+    }
+
+    /**
+     * @return void
+     */
+    public function offsetSet($key, $value)
+    {
+        throw new \BadMethodCallException(self::class.' objects are immutable.');
+    }
+
+    /**
+     * @return void
+     */
+    public function offsetUnset($key)
+    {
+        throw new \BadMethodCallException(self::class.' objects are immutable.');
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        $value = $this->getValue();
+
+        if (!\is_array($value)) {
+            return (string) $value;
+        }
+
+        return sprintf('%s (count=%d)', $this->getType(), \count($value));
+    }
+
+    /**
+     * Returns a depth limited clone of $this.
+     *
+     * @return static
+     */
+    public function withMaxDepth(int $maxDepth)
+    {
+        $data = clone $this;
+        $data->maxDepth = (int) $maxDepth;
+
+        return $data;
+    }
+
+    /**
+     * Limits the number of elements per depth level.
+     *
+     * @return static
+     */
+    public function withMaxItemsPerDepth(int $maxItemsPerDepth)
+    {
+        $data = clone $this;
+        $data->maxItemsPerDepth = (int) $maxItemsPerDepth;
+
+        return $data;
+    }
+
+    /**
+     * Enables/disables objects' identifiers tracking.
+     *
+     * @param bool $useRefHandles False to hide global ref. handles
+     *
+     * @return static
+     */
+    public function withRefHandles(bool $useRefHandles)
+    {
+        $data = clone $this;
+        $data->useRefHandles = $useRefHandles ? -1 : 0;
+
+        return $data;
+    }
+
+    /**
+     * @return static
+     */
+    public function withContext(array $context)
+    {
+        $data = clone $this;
+        $data->context = $context;
+
+        return $data;
+    }
+
+    /**
+     * Seeks to a specific key in nested data structures.
+     *
+     * @param string|int $key The key to seek to
+     *
+     * @return static|null Null if the key is not set
+     */
+    public function seek($key)
+    {
+        $item = $this->data[$this->position][$this->key];
+
+        if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) {
+            $item = $item->value;
+        }
+        if (!($item = $this->getStub($item)) instanceof Stub || !$item->position) {
+            return null;
+        }
+        $keys = [$key];
+
+        switch ($item->type) {
+            case Stub::TYPE_OBJECT:
+                $keys[] = Caster::PREFIX_DYNAMIC.$key;
+                $keys[] = Caster::PREFIX_PROTECTED.$key;
+                $keys[] = Caster::PREFIX_VIRTUAL.$key;
+                $keys[] = "\0$item->class\0$key";
+                // no break
+            case Stub::TYPE_ARRAY:
+            case Stub::TYPE_RESOURCE:
+                break;
+            default:
+                return null;
+        }
+
+        $data = null;
+        $children = $this->data[$item->position];
+
+        foreach ($keys as $key) {
+            if (isset($children[$key]) || \array_key_exists($key, $children)) {
+                $data = clone $this;
+                $data->key = $key;
+                $data->position = $item->position;
+                break;
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Dumps data with a DumperInterface dumper.
+     */
+    public function dump(DumperInterface $dumper)
+    {
+        $refs = [0];
+        $cursor = new Cursor();
+
+        if ($cursor->attr = $this->context[SourceContextProvider::class] ?? []) {
+            $cursor->attr['if_links'] = true;
+            $cursor->hashType = -1;
+            $dumper->dumpScalar($cursor, 'default', '^');
+            $cursor->attr = ['if_links' => true];
+            $dumper->dumpScalar($cursor, 'default', ' ');
+            $cursor->hashType = 0;
+        }
+
+        $this->dumpItem($dumper, $cursor, $refs, $this->data[$this->position][$this->key]);
+    }
+
+    /**
+     * Depth-first dumping of items.
+     *
+     * @param mixed $item A Stub object or the original value being dumped
+     */
+    private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, $item)
+    {
+        $cursor->refIndex = 0;
+        $cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0;
+        $cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0;
+        $firstSeen = true;
+
+        if (!$item instanceof Stub) {
+            $cursor->attr = [];
+            $type = \gettype($item);
+            if ($item && 'array' === $type) {
+                $item = $this->getStub($item);
+            }
+        } elseif (Stub::TYPE_REF === $item->type) {
+            if ($item->handle) {
+                if (!isset($refs[$r = $item->handle - (\PHP_INT_MAX >> 1)])) {
+                    $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
+                } else {
+                    $firstSeen = false;
+                }
+                $cursor->hardRefTo = $refs[$r];
+                $cursor->hardRefHandle = $this->useRefHandles & $item->handle;
+                $cursor->hardRefCount = 0 < $item->handle ? $item->refCount : 0;
+            }
+            $cursor->attr = $item->attr;
+            $type = $item->class ?: \gettype($item->value);
+            $item = $this->getStub($item->value);
+        }
+        if ($item instanceof Stub) {
+            if ($item->refCount) {
+                if (!isset($refs[$r = $item->handle])) {
+                    $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
+                } else {
+                    $firstSeen = false;
+                }
+                $cursor->softRefTo = $refs[$r];
+            }
+            $cursor->softRefHandle = $this->useRefHandles & $item->handle;
+            $cursor->softRefCount = $item->refCount;
+            $cursor->attr = $item->attr;
+            $cut = $item->cut;
+
+            if ($item->position && $firstSeen) {
+                $children = $this->data[$item->position];
+
+                if ($cursor->stop) {
+                    if ($cut >= 0) {
+                        $cut += \count($children);
+                    }
+                    $children = [];
+                }
+            } else {
+                $children = [];
+            }
+            switch ($item->type) {
+                case Stub::TYPE_STRING:
+                    $dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut);
+                    break;
+
+                case Stub::TYPE_ARRAY:
+                    $item = clone $item;
+                    $item->type = $item->class;
+                    $item->class = $item->value;
+                    // no break
+                case Stub::TYPE_OBJECT:
+                case Stub::TYPE_RESOURCE:
+                    $withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth;
+                    $dumper->enterHash($cursor, $item->type, $item->class, $withChildren);
+                    if ($withChildren) {
+                        if ($cursor->skipChildren) {
+                            $withChildren = false;
+                            $cut = -1;
+                        } else {
+                            $cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class);
+                        }
+                    } elseif ($children && 0 <= $cut) {
+                        $cut += \count($children);
+                    }
+                    $cursor->skipChildren = false;
+                    $dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut);
+                    break;
+
+                default:
+                    throw new \RuntimeException(sprintf('Unexpected Stub type: "%s".', $item->type));
+            }
+        } elseif ('array' === $type) {
+            $dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false);
+            $dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0);
+        } elseif ('string' === $type) {
+            $dumper->dumpString($cursor, $item, false, 0);
+        } else {
+            $dumper->dumpScalar($cursor, $type, $item);
+        }
+    }
+
+    /**
+     * Dumps children of hash structures.
+     *
+     * @return int The final number of removed items
+     */
+    private function dumpChildren(DumperInterface $dumper, Cursor $parentCursor, array &$refs, array $children, int $hashCut, int $hashType, bool $dumpKeys): int
+    {
+        $cursor = clone $parentCursor;
+        ++$cursor->depth;
+        $cursor->hashType = $hashType;
+        $cursor->hashIndex = 0;
+        $cursor->hashLength = \count($children);
+        $cursor->hashCut = $hashCut;
+        foreach ($children as $key => $child) {
+            $cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key);
+            $cursor->hashKey = $dumpKeys ? $key : null;
+            $this->dumpItem($dumper, $cursor, $refs, $child);
+            if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) {
+                $parentCursor->stop = true;
+
+                return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut;
+            }
+        }
+
+        return $hashCut;
+    }
+
+    private function getStub($item)
+    {
+        if (!$item || !\is_array($item)) {
+            return $item;
+        }
+
+        $stub = new Stub();
+        $stub->type = Stub::TYPE_ARRAY;
+        foreach ($item as $stub->class => $stub->position) {
+        }
+        if (isset($item[0])) {
+            $stub->cut = $item[0];
+        }
+        $stub->value = $stub->cut + ($stub->position ? \count($this->data[$stub->position]) : 0);
+
+        return $stub;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/DumperInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/DumperInterface.php
new file mode 100644
index 0000000..6d60b72
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/DumperInterface.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * DumperInterface used by Data objects.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+interface DumperInterface
+{
+    /**
+     * Dumps a scalar value.
+     *
+     * @param string                $type  The PHP type of the value being dumped
+     * @param string|int|float|bool $value The scalar value being dumped
+     */
+    public function dumpScalar(Cursor $cursor, string $type, $value);
+
+    /**
+     * Dumps a string.
+     *
+     * @param string $str The string being dumped
+     * @param bool   $bin Whether $str is UTF-8 or binary encoded
+     * @param int    $cut The number of characters $str has been cut by
+     */
+    public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut);
+
+    /**
+     * Dumps while entering an hash.
+     *
+     * @param int        $type     A Cursor::HASH_* const for the type of hash
+     * @param string|int $class    The object class, resource type or array count
+     * @param bool       $hasChild When the dump of the hash has child item
+     */
+    public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild);
+
+    /**
+     * Dumps while leaving an hash.
+     *
+     * @param int        $type     A Cursor::HASH_* const for the type of hash
+     * @param string|int $class    The object class, resource type or array count
+     * @param bool       $hasChild When the dump of the hash has child item
+     * @param int        $cut      The number of items the hash has been cut by
+     */
+    public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Stub.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Stub.php
new file mode 100644
index 0000000..073c56e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Stub.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * Represents the main properties of a PHP variable.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class Stub
+{
+    public const TYPE_REF = 1;
+    public const TYPE_STRING = 2;
+    public const TYPE_ARRAY = 3;
+    public const TYPE_OBJECT = 4;
+    public const TYPE_RESOURCE = 5;
+
+    public const STRING_BINARY = 1;
+    public const STRING_UTF8 = 2;
+
+    public const ARRAY_ASSOC = 1;
+    public const ARRAY_INDEXED = 2;
+
+    public $type = self::TYPE_REF;
+    public $class = '';
+    public $value;
+    public $cut = 0;
+    public $handle = 0;
+    public $refCount = 0;
+    public $position = 0;
+    public $attr = [];
+
+    private static $defaultProperties = [];
+
+    /**
+     * @internal
+     */
+    public function __sleep(): array
+    {
+        $properties = [];
+
+        if (!isset(self::$defaultProperties[$c = static::class])) {
+            self::$defaultProperties[$c] = get_class_vars($c);
+
+            foreach ((new \ReflectionClass($c))->getStaticProperties() as $k => $v) {
+                unset(self::$defaultProperties[$c][$k]);
+            }
+        }
+
+        foreach (self::$defaultProperties[$c] as $k => $v) {
+            if ($this->$k !== $v) {
+                $properties[] = $k;
+            }
+        }
+
+        return $properties;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/VarCloner.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/VarCloner.php
new file mode 100644
index 0000000..90d5ac9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/VarCloner.php
@@ -0,0 +1,288 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class VarCloner extends AbstractCloner
+{
+    private static $gid;
+    private static $arrayCache = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doClone($var)
+    {
+        $len = 1;                       // Length of $queue
+        $pos = 0;                       // Number of cloned items past the minimum depth
+        $refsCounter = 0;               // Hard references counter
+        $queue = [[$var]];    // This breadth-first queue is the return value
+        $hardRefs = [];            // Map of original zval ids to stub objects
+        $objRefs = [];             // Map of original object handles to their stub object counterpart
+        $objects = [];             // Keep a ref to objects to ensure their handle cannot be reused while cloning
+        $resRefs = [];             // Map of original resource handles to their stub object counterpart
+        $values = [];              // Map of stub objects' ids to original values
+        $maxItems = $this->maxItems;
+        $maxString = $this->maxString;
+        $minDepth = $this->minDepth;
+        $currentDepth = 0;              // Current tree depth
+        $currentDepthFinalIndex = 0;    // Final $queue index for current tree depth
+        $minimumDepthReached = 0 === $minDepth; // Becomes true when minimum tree depth has been reached
+        $cookie = (object) [];          // Unique object used to detect hard references
+        $a = null;                      // Array cast for nested structures
+        $stub = null;                   // Stub capturing the main properties of an original item value
+                                        // or null if the original value is used directly
+
+        if (!$gid = self::$gid) {
+            $gid = self::$gid = md5(random_bytes(6)); // Unique string used to detect the special $GLOBALS variable
+        }
+        $arrayStub = new Stub();
+        $arrayStub->type = Stub::TYPE_ARRAY;
+        $fromObjCast = false;
+
+        for ($i = 0; $i < $len; ++$i) {
+            // Detect when we move on to the next tree depth
+            if ($i > $currentDepthFinalIndex) {
+                ++$currentDepth;
+                $currentDepthFinalIndex = $len - 1;
+                if ($currentDepth >= $minDepth) {
+                    $minimumDepthReached = true;
+                }
+            }
+
+            $refs = $vals = $queue[$i];
+            foreach ($vals as $k => $v) {
+                // $v is the original value or a stub object in case of hard references
+
+                if (\PHP_VERSION_ID >= 70400) {
+                    $zvalIsRef = null !== \ReflectionReference::fromArrayElement($vals, $k);
+                } else {
+                    $refs[$k] = $cookie;
+                    $zvalIsRef = $vals[$k] === $cookie;
+                }
+
+                if ($zvalIsRef) {
+                    $vals[$k] = &$stub;         // Break hard references to make $queue completely
+                    unset($stub);               // independent from the original structure
+                    if ($v instanceof Stub && isset($hardRefs[spl_object_id($v)])) {
+                        $vals[$k] = $refs[$k] = $v;
+                        if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
+                            ++$v->value->refCount;
+                        }
+                        ++$v->refCount;
+                        continue;
+                    }
+                    $refs[$k] = $vals[$k] = new Stub();
+                    $refs[$k]->value = $v;
+                    $h = spl_object_id($refs[$k]);
+                    $hardRefs[$h] = &$refs[$k];
+                    $values[$h] = $v;
+                    $vals[$k]->handle = ++$refsCounter;
+                }
+                // Create $stub when the original value $v can not be used directly
+                // If $v is a nested structure, put that structure in array $a
+                switch (true) {
+                    case null === $v:
+                    case \is_bool($v):
+                    case \is_int($v):
+                    case \is_float($v):
+                        continue 2;
+                    case \is_string($v):
+                        if ('' === $v) {
+                            continue 2;
+                        }
+                        if (!preg_match('//u', $v)) {
+                            $stub = new Stub();
+                            $stub->type = Stub::TYPE_STRING;
+                            $stub->class = Stub::STRING_BINARY;
+                            if (0 <= $maxString && 0 < $cut = \strlen($v) - $maxString) {
+                                $stub->cut = $cut;
+                                $stub->value = substr($v, 0, -$cut);
+                            } else {
+                                $stub->value = $v;
+                            }
+                        } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) {
+                            $stub = new Stub();
+                            $stub->type = Stub::TYPE_STRING;
+                            $stub->class = Stub::STRING_UTF8;
+                            $stub->cut = $cut;
+                            $stub->value = mb_substr($v, 0, $maxString, 'UTF-8');
+                        } else {
+                            continue 2;
+                        }
+                        $a = null;
+                        break;
+
+                    case \is_array($v):
+                        if (!$v) {
+                            continue 2;
+                        }
+                        $stub = $arrayStub;
+                        $stub->class = Stub::ARRAY_INDEXED;
+
+                        $j = -1;
+                        foreach ($v as $gk => $gv) {
+                            if ($gk !== ++$j) {
+                                $stub->class = Stub::ARRAY_ASSOC;
+                                break;
+                            }
+                        }
+                        $a = $v;
+
+                        if (Stub::ARRAY_ASSOC === $stub->class) {
+                            // Copies of $GLOBALS have very strange behavior,
+                            // let's detect them with some black magic
+                            if (\PHP_VERSION_ID < 80100 && ($a[$gid] = true) && isset($v[$gid])) {
+                                unset($v[$gid]);
+                                $a = [];
+                                foreach ($v as $gk => &$gv) {
+                                    if ($v === $gv) {
+                                        unset($v);
+                                        $v = new Stub();
+                                        $v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
+                                        $v->handle = -1;
+                                        $gv = &$hardRefs[spl_object_id($v)];
+                                        $gv = $v;
+                                    }
+
+                                    $a[$gk] = &$gv;
+                                }
+                                unset($gv);
+                            } else {
+                                $a = $v;
+                            }
+                        }
+                        break;
+
+                    case \is_object($v):
+                        if (empty($objRefs[$h = spl_object_id($v)])) {
+                            $stub = new Stub();
+                            $stub->type = Stub::TYPE_OBJECT;
+                            $stub->class = \get_class($v);
+                            $stub->value = $v;
+                            $stub->handle = $h;
+                            $a = $this->castObject($stub, 0 < $i);
+                            if ($v !== $stub->value) {
+                                if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) {
+                                    break;
+                                }
+                                $stub->handle = $h = spl_object_id($stub->value);
+                            }
+                            $stub->value = null;
+                            if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) {
+                                $stub->cut = \count($a);
+                                $a = null;
+                            }
+                        }
+                        if (empty($objRefs[$h])) {
+                            $objRefs[$h] = $stub;
+                            $objects[] = $v;
+                        } else {
+                            $stub = $objRefs[$h];
+                            ++$stub->refCount;
+                            $a = null;
+                        }
+                        break;
+
+                    default: // resource
+                        if (empty($resRefs[$h = (int) $v])) {
+                            $stub = new Stub();
+                            $stub->type = Stub::TYPE_RESOURCE;
+                            if ('Unknown' === $stub->class = @get_resource_type($v)) {
+                                $stub->class = 'Closed';
+                            }
+                            $stub->value = $v;
+                            $stub->handle = $h;
+                            $a = $this->castResource($stub, 0 < $i);
+                            $stub->value = null;
+                            if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) {
+                                $stub->cut = \count($a);
+                                $a = null;
+                            }
+                        }
+                        if (empty($resRefs[$h])) {
+                            $resRefs[$h] = $stub;
+                        } else {
+                            $stub = $resRefs[$h];
+                            ++$stub->refCount;
+                            $a = null;
+                        }
+                        break;
+                }
+
+                if ($a) {
+                    if (!$minimumDepthReached || 0 > $maxItems) {
+                        $queue[$len] = $a;
+                        $stub->position = $len++;
+                    } elseif ($pos < $maxItems) {
+                        if ($maxItems < $pos += \count($a)) {
+                            $a = \array_slice($a, 0, $maxItems - $pos, true);
+                            if ($stub->cut >= 0) {
+                                $stub->cut += $pos - $maxItems;
+                            }
+                        }
+                        $queue[$len] = $a;
+                        $stub->position = $len++;
+                    } elseif ($stub->cut >= 0) {
+                        $stub->cut += \count($a);
+                        $stub->position = 0;
+                    }
+                }
+
+                if ($arrayStub === $stub) {
+                    if ($arrayStub->cut) {
+                        $stub = [$arrayStub->cut, $arrayStub->class => $arrayStub->position];
+                        $arrayStub->cut = 0;
+                    } elseif (isset(self::$arrayCache[$arrayStub->class][$arrayStub->position])) {
+                        $stub = self::$arrayCache[$arrayStub->class][$arrayStub->position];
+                    } else {
+                        self::$arrayCache[$arrayStub->class][$arrayStub->position] = $stub = [$arrayStub->class => $arrayStub->position];
+                    }
+                }
+
+                if ($zvalIsRef) {
+                    $refs[$k]->value = $stub;
+                } else {
+                    $vals[$k] = $stub;
+                }
+            }
+
+            if ($fromObjCast) {
+                $fromObjCast = false;
+                $refs = $vals;
+                $vals = [];
+                $j = -1;
+                foreach ($queue[$i] as $k => $v) {
+                    foreach ([$k => true] as $gk => $gv) {
+                    }
+                    if ($gk !== $k) {
+                        $vals = (object) $vals;
+                        $vals->{$k} = $refs[++$j];
+                        $vals = (array) $vals;
+                    } else {
+                        $vals[$k] = $refs[++$j];
+                    }
+                }
+            }
+
+            $queue[$i] = $vals;
+        }
+
+        foreach ($values as $h => $v) {
+            $hardRefs[$h] = $v;
+        }
+
+        return $queue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php
new file mode 100644
index 0000000..7d9ec0e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Command\Descriptor;
+
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+
+/**
+ * Describe collected data clones for cli output.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ *
+ * @final
+ */
+class CliDescriptor implements DumpDescriptorInterface
+{
+    private $dumper;
+    private $lastIdentifier;
+    private $supportsHref;
+
+    public function __construct(CliDumper $dumper)
+    {
+        $this->dumper = $dumper;
+        $this->supportsHref = method_exists(OutputFormatterStyle::class, 'setHref');
+    }
+
+    public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void
+    {
+        $io = $output instanceof SymfonyStyle ? $output : new SymfonyStyle(new ArrayInput([]), $output);
+        $this->dumper->setColors($output->isDecorated());
+
+        $rows = [['date', date('r', (int) $context['timestamp'])]];
+        $lastIdentifier = $this->lastIdentifier;
+        $this->lastIdentifier = $clientId;
+
+        $section = "Received from client #$clientId";
+        if (isset($context['request'])) {
+            $request = $context['request'];
+            $this->lastIdentifier = $request['identifier'];
+            $section = sprintf('%s %s', $request['method'], $request['uri']);
+            if ($controller = $request['controller']) {
+                $rows[] = ['controller', rtrim($this->dumper->dump($controller, true), "\n")];
+            }
+        } elseif (isset($context['cli'])) {
+            $this->lastIdentifier = $context['cli']['identifier'];
+            $section = '$ '.$context['cli']['command_line'];
+        }
+
+        if ($this->lastIdentifier !== $lastIdentifier) {
+            $io->section($section);
+        }
+
+        if (isset($context['source'])) {
+            $source = $context['source'];
+            $sourceInfo = sprintf('%s on line %d', $source['name'], $source['line']);
+            $fileLink = $source['file_link'] ?? null;
+            if ($this->supportsHref && $fileLink) {
+                $sourceInfo = sprintf('<href=%s>%s</>', $fileLink, $sourceInfo);
+            }
+            $rows[] = ['source', $sourceInfo];
+            $file = $source['file_relative'] ?? $source['file'];
+            $rows[] = ['file', $file];
+        }
+
+        $io->table([], $rows);
+
+        if (!$this->supportsHref && isset($fileLink)) {
+            $io->writeln(['<info>Open source in your IDE/browser:</info>', $fileLink]);
+            $io->newLine();
+        }
+
+        $this->dumper->dump($data);
+        $io->newLine();
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php
new file mode 100644
index 0000000..267d27b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Command\Descriptor;
+
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\VarDumper\Cloner\Data;
+
+/**
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+interface DumpDescriptorInterface
+{
+    public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php
new file mode 100644
index 0000000..636b618
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Command\Descriptor;
+
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\HtmlDumper;
+
+/**
+ * Describe collected data clones for html output.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ *
+ * @final
+ */
+class HtmlDescriptor implements DumpDescriptorInterface
+{
+    private $dumper;
+    private $initialized = false;
+
+    public function __construct(HtmlDumper $dumper)
+    {
+        $this->dumper = $dumper;
+    }
+
+    public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void
+    {
+        if (!$this->initialized) {
+            $styles = file_get_contents(__DIR__.'/../../Resources/css/htmlDescriptor.css');
+            $scripts = file_get_contents(__DIR__.'/../../Resources/js/htmlDescriptor.js');
+            $output->writeln("<style>$styles</style><script>$scripts</script>");
+            $this->initialized = true;
+        }
+
+        $title = '-';
+        if (isset($context['request'])) {
+            $request = $context['request'];
+            $controller = "<span class='dumped-tag'>{$this->dumper->dump($request['controller'], true, ['maxDepth' => 0])}</span>";
+            $title = sprintf('<code>%s</code> <a href="%s">%s</a>', $request['method'], $uri = $request['uri'], $uri);
+            $dedupIdentifier = $request['identifier'];
+        } elseif (isset($context['cli'])) {
+            $title = '<code>$ </code>'.$context['cli']['command_line'];
+            $dedupIdentifier = $context['cli']['identifier'];
+        } else {
+            $dedupIdentifier = uniqid('', true);
+        }
+
+        $sourceDescription = '';
+        if (isset($context['source'])) {
+            $source = $context['source'];
+            $projectDir = $source['project_dir'] ?? null;
+            $sourceDescription = sprintf('%s on line %d', $source['name'], $source['line']);
+            if (isset($source['file_link'])) {
+                $sourceDescription = sprintf('<a href="%s">%s</a>', $source['file_link'], $sourceDescription);
+            }
+        }
+
+        $isoDate = $this->extractDate($context, 'c');
+        $tags = array_filter([
+            'controller' => $controller ?? null,
+            'project dir' => $projectDir ?? null,
+        ]);
+
+        $output->writeln(<<<HTML
+<article data-dedup-id="$dedupIdentifier">
+    <header>
+        <div class="row">
+            <h2 class="col">$title</h2>
+            <time class="col text-small" title="$isoDate" datetime="$isoDate">
+                {$this->extractDate($context)}
+            </time>
+        </div>
+        {$this->renderTags($tags)}
+    </header>
+    <section class="body">
+        <p class="text-small">
+            $sourceDescription
+        </p>
+        {$this->dumper->dump($data, true)}
+    </section>
+</article>
+HTML
+        );
+    }
+
+    private function extractDate(array $context, string $format = 'r'): string
+    {
+        return date($format, (int) $context['timestamp']);
+    }
+
+    private function renderTags(array $tags): string
+    {
+        if (!$tags) {
+            return '';
+        }
+
+        $renderedTags = '';
+        foreach ($tags as $key => $value) {
+            $renderedTags .= sprintf('<li><span class="badge">%s</span>%s</li>', $key, $value);
+        }
+
+        return <<<HTML
+<div class="row">
+    <ul class="tags">
+        $renderedTags
+    </ul>
+</div>
+HTML;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/ServerDumpCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/ServerDumpCommand.php
new file mode 100644
index 0000000..ead9d5b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Command/ServerDumpCommand.php
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Command\Descriptor\CliDescriptor;
+use Symfony\Component\VarDumper\Command\Descriptor\DumpDescriptorInterface;
+use Symfony\Component\VarDumper\Command\Descriptor\HtmlDescriptor;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+use Symfony\Component\VarDumper\Dumper\HtmlDumper;
+use Symfony\Component\VarDumper\Server\DumpServer;
+
+/**
+ * Starts a dump server to collect and output dumps on a single place with multiple formats support.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ *
+ * @final
+ */
+class ServerDumpCommand extends Command
+{
+    protected static $defaultName = 'server:dump';
+    protected static $defaultDescription = 'Start a dump server that collects and displays dumps in a single place';
+
+    private $server;
+
+    /** @var DumpDescriptorInterface[] */
+    private $descriptors;
+
+    public function __construct(DumpServer $server, array $descriptors = [])
+    {
+        $this->server = $server;
+        $this->descriptors = $descriptors + [
+            'cli' => new CliDescriptor(new CliDumper()),
+            'html' => new HtmlDescriptor(new HtmlDumper()),
+        ];
+
+        parent::__construct();
+    }
+
+    protected function configure()
+    {
+        $availableFormats = implode(', ', array_keys($this->descriptors));
+
+        $this
+            ->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', $availableFormats), 'cli')
+            ->setDescription(self::$defaultDescription)
+            ->setHelp(<<<'EOF'
+<info>%command.name%</info> starts a dump server that collects and displays
+dumps in a single place for debugging you application:
+
+  <info>php %command.full_name%</info>
+
+You can consult dumped data in HTML format in your browser by providing the <comment>--format=html</comment> option
+and redirecting the output to a file:
+
+  <info>php %command.full_name% --format="html" > dump.html</info>
+
+EOF
+            )
+        ;
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+        $format = $input->getOption('format');
+
+        if (!$descriptor = $this->descriptors[$format] ?? null) {
+            throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $format));
+        }
+
+        $errorIo = $io->getErrorStyle();
+        $errorIo->title('Symfony Var Dumper Server');
+
+        $this->server->start();
+
+        $errorIo->success(sprintf('Server listening on %s', $this->server->getHost()));
+        $errorIo->comment('Quit the server with CONTROL-C.');
+
+        $this->server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $io) {
+            $descriptor->describe($io, $data, $context, $clientId);
+        });
+
+        return 0;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/AbstractDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/AbstractDumper.php
new file mode 100644
index 0000000..6064ea9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/AbstractDumper.php
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Cloner\DumperInterface;
+
+/**
+ * Abstract mechanism for dumping a Data object.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+abstract class AbstractDumper implements DataDumperInterface, DumperInterface
+{
+    public const DUMP_LIGHT_ARRAY = 1;
+    public const DUMP_STRING_LENGTH = 2;
+    public const DUMP_COMMA_SEPARATOR = 4;
+    public const DUMP_TRAILING_COMMA = 8;
+
+    public static $defaultOutput = 'php://output';
+
+    protected $line = '';
+    protected $lineDumper;
+    protected $outputStream;
+    protected $decimalPoint; // This is locale dependent
+    protected $indentPad = '  ';
+    protected $flags;
+
+    private $charset = '';
+
+    /**
+     * @param callable|resource|string|null $output  A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput
+     * @param string|null                   $charset The default character encoding to use for non-UTF8 strings
+     * @param int                           $flags   A bit field of static::DUMP_* constants to fine tune dumps representation
+     */
+    public function __construct($output = null, string $charset = null, int $flags = 0)
+    {
+        $this->flags = $flags;
+        $this->setCharset($charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8');
+        $this->decimalPoint = localeconv();
+        $this->decimalPoint = $this->decimalPoint['decimal_point'];
+        $this->setOutput($output ?: static::$defaultOutput);
+        if (!$output && \is_string(static::$defaultOutput)) {
+            static::$defaultOutput = $this->outputStream;
+        }
+    }
+
+    /**
+     * Sets the output destination of the dumps.
+     *
+     * @param callable|resource|string $output A line dumper callable, an opened stream or an output path
+     *
+     * @return callable|resource|string The previous output destination
+     */
+    public function setOutput($output)
+    {
+        $prev = $this->outputStream ?? $this->lineDumper;
+
+        if (\is_callable($output)) {
+            $this->outputStream = null;
+            $this->lineDumper = $output;
+        } else {
+            if (\is_string($output)) {
+                $output = fopen($output, 'w');
+            }
+            $this->outputStream = $output;
+            $this->lineDumper = [$this, 'echoLine'];
+        }
+
+        return $prev;
+    }
+
+    /**
+     * Sets the default character encoding to use for non-UTF8 strings.
+     *
+     * @return string The previous charset
+     */
+    public function setCharset(string $charset)
+    {
+        $prev = $this->charset;
+
+        $charset = strtoupper($charset);
+        $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset;
+
+        $this->charset = $charset;
+
+        return $prev;
+    }
+
+    /**
+     * Sets the indentation pad string.
+     *
+     * @param string $pad A string that will be prepended to dumped lines, repeated by nesting level
+     *
+     * @return string The previous indent pad
+     */
+    public function setIndentPad(string $pad)
+    {
+        $prev = $this->indentPad;
+        $this->indentPad = $pad;
+
+        return $prev;
+    }
+
+    /**
+     * Dumps a Data object.
+     *
+     * @param callable|resource|string|true|null $output A line dumper callable, an opened stream, an output path or true to return the dump
+     *
+     * @return string|null The dump as string when $output is true
+     */
+    public function dump(Data $data, $output = null)
+    {
+        $this->decimalPoint = localeconv();
+        $this->decimalPoint = $this->decimalPoint['decimal_point'];
+
+        if ($locale = $this->flags & (self::DUMP_COMMA_SEPARATOR | self::DUMP_TRAILING_COMMA) ? setlocale(\LC_NUMERIC, 0) : null) {
+            setlocale(\LC_NUMERIC, 'C');
+        }
+
+        if ($returnDump = true === $output) {
+            $output = fopen('php://memory', 'r+');
+        }
+        if ($output) {
+            $prevOutput = $this->setOutput($output);
+        }
+        try {
+            $data->dump($this);
+            $this->dumpLine(-1);
+
+            if ($returnDump) {
+                $result = stream_get_contents($output, -1, 0);
+                fclose($output);
+
+                return $result;
+            }
+        } finally {
+            if ($output) {
+                $this->setOutput($prevOutput);
+            }
+            if ($locale) {
+                setlocale(\LC_NUMERIC, $locale);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Dumps the current line.
+     *
+     * @param int $depth The recursive depth in the dumped structure for the line being dumped,
+     *                   or -1 to signal the end-of-dump to the line dumper callable
+     */
+    protected function dumpLine(int $depth)
+    {
+        ($this->lineDumper)($this->line, $depth, $this->indentPad);
+        $this->line = '';
+    }
+
+    /**
+     * Generic line dumper callback.
+     */
+    protected function echoLine(string $line, int $depth, string $indentPad)
+    {
+        if (-1 !== $depth) {
+            fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n");
+        }
+    }
+
+    /**
+     * Converts a non-UTF-8 string to UTF-8.
+     *
+     * @return string|null The string converted to UTF-8
+     */
+    protected function utf8Encode(?string $s)
+    {
+        if (null === $s || preg_match('//u', $s)) {
+            return $s;
+        }
+
+        if (!\function_exists('iconv')) {
+            throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
+        }
+
+        if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) {
+            return $c;
+        }
+        if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) {
+            return $c;
+        }
+
+        return iconv('CP850', 'UTF-8', $s);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/CliDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/CliDumper.php
new file mode 100644
index 0000000..c1539ee
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/CliDumper.php
@@ -0,0 +1,643 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Cursor;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * CliDumper dumps variables for command line output.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class CliDumper extends AbstractDumper
+{
+    public static $defaultColors;
+    public static $defaultOutput = 'php://stdout';
+
+    protected $colors;
+    protected $maxStringWidth = 0;
+    protected $styles = [
+        // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+        'default' => '0;38;5;208',
+        'num' => '1;38;5;38',
+        'const' => '1;38;5;208',
+        'str' => '1;38;5;113',
+        'note' => '38;5;38',
+        'ref' => '38;5;247',
+        'public' => '',
+        'protected' => '',
+        'private' => '',
+        'meta' => '38;5;170',
+        'key' => '38;5;113',
+        'index' => '38;5;38',
+    ];
+
+    protected static $controlCharsRx = '/[\x00-\x1F\x7F]+/';
+    protected static $controlCharsMap = [
+        "\t" => '\t',
+        "\n" => '\n',
+        "\v" => '\v',
+        "\f" => '\f',
+        "\r" => '\r',
+        "\033" => '\e',
+    ];
+
+    protected $collapseNextHash = false;
+    protected $expandNextHash = false;
+
+    private $displayOptions = [
+        'fileLinkFormat' => null,
+    ];
+
+    private $handlesHrefGracefully;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($output = null, string $charset = null, int $flags = 0)
+    {
+        parent::__construct($output, $charset, $flags);
+
+        if ('\\' === \DIRECTORY_SEPARATOR && !$this->isWindowsTrueColor()) {
+            // Use only the base 16 xterm colors when using ANSICON or standard Windows 10 CLI
+            $this->setStyles([
+                'default' => '31',
+                'num' => '1;34',
+                'const' => '1;31',
+                'str' => '1;32',
+                'note' => '34',
+                'ref' => '1;30',
+                'meta' => '35',
+                'key' => '32',
+                'index' => '34',
+            ]);
+        }
+
+        $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
+    }
+
+    /**
+     * Enables/disables colored output.
+     */
+    public function setColors(bool $colors)
+    {
+        $this->colors = $colors;
+    }
+
+    /**
+     * Sets the maximum number of characters per line for dumped strings.
+     */
+    public function setMaxStringWidth(int $maxStringWidth)
+    {
+        $this->maxStringWidth = $maxStringWidth;
+    }
+
+    /**
+     * Configures styles.
+     *
+     * @param array $styles A map of style names to style definitions
+     */
+    public function setStyles(array $styles)
+    {
+        $this->styles = $styles + $this->styles;
+    }
+
+    /**
+     * Configures display options.
+     *
+     * @param array $displayOptions A map of display options to customize the behavior
+     */
+    public function setDisplayOptions(array $displayOptions)
+    {
+        $this->displayOptions = $displayOptions + $this->displayOptions;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dumpScalar(Cursor $cursor, string $type, $value)
+    {
+        $this->dumpKey($cursor);
+
+        $style = 'const';
+        $attr = $cursor->attr;
+
+        switch ($type) {
+            case 'default':
+                $style = 'default';
+                break;
+
+            case 'integer':
+                $style = 'num';
+                break;
+
+            case 'double':
+                $style = 'num';
+
+                switch (true) {
+                    case \INF === $value:  $value = 'INF'; break;
+                    case -\INF === $value: $value = '-INF'; break;
+                    case is_nan($value):  $value = 'NAN'; break;
+                    default:
+                        $value = (string) $value;
+                        if (!str_contains($value, $this->decimalPoint)) {
+                            $value .= $this->decimalPoint.'0';
+                        }
+                        break;
+                }
+                break;
+
+            case 'NULL':
+                $value = 'null';
+                break;
+
+            case 'boolean':
+                $value = $value ? 'true' : 'false';
+                break;
+
+            default:
+                $attr += ['value' => $this->utf8Encode($value)];
+                $value = $this->utf8Encode($type);
+                break;
+        }
+
+        $this->line .= $this->style($style, $value, $attr);
+
+        $this->endValue($cursor);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut)
+    {
+        $this->dumpKey($cursor);
+        $attr = $cursor->attr;
+
+        if ($bin) {
+            $str = $this->utf8Encode($str);
+        }
+        if ('' === $str) {
+            $this->line .= '""';
+            $this->endValue($cursor);
+        } else {
+            $attr += [
+                'length' => 0 <= $cut ? mb_strlen($str, 'UTF-8') + $cut : 0,
+                'binary' => $bin,
+            ];
+            $str = $bin && false !== strpos($str, "\0") ? [$str] : explode("\n", $str);
+            if (isset($str[1]) && !isset($str[2]) && !isset($str[1][0])) {
+                unset($str[1]);
+                $str[0] .= "\n";
+            }
+            $m = \count($str) - 1;
+            $i = $lineCut = 0;
+
+            if (self::DUMP_STRING_LENGTH & $this->flags) {
+                $this->line .= '('.$attr['length'].') ';
+            }
+            if ($bin) {
+                $this->line .= 'b';
+            }
+
+            if ($m) {
+                $this->line .= '"""';
+                $this->dumpLine($cursor->depth);
+            } else {
+                $this->line .= '"';
+            }
+
+            foreach ($str as $str) {
+                if ($i < $m) {
+                    $str .= "\n";
+                }
+                if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = mb_strlen($str, 'UTF-8')) {
+                    $str = mb_substr($str, 0, $this->maxStringWidth, 'UTF-8');
+                    $lineCut = $len - $this->maxStringWidth;
+                }
+                if ($m && 0 < $cursor->depth) {
+                    $this->line .= $this->indentPad;
+                }
+                if ('' !== $str) {
+                    $this->line .= $this->style('str', $str, $attr);
+                }
+                if ($i++ == $m) {
+                    if ($m) {
+                        if ('' !== $str) {
+                            $this->dumpLine($cursor->depth);
+                            if (0 < $cursor->depth) {
+                                $this->line .= $this->indentPad;
+                            }
+                        }
+                        $this->line .= '"""';
+                    } else {
+                        $this->line .= '"';
+                    }
+                    if ($cut < 0) {
+                        $this->line .= '…';
+                        $lineCut = 0;
+                    } elseif ($cut) {
+                        $lineCut += $cut;
+                    }
+                }
+                if ($lineCut) {
+                    $this->line .= '…'.$lineCut;
+                    $lineCut = 0;
+                }
+
+                if ($i > $m) {
+                    $this->endValue($cursor);
+                } else {
+                    $this->dumpLine($cursor->depth);
+                }
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild)
+    {
+        if (null === $this->colors) {
+            $this->colors = $this->supportsColors();
+        }
+
+        $this->dumpKey($cursor);
+        $attr = $cursor->attr;
+
+        if ($this->collapseNextHash) {
+            $cursor->skipChildren = true;
+            $this->collapseNextHash = $hasChild = false;
+        }
+
+        $class = $this->utf8Encode($class);
+        if (Cursor::HASH_OBJECT === $type) {
+            $prefix = $class && 'stdClass' !== $class ? $this->style('note', $class, $attr).(empty($attr['cut_hash']) ? ' {' : '') : '{';
+        } elseif (Cursor::HASH_RESOURCE === $type) {
+            $prefix = $this->style('note', $class.' resource', $attr).($hasChild ? ' {' : ' ');
+        } else {
+            $prefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? $this->style('note', 'array:'.$class).' [' : '[';
+        }
+
+        if (($cursor->softRefCount || 0 < $cursor->softRefHandle) && empty($attr['cut_hash'])) {
+            $prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), ['count' => $cursor->softRefCount]);
+        } elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) {
+            $prefix .= $this->style('ref', '&'.$cursor->hardRefTo, ['count' => $cursor->hardRefCount]);
+        } elseif (!$hasChild && Cursor::HASH_RESOURCE === $type) {
+            $prefix = substr($prefix, 0, -1);
+        }
+
+        $this->line .= $prefix;
+
+        if ($hasChild) {
+            $this->dumpLine($cursor->depth);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut)
+    {
+        if (empty($cursor->attr['cut_hash'])) {
+            $this->dumpEllipsis($cursor, $hasChild, $cut);
+            $this->line .= Cursor::HASH_OBJECT === $type ? '}' : (Cursor::HASH_RESOURCE !== $type ? ']' : ($hasChild ? '}' : ''));
+        }
+
+        $this->endValue($cursor);
+    }
+
+    /**
+     * Dumps an ellipsis for cut children.
+     *
+     * @param bool $hasChild When the dump of the hash has child item
+     * @param int  $cut      The number of items the hash has been cut by
+     */
+    protected function dumpEllipsis(Cursor $cursor, bool $hasChild, int $cut)
+    {
+        if ($cut) {
+            $this->line .= ' …';
+            if (0 < $cut) {
+                $this->line .= $cut;
+            }
+            if ($hasChild) {
+                $this->dumpLine($cursor->depth + 1);
+            }
+        }
+    }
+
+    /**
+     * Dumps a key in a hash structure.
+     */
+    protected function dumpKey(Cursor $cursor)
+    {
+        if (null !== $key = $cursor->hashKey) {
+            if ($cursor->hashKeyIsBinary) {
+                $key = $this->utf8Encode($key);
+            }
+            $attr = ['binary' => $cursor->hashKeyIsBinary];
+            $bin = $cursor->hashKeyIsBinary ? 'b' : '';
+            $style = 'key';
+            switch ($cursor->hashType) {
+                default:
+                case Cursor::HASH_INDEXED:
+                    if (self::DUMP_LIGHT_ARRAY & $this->flags) {
+                        break;
+                    }
+                    $style = 'index';
+                    // no break
+                case Cursor::HASH_ASSOC:
+                    if (\is_int($key)) {
+                        $this->line .= $this->style($style, $key).' => ';
+                    } else {
+                        $this->line .= $bin.'"'.$this->style($style, $key).'" => ';
+                    }
+                    break;
+
+                case Cursor::HASH_RESOURCE:
+                    $key = "\0~\0".$key;
+                    // no break
+                case Cursor::HASH_OBJECT:
+                    if (!isset($key[0]) || "\0" !== $key[0]) {
+                        $this->line .= '+'.$bin.$this->style('public', $key).': ';
+                    } elseif (0 < strpos($key, "\0", 1)) {
+                        $key = explode("\0", substr($key, 1), 2);
+
+                        switch ($key[0][0]) {
+                            case '+': // User inserted keys
+                                $attr['dynamic'] = true;
+                                $this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": ';
+                                break 2;
+                            case '~':
+                                $style = 'meta';
+                                if (isset($key[0][1])) {
+                                    parse_str(substr($key[0], 1), $attr);
+                                    $attr += ['binary' => $cursor->hashKeyIsBinary];
+                                }
+                                break;
+                            case '*':
+                                $style = 'protected';
+                                $bin = '#'.$bin;
+                                break;
+                            default:
+                                $attr['class'] = $key[0];
+                                $style = 'private';
+                                $bin = '-'.$bin;
+                                break;
+                        }
+
+                        if (isset($attr['collapse'])) {
+                            if ($attr['collapse']) {
+                                $this->collapseNextHash = true;
+                            } else {
+                                $this->expandNextHash = true;
+                            }
+                        }
+
+                        $this->line .= $bin.$this->style($style, $key[1], $attr).($attr['separator'] ?? ': ');
+                    } else {
+                        // This case should not happen
+                        $this->line .= '-'.$bin.'"'.$this->style('private', $key, ['class' => '']).'": ';
+                    }
+                    break;
+            }
+
+            if ($cursor->hardRefTo) {
+                $this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), ['count' => $cursor->hardRefCount]).' ';
+            }
+        }
+    }
+
+    /**
+     * Decorates a value with some style.
+     *
+     * @param string $style The type of style being applied
+     * @param string $value The value being styled
+     * @param array  $attr  Optional context information
+     *
+     * @return string The value with style decoration
+     */
+    protected function style(string $style, string $value, array $attr = [])
+    {
+        if (null === $this->colors) {
+            $this->colors = $this->supportsColors();
+        }
+
+        if (null === $this->handlesHrefGracefully) {
+            $this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
+                && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
+        }
+
+        if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
+            $prefix = substr($value, 0, -$attr['ellipsis']);
+            if ('cli' === \PHP_SAPI && 'path' === $attr['ellipsis-type'] && isset($_SERVER[$pwd = '\\' === \DIRECTORY_SEPARATOR ? 'CD' : 'PWD']) && str_starts_with($prefix, $_SERVER[$pwd])) {
+                $prefix = '.'.substr($prefix, \strlen($_SERVER[$pwd]));
+            }
+            if (!empty($attr['ellipsis-tail'])) {
+                $prefix .= substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']);
+                $value = substr($value, -$attr['ellipsis'] + $attr['ellipsis-tail']);
+            } else {
+                $value = substr($value, -$attr['ellipsis']);
+            }
+
+            $value = $this->style('default', $prefix).$this->style($style, $value);
+
+            goto href;
+        }
+
+        $map = static::$controlCharsMap;
+        $startCchr = $this->colors ? "\033[m\033[{$this->styles['default']}m" : '';
+        $endCchr = $this->colors ? "\033[m\033[{$this->styles[$style]}m" : '';
+        $value = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $startCchr, $endCchr) {
+            $s = $startCchr;
+            $c = $c[$i = 0];
+            do {
+                $s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
+            } while (isset($c[++$i]));
+
+            return $s.$endCchr;
+        }, $value, -1, $cchrCount);
+
+        if ($this->colors) {
+            if ($cchrCount && "\033" === $value[0]) {
+                $value = substr($value, \strlen($startCchr));
+            } else {
+                $value = "\033[{$this->styles[$style]}m".$value;
+            }
+            if ($cchrCount && str_ends_with($value, $endCchr)) {
+                $value = substr($value, 0, -\strlen($endCchr));
+            } else {
+                $value .= "\033[{$this->styles['default']}m";
+            }
+        }
+
+        href:
+        if ($this->colors && $this->handlesHrefGracefully) {
+            if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) {
+                if ('note' === $style) {
+                    $value .= "\033]8;;{$href}\033\\^\033]8;;\033\\";
+                } else {
+                    $attr['href'] = $href;
+                }
+            }
+            if (isset($attr['href'])) {
+                $value = "\033]8;;{$attr['href']}\033\\{$value}\033]8;;\033\\";
+            }
+        } elseif ($attr['if_links'] ?? false) {
+            return '';
+        }
+
+        return $value;
+    }
+
+    /**
+     * @return bool Tells if the current output stream supports ANSI colors or not
+     */
+    protected function supportsColors()
+    {
+        if ($this->outputStream !== static::$defaultOutput) {
+            return $this->hasColorSupport($this->outputStream);
+        }
+        if (null !== static::$defaultColors) {
+            return static::$defaultColors;
+        }
+        if (isset($_SERVER['argv'][1])) {
+            $colors = $_SERVER['argv'];
+            $i = \count($colors);
+            while (--$i > 0) {
+                if (isset($colors[$i][5])) {
+                    switch ($colors[$i]) {
+                        case '--ansi':
+                        case '--color':
+                        case '--color=yes':
+                        case '--color=force':
+                        case '--color=always':
+                        case '--colors=always':
+                            return static::$defaultColors = true;
+
+                        case '--no-ansi':
+                        case '--color=no':
+                        case '--color=none':
+                        case '--color=never':
+                        case '--colors=never':
+                            return static::$defaultColors = false;
+                    }
+                }
+            }
+        }
+
+        $h = stream_get_meta_data($this->outputStream) + ['wrapper_type' => null];
+        $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'w') : $this->outputStream;
+
+        return static::$defaultColors = $this->hasColorSupport($h);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function dumpLine(int $depth, bool $endOfValue = false)
+    {
+        if ($this->colors) {
+            $this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
+        }
+        parent::dumpLine($depth);
+    }
+
+    protected function endValue(Cursor $cursor)
+    {
+        if (-1 === $cursor->hashType) {
+            return;
+        }
+
+        if (Stub::ARRAY_INDEXED === $cursor->hashType || Stub::ARRAY_ASSOC === $cursor->hashType) {
+            if (self::DUMP_TRAILING_COMMA & $this->flags && 0 < $cursor->depth) {
+                $this->line .= ',';
+            } elseif (self::DUMP_COMMA_SEPARATOR & $this->flags && 1 < $cursor->hashLength - $cursor->hashIndex) {
+                $this->line .= ',';
+            }
+        }
+
+        $this->dumpLine($cursor->depth, true);
+    }
+
+    /**
+     * Returns true if the stream supports colorization.
+     *
+     * Reference: Composer\XdebugHandler\Process::supportsColor
+     * https://github.com/composer/xdebug-handler
+     *
+     * @param mixed $stream A CLI output stream
+     */
+    private function hasColorSupport($stream): bool
+    {
+        if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
+            return false;
+        }
+
+        // Follow https://no-color.org/
+        if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
+            return false;
+        }
+
+        if ('Hyper' === getenv('TERM_PROGRAM')) {
+            return true;
+        }
+
+        if (\DIRECTORY_SEPARATOR === '\\') {
+            return (\function_exists('sapi_windows_vt100_support')
+                && @sapi_windows_vt100_support($stream))
+                || false !== getenv('ANSICON')
+                || 'ON' === getenv('ConEmuANSI')
+                || 'xterm' === getenv('TERM');
+        }
+
+        return stream_isatty($stream);
+    }
+
+    /**
+     * Returns true if the Windows terminal supports true color.
+     *
+     * Note that this does not check an output stream, but relies on environment
+     * variables from known implementations, or a PHP and Windows version that
+     * supports true color.
+     */
+    private function isWindowsTrueColor(): bool
+    {
+        $result = 183 <= getenv('ANSICON_VER')
+            || 'ON' === getenv('ConEmuANSI')
+            || 'xterm' === getenv('TERM')
+            || 'Hyper' === getenv('TERM_PROGRAM');
+
+        if (!$result) {
+            $version = sprintf(
+                '%s.%s.%s',
+                PHP_WINDOWS_VERSION_MAJOR,
+                PHP_WINDOWS_VERSION_MINOR,
+                PHP_WINDOWS_VERSION_BUILD
+            );
+            $result = $version >= '10.0.15063';
+        }
+
+        return $result;
+    }
+
+    private function getSourceLink(string $file, int $line)
+    {
+        if ($fmt = $this->displayOptions['fileLinkFormat']) {
+            return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file.'#L'.$line);
+        }
+
+        return false;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php
new file mode 100644
index 0000000..38f8789
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper\ContextProvider;
+
+/**
+ * Tries to provide context on CLI.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+final class CliContextProvider implements ContextProviderInterface
+{
+    public function getContext(): ?array
+    {
+        if ('cli' !== \PHP_SAPI) {
+            return null;
+        }
+
+        return [
+            'command_line' => $commandLine = implode(' ', $_SERVER['argv'] ?? []),
+            'identifier' => hash('crc32b', $commandLine.$_SERVER['REQUEST_TIME_FLOAT']),
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php
new file mode 100644
index 0000000..38ef3b0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper\ContextProvider;
+
+/**
+ * Interface to provide contextual data about dump data clones sent to a server.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+interface ContextProviderInterface
+{
+    /**
+     * @return array|null Context data or null if unable to provide any context
+     */
+    public function getContext(): ?array;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php
new file mode 100644
index 0000000..3684a47
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper\ContextProvider;
+
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\VarDumper\Caster\ReflectionCaster;
+use Symfony\Component\VarDumper\Cloner\VarCloner;
+
+/**
+ * Tries to provide context from a request.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+final class RequestContextProvider implements ContextProviderInterface
+{
+    private $requestStack;
+    private $cloner;
+
+    public function __construct(RequestStack $requestStack)
+    {
+        $this->requestStack = $requestStack;
+        $this->cloner = new VarCloner();
+        $this->cloner->setMaxItems(0);
+        $this->cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);
+    }
+
+    public function getContext(): ?array
+    {
+        if (null === $request = $this->requestStack->getCurrentRequest()) {
+            return null;
+        }
+
+        $controller = $request->attributes->get('_controller');
+
+        return [
+            'uri' => $request->getUri(),
+            'method' => $request->getMethod(),
+            'controller' => $controller ? $this->cloner->cloneVar($controller) : $controller,
+            'identifier' => spl_object_hash($request),
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php
new file mode 100644
index 0000000..2e2c818
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper\ContextProvider;
+
+use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
+use Symfony\Component\VarDumper\Cloner\VarCloner;
+use Symfony\Component\VarDumper\Dumper\HtmlDumper;
+use Symfony\Component\VarDumper\VarDumper;
+use Twig\Template;
+
+/**
+ * Tries to provide context from sources (class name, file, line, code excerpt, ...).
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+final class SourceContextProvider implements ContextProviderInterface
+{
+    private $limit;
+    private $charset;
+    private $projectDir;
+    private $fileLinkFormatter;
+
+    public function __construct(string $charset = null, string $projectDir = null, FileLinkFormatter $fileLinkFormatter = null, int $limit = 9)
+    {
+        $this->charset = $charset;
+        $this->projectDir = $projectDir;
+        $this->fileLinkFormatter = $fileLinkFormatter;
+        $this->limit = $limit;
+    }
+
+    public function getContext(): ?array
+    {
+        $trace = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, $this->limit);
+
+        $file = $trace[1]['file'];
+        $line = $trace[1]['line'];
+        $name = false;
+        $fileExcerpt = false;
+
+        for ($i = 2; $i < $this->limit; ++$i) {
+            if (isset($trace[$i]['class'], $trace[$i]['function'])
+                && 'dump' === $trace[$i]['function']
+                && VarDumper::class === $trace[$i]['class']
+            ) {
+                $file = $trace[$i]['file'] ?? $file;
+                $line = $trace[$i]['line'] ?? $line;
+
+                while (++$i < $this->limit) {
+                    if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && !str_starts_with($trace[$i]['function'], 'call_user_func')) {
+                        $file = $trace[$i]['file'];
+                        $line = $trace[$i]['line'];
+
+                        break;
+                    } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof Template) {
+                        $template = $trace[$i]['object'];
+                        $name = $template->getTemplateName();
+                        $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false);
+                        $info = $template->getDebugInfo();
+                        if (isset($info[$trace[$i - 1]['line']])) {
+                            $line = $info[$trace[$i - 1]['line']];
+                            $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : null;
+
+                            if ($src) {
+                                $src = explode("\n", $src);
+                                $fileExcerpt = [];
+
+                                for ($i = max($line - 3, 1), $max = min($line + 3, \count($src)); $i <= $max; ++$i) {
+                                    $fileExcerpt[] = '<li'.($i === $line ? ' class="selected"' : '').'><code>'.$this->htmlEncode($src[$i - 1]).'</code></li>';
+                                }
+
+                                $fileExcerpt = '<ol start="'.max($line - 3, 1).'">'.implode("\n", $fileExcerpt).'</ol>';
+                            }
+                        }
+                        break;
+                    }
+                }
+                break;
+            }
+        }
+
+        if (false === $name) {
+            $name = str_replace('\\', '/', $file);
+            $name = substr($name, strrpos($name, '/') + 1);
+        }
+
+        $context = ['name' => $name, 'file' => $file, 'line' => $line];
+        $context['file_excerpt'] = $fileExcerpt;
+
+        if (null !== $this->projectDir) {
+            $context['project_dir'] = $this->projectDir;
+            if (str_starts_with($file, $this->projectDir)) {
+                $context['file_relative'] = ltrim(substr($file, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR);
+            }
+        }
+
+        if ($this->fileLinkFormatter && $fileLink = $this->fileLinkFormatter->format($context['file'], $context['line'])) {
+            $context['file_link'] = $fileLink;
+        }
+
+        return $context;
+    }
+
+    private function htmlEncode(string $s): string
+    {
+        $html = '';
+
+        $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset);
+        $dumper->setDumpHeader('');
+        $dumper->setDumpBoundaries('', '');
+
+        $cloner = new VarCloner();
+        $dumper->dump($cloner->cloneVar($s));
+
+        return substr(strip_tags($html), 1, -1);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php
new file mode 100644
index 0000000..7638417
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
+
+/**
+ * @author Kévin Thérage <therage.kevin@gmail.com>
+ */
+class ContextualizedDumper implements DataDumperInterface
+{
+    private $wrappedDumper;
+    private $contextProviders;
+
+    /**
+     * @param ContextProviderInterface[] $contextProviders
+     */
+    public function __construct(DataDumperInterface $wrappedDumper, array $contextProviders)
+    {
+        $this->wrappedDumper = $wrappedDumper;
+        $this->contextProviders = $contextProviders;
+    }
+
+    public function dump(Data $data)
+    {
+        $context = [];
+        foreach ($this->contextProviders as $contextProvider) {
+            $context[\get_class($contextProvider)] = $contextProvider->getContext();
+        }
+
+        $this->wrappedDumper->dump($data->withContext($context));
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php
new file mode 100644
index 0000000..b173bcc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+
+/**
+ * DataDumperInterface for dumping Data objects.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+interface DataDumperInterface
+{
+    public function dump(Data $data);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/HtmlDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
new file mode 100644
index 0000000..6c3abaa
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
@@ -0,0 +1,986 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Cursor;
+use Symfony\Component\VarDumper\Cloner\Data;
+
+/**
+ * HtmlDumper dumps variables as HTML.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class HtmlDumper extends CliDumper
+{
+    public static $defaultOutput = 'php://output';
+
+    protected static $themes = [
+        'dark' => [
+            'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all',
+            'num' => 'font-weight:bold; color:#1299DA',
+            'const' => 'font-weight:bold',
+            'str' => 'font-weight:bold; color:#56DB3A',
+            'note' => 'color:#1299DA',
+            'ref' => 'color:#A0A0A0',
+            'public' => 'color:#FFFFFF',
+            'protected' => 'color:#FFFFFF',
+            'private' => 'color:#FFFFFF',
+            'meta' => 'color:#B729D9',
+            'key' => 'color:#56DB3A',
+            'index' => 'color:#1299DA',
+            'ellipsis' => 'color:#FF8400',
+            'ns' => 'user-select:none;',
+        ],
+        'light' => [
+            'default' => 'background:none; color:#CC7832; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all',
+            'num' => 'font-weight:bold; color:#1299DA',
+            'const' => 'font-weight:bold',
+            'str' => 'font-weight:bold; color:#629755;',
+            'note' => 'color:#6897BB',
+            'ref' => 'color:#6E6E6E',
+            'public' => 'color:#262626',
+            'protected' => 'color:#262626',
+            'private' => 'color:#262626',
+            'meta' => 'color:#B729D9',
+            'key' => 'color:#789339',
+            'index' => 'color:#1299DA',
+            'ellipsis' => 'color:#CC7832',
+            'ns' => 'user-select:none;',
+        ],
+    ];
+
+    protected $dumpHeader;
+    protected $dumpPrefix = '<pre class=sf-dump id=%s data-indent-pad="%s">';
+    protected $dumpSuffix = '</pre><script>Sfdump(%s)</script>';
+    protected $dumpId = 'sf-dump';
+    protected $colors = true;
+    protected $headerIsDumped = false;
+    protected $lastDepth = -1;
+    protected $styles;
+
+    private $displayOptions = [
+        'maxDepth' => 1,
+        'maxStringLength' => 160,
+        'fileLinkFormat' => null,
+    ];
+    private $extraDisplayOptions = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __construct($output = null, string $charset = null, int $flags = 0)
+    {
+        AbstractDumper::__construct($output, $charset, $flags);
+        $this->dumpId = 'sf-dump-'.mt_rand();
+        $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
+        $this->styles = static::$themes['dark'] ?? self::$themes['dark'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setStyles(array $styles)
+    {
+        $this->headerIsDumped = false;
+        $this->styles = $styles + $this->styles;
+    }
+
+    public function setTheme(string $themeName)
+    {
+        if (!isset(static::$themes[$themeName])) {
+            throw new \InvalidArgumentException(sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class));
+        }
+
+        $this->setStyles(static::$themes[$themeName]);
+    }
+
+    /**
+     * Configures display options.
+     *
+     * @param array $displayOptions A map of display options to customize the behavior
+     */
+    public function setDisplayOptions(array $displayOptions)
+    {
+        $this->headerIsDumped = false;
+        $this->displayOptions = $displayOptions + $this->displayOptions;
+    }
+
+    /**
+     * Sets an HTML header that will be dumped once in the output stream.
+     */
+    public function setDumpHeader(?string $header)
+    {
+        $this->dumpHeader = $header;
+    }
+
+    /**
+     * Sets an HTML prefix and suffix that will encapse every single dump.
+     */
+    public function setDumpBoundaries(string $prefix, string $suffix)
+    {
+        $this->dumpPrefix = $prefix;
+        $this->dumpSuffix = $suffix;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dump(Data $data, $output = null, array $extraDisplayOptions = [])
+    {
+        $this->extraDisplayOptions = $extraDisplayOptions;
+        $result = parent::dump($data, $output);
+        $this->dumpId = 'sf-dump-'.mt_rand();
+
+        return $result;
+    }
+
+    /**
+     * Dumps the HTML header.
+     */
+    protected function getDumpHeader()
+    {
+        $this->headerIsDumped = $this->outputStream ?? $this->lineDumper;
+
+        if (null !== $this->dumpHeader) {
+            return $this->dumpHeader;
+        }
+
+        $line = str_replace('{$options}', json_encode($this->displayOptions, \JSON_FORCE_OBJECT), <<<'EOHTML'
+<script>
+Sfdump = window.Sfdump || (function (doc) {
+
+var refStyle = doc.createElement('style'),
+    rxEsc = /([.*+?^${}()|\[\]\/\\])/g,
+    idRx = /\bsf-dump-\d+-ref[012]\w+\b/,
+    keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl',
+    addEventListener = function (e, n, cb) {
+        e.addEventListener(n, cb, false);
+    };
+
+refStyle.innerHTML = 'pre.sf-dump .sf-dump-compact, .sf-dump-str-collapse .sf-dump-str-collapse, .sf-dump-str-expand .sf-dump-str-expand { display: none; }';
+(doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle);
+refStyle = doc.createElement('style');
+(doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle);
+
+if (!doc.addEventListener) {
+    addEventListener = function (element, eventName, callback) {
+        element.attachEvent('on' + eventName, function (e) {
+            e.preventDefault = function () {e.returnValue = false;};
+            e.target = e.srcElement;
+            callback(e);
+        });
+    };
+}
+
+function toggle(a, recursive) {
+    var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass;
+
+    if (/\bsf-dump-compact\b/.test(oldClass)) {
+        arrow = '▼';
+        newClass = 'sf-dump-expanded';
+    } else if (/\bsf-dump-expanded\b/.test(oldClass)) {
+        arrow = '▶';
+        newClass = 'sf-dump-compact';
+    } else {
+        return false;
+    }
+
+    if (doc.createEvent && s.dispatchEvent) {
+        var event = doc.createEvent('Event');
+        event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false);
+
+        s.dispatchEvent(event);
+    }
+
+    a.lastChild.innerHTML = arrow;
+    s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass);
+
+    if (recursive) {
+        try {
+            a = s.querySelectorAll('.'+oldClass);
+            for (s = 0; s < a.length; ++s) {
+                if (-1 == a[s].className.indexOf(newClass)) {
+                    a[s].className = newClass;
+                    a[s].previousSibling.lastChild.innerHTML = arrow;
+                }
+            }
+        } catch (e) {
+        }
+    }
+
+    return true;
+};
+
+function collapse(a, recursive) {
+    var s = a.nextSibling || {}, oldClass = s.className;
+
+    if (/\bsf-dump-expanded\b/.test(oldClass)) {
+        toggle(a, recursive);
+
+        return true;
+    }
+
+    return false;
+};
+
+function expand(a, recursive) {
+    var s = a.nextSibling || {}, oldClass = s.className;
+
+    if (/\bsf-dump-compact\b/.test(oldClass)) {
+        toggle(a, recursive);
+
+        return true;
+    }
+
+    return false;
+};
+
+function collapseAll(root) {
+    var a = root.querySelector('a.sf-dump-toggle');
+    if (a) {
+        collapse(a, true);
+        expand(a);
+
+        return true;
+    }
+
+    return false;
+}
+
+function reveal(node) {
+    var previous, parents = [];
+
+    while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) {
+        parents.push(previous);
+    }
+
+    if (0 !== parents.length) {
+        parents.forEach(function (parent) {
+            expand(parent);
+        });
+
+        return true;
+    }
+
+    return false;
+}
+
+function highlight(root, activeNode, nodes) {
+    resetHighlightedNodes(root);
+
+    Array.from(nodes||[]).forEach(function (node) {
+        if (!/\bsf-dump-highlight\b/.test(node.className)) {
+            node.className = node.className + ' sf-dump-highlight';
+        }
+    });
+
+    if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) {
+        activeNode.className = activeNode.className + ' sf-dump-highlight-active';
+    }
+}
+
+function resetHighlightedNodes(root) {
+    Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) {
+        strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, '');
+        strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, '');
+    });
+}
+
+return function (root, x) {
+    root = doc.getElementById(root);
+
+    var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || '  ').replace(rxEsc, '\\$1')+')+', 'm'),
+        options = {$options},
+        elt = root.getElementsByTagName('A'),
+        len = elt.length,
+        i = 0, s, h,
+        t = [];
+
+    while (i < len) t.push(elt[i++]);
+
+    for (i in x) {
+        options[i] = x[i];
+    }
+
+    function a(e, f) {
+        addEventListener(root, e, function (e, n) {
+            if ('A' == e.target.tagName) {
+                f(e.target, e);
+            } else if ('A' == e.target.parentNode.tagName) {
+                f(e.target.parentNode, e);
+            } else {
+                n = /\bsf-dump-ellipsis\b/.test(e.target.className) ? e.target.parentNode : e.target;
+
+                if ((n = n.nextElementSibling) && 'A' == n.tagName) {
+                    if (!/\bsf-dump-toggle\b/.test(n.className)) {
+                        n = n.nextElementSibling || n;
+                    }
+
+                    f(n, e, true);
+                }
+            }
+        });
+    };
+    function isCtrlKey(e) {
+        return e.ctrlKey || e.metaKey;
+    }
+    function xpathString(str) {
+        var parts = str.match(/[^'"]+|['"]/g).map(function (part) {
+            if ("'" == part)  {
+                return '"\'"';
+            }
+            if ('"' == part) {
+                return "'\"'";
+            }
+
+            return "'" + part + "'";
+        });
+
+        return "concat(" + parts.join(",") + ", '')";
+    }
+    function xpathHasClass(className) {
+        return "contains(concat(' ', normalize-space(@class), ' '), ' " + className +" ')";
+    }
+    addEventListener(root, 'mouseover', function (e) {
+        if ('' != refStyle.innerHTML) {
+            refStyle.innerHTML = '';
+        }
+    });
+    a('mouseover', function (a, e, c) {
+        if (c) {
+            e.target.style.cursor = "pointer";
+        } else if (a = idRx.exec(a.className)) {
+            try {
+                refStyle.innerHTML = 'pre.sf-dump .'+a[0]+'{background-color: #B729D9; color: #FFF !important; border-radius: 2px}';
+            } catch (e) {
+            }
+        }
+    });
+    a('click', function (a, e, c) {
+        if (/\bsf-dump-toggle\b/.test(a.className)) {
+            e.preventDefault();
+            if (!toggle(a, isCtrlKey(e))) {
+                var r = doc.getElementById(a.getAttribute('href').substr(1)),
+                    s = r.previousSibling,
+                    f = r.parentNode,
+                    t = a.parentNode;
+                t.replaceChild(r, a);
+                f.replaceChild(a, s);
+                t.insertBefore(s, r);
+                f = f.firstChild.nodeValue.match(indentRx);
+                t = t.firstChild.nodeValue.match(indentRx);
+                if (f && t && f[0] !== t[0]) {
+                    r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]);
+                }
+                if (/\bsf-dump-compact\b/.test(r.className)) {
+                    toggle(s, isCtrlKey(e));
+                }
+            }
+
+            if (c) {
+            } else if (doc.getSelection) {
+                try {
+                    doc.getSelection().removeAllRanges();
+                } catch (e) {
+                    doc.getSelection().empty();
+                }
+            } else {
+                doc.selection.empty();
+            }
+        } else if (/\bsf-dump-str-toggle\b/.test(a.className)) {
+            e.preventDefault();
+            e = a.parentNode.parentNode;
+            e.className = e.className.replace(/\bsf-dump-str-(expand|collapse)\b/, a.parentNode.className);
+        }
+    });
+
+    elt = root.getElementsByTagName('SAMP');
+    len = elt.length;
+    i = 0;
+
+    while (i < len) t.push(elt[i++]);
+    len = t.length;
+
+    for (i = 0; i < len; ++i) {
+        elt = t[i];
+        if ('SAMP' == elt.tagName) {
+            a = elt.previousSibling || {};
+            if ('A' != a.tagName) {
+                a = doc.createElement('A');
+                a.className = 'sf-dump-ref';
+                elt.parentNode.insertBefore(a, elt);
+            } else {
+                a.innerHTML += ' ';
+            }
+            a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children';
+            a.innerHTML += elt.className == 'sf-dump-compact' ? '<span>▶</span>' : '<span>▼</span>';
+            a.className += ' sf-dump-toggle';
+
+            x = 1;
+            if ('sf-dump' != elt.parentNode.className) {
+                x += elt.parentNode.getAttribute('data-depth')/1;
+            }
+        } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) {
+            a = a.substr(1);
+            elt.className += ' '+a;
+
+            if (/[\[{]$/.test(elt.previousSibling.nodeValue)) {
+                a = a != elt.nextSibling.id && doc.getElementById(a);
+                try {
+                    s = a.nextSibling;
+                    elt.appendChild(a);
+                    s.parentNode.insertBefore(a, s);
+                    if (/^[@#]/.test(elt.innerHTML)) {
+                        elt.innerHTML += ' <span>▶</span>';
+                    } else {
+                        elt.innerHTML = '<span>▶</span>';
+                        elt.className = 'sf-dump-ref';
+                    }
+                    elt.className += ' sf-dump-toggle';
+                } catch (e) {
+                    if ('&' == elt.innerHTML.charAt(0)) {
+                        elt.innerHTML = '…';
+                        elt.className = 'sf-dump-ref';
+                    }
+                }
+            }
+        }
+    }
+
+    if (doc.evaluate && Array.from && root.children.length > 1) {
+        root.setAttribute('tabindex', 0);
+
+        SearchState = function () {
+            this.nodes = [];
+            this.idx = 0;
+        };
+        SearchState.prototype = {
+            next: function () {
+                if (this.isEmpty()) {
+                    return this.current();
+                }
+                this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0;
+
+                return this.current();
+            },
+            previous: function () {
+                if (this.isEmpty()) {
+                    return this.current();
+                }
+                this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1);
+
+                return this.current();
+            },
+            isEmpty: function () {
+                return 0 === this.count();
+            },
+            current: function () {
+                if (this.isEmpty()) {
+                    return null;
+                }
+                return this.nodes[this.idx];
+            },
+            reset: function () {
+                this.nodes = [];
+                this.idx = 0;
+            },
+            count: function () {
+                return this.nodes.length;
+            },
+        };
+
+        function showCurrent(state)
+        {
+            var currentNode = state.current(), currentRect, searchRect;
+            if (currentNode) {
+                reveal(currentNode);
+                highlight(root, currentNode, state.nodes);
+                if ('scrollIntoView' in currentNode) {
+                    currentNode.scrollIntoView(true);
+                    currentRect = currentNode.getBoundingClientRect();
+                    searchRect = search.getBoundingClientRect();
+                    if (currentRect.top < (searchRect.top + searchRect.height)) {
+                        window.scrollBy(0, -(searchRect.top + searchRect.height + 5));
+                    }
+                }
+            }
+            counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count();
+        }
+
+        var search = doc.createElement('div');
+        search.className = 'sf-dump-search-wrapper sf-dump-search-hidden';
+        search.innerHTML = '
+            <input type="text" class="sf-dump-search-input">
+            <span class="sf-dump-search-count">0 of 0<\/span>
+            <button type="button" class="sf-dump-search-input-previous" tabindex="-1">
+                <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1683 1331l-166 165q-19 19-45 19t-45-19L896 965l-531 531q-19 19-45 19t-45-19l-166-165q-19-19-19-45.5t19-45.5l742-741q19-19 45-19t45 19l742 741q19 19 19 45.5t-19 45.5z"\/><\/svg>
+            <\/button>
+            <button type="button" class="sf-dump-search-input-next" tabindex="-1">
+                <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1683 808l-742 741q-19 19-45 19t-45-19L109 808q-19-19-19-45.5t19-45.5l166-165q19-19 45-19t45 19l531 531 531-531q19-19 45-19t45 19l166 165q19 19 19 45.5t-19 45.5z"\/><\/svg>
+            <\/button>
+        ';
+        root.insertBefore(search, root.firstChild);
+
+        var state = new SearchState();
+        var searchInput = search.querySelector('.sf-dump-search-input');
+        var counter = search.querySelector('.sf-dump-search-count');
+        var searchInputTimer = 0;
+        var previousSearchQuery = '';
+
+        addEventListener(searchInput, 'keyup', function (e) {
+            var searchQuery = e.target.value;
+            /* Don't perform anything if the pressed key didn't change the query */
+            if (searchQuery === previousSearchQuery) {
+                return;
+            }
+            previousSearchQuery = searchQuery;
+            clearTimeout(searchInputTimer);
+            searchInputTimer = setTimeout(function () {
+                state.reset();
+                collapseAll(root);
+                resetHighlightedNodes(root);
+                if ('' === searchQuery) {
+                    counter.textContent = '0 of 0';
+
+                    return;
+                }
+
+                var classMatches = [
+                    "sf-dump-str",
+                    "sf-dump-key",
+                    "sf-dump-public",
+                    "sf-dump-protected",
+                    "sf-dump-private",
+                ].map(xpathHasClass).join(' or ');
+
+                var xpathResult = doc.evaluate('.//span[' + classMatches + '][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', root, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+
+                while (node = xpathResult.iterateNext()) state.nodes.push(node);
+
+                showCurrent(state);
+            }, 400);
+        });
+
+        Array.from(search.querySelectorAll('.sf-dump-search-input-next, .sf-dump-search-input-previous')).forEach(function (btn) {
+            addEventListener(btn, 'click', function (e) {
+                e.preventDefault();
+                -1 !== e.target.className.indexOf('next') ? state.next() : state.previous();
+                searchInput.focus();
+                collapseAll(root);
+                showCurrent(state);
+            })
+        });
+
+        addEventListener(root, 'keydown', function (e) {
+            var isSearchActive = !/\bsf-dump-search-hidden\b/.test(search.className);
+            if ((114 === e.keyCode && !isSearchActive) || (isCtrlKey(e) && 70 === e.keyCode)) {
+                /* F3 or CMD/CTRL + F */
+                if (70 === e.keyCode && document.activeElement === searchInput) {
+                   /*
+                    * If CMD/CTRL + F is hit while having focus on search input,
+                    * the user probably meant to trigger browser search instead.
+                    * Let the browser execute its behavior:
+                    */
+                    return;
+                }
+
+                e.preventDefault();
+                search.className = search.className.replace(/\bsf-dump-search-hidden\b/, '');
+                searchInput.focus();
+            } else if (isSearchActive) {
+                if (27 === e.keyCode) {
+                    /* ESC key */
+                    search.className += ' sf-dump-search-hidden';
+                    e.preventDefault();
+                    resetHighlightedNodes(root);
+                    searchInput.value = '';
+                } else if (
+                    (isCtrlKey(e) && 71 === e.keyCode) /* CMD/CTRL + G */
+                    || 13 === e.keyCode /* Enter */
+                    || 114 === e.keyCode /* F3 */
+                ) {
+                    e.preventDefault();
+                    e.shiftKey ? state.previous() : state.next();
+                    collapseAll(root);
+                    showCurrent(state);
+                }
+            }
+        });
+    }
+
+    if (0 >= options.maxStringLength) {
+        return;
+    }
+    try {
+        elt = root.querySelectorAll('.sf-dump-str');
+        len = elt.length;
+        i = 0;
+        t = [];
+
+        while (i < len) t.push(elt[i++]);
+        len = t.length;
+
+        for (i = 0; i < len; ++i) {
+            elt = t[i];
+            s = elt.innerText || elt.textContent;
+            x = s.length - options.maxStringLength;
+            if (0 < x) {
+                h = elt.innerHTML;
+                elt[elt.innerText ? 'innerText' : 'textContent'] = s.substring(0, options.maxStringLength);
+                elt.className += ' sf-dump-str-collapse';
+                elt.innerHTML = '<span class=sf-dump-str-collapse>'+h+'<a class="sf-dump-ref sf-dump-str-toggle" title="Collapse"> ◀</a></span>'+
+                    '<span class=sf-dump-str-expand>'+elt.innerHTML+'<a class="sf-dump-ref sf-dump-str-toggle" title="'+x+' remaining characters"> ▶</a></span>';
+            }
+        }
+    } catch (e) {
+    }
+};
+
+})(document);
+</script><style>
+pre.sf-dump {
+    display: block;
+    white-space: pre;
+    padding: 5px;
+    overflow: initial !important;
+}
+pre.sf-dump:after {
+   content: "";
+   visibility: hidden;
+   display: block;
+   height: 0;
+   clear: both;
+}
+pre.sf-dump span {
+    display: inline;
+}
+pre.sf-dump a {
+    text-decoration: none;
+    cursor: pointer;
+    border: 0;
+    outline: none;
+    color: inherit;
+}
+pre.sf-dump img {
+    max-width: 50em;
+    max-height: 50em;
+    margin: .5em 0 0 0;
+    padding: 0;
+    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAHUlEQVQY02O8zAABilCaiQEN0EeA8QuUcX9g3QEAAjcC5piyhyEAAAAASUVORK5CYII=) #D3D3D3;
+}
+pre.sf-dump .sf-dump-ellipsis {
+    display: inline-block;
+    overflow: visible;
+    text-overflow: ellipsis;
+    max-width: 5em;
+    white-space: nowrap;
+    overflow: hidden;
+    vertical-align: top;
+}
+pre.sf-dump .sf-dump-ellipsis+.sf-dump-ellipsis {
+    max-width: none;
+}
+pre.sf-dump code {
+    display:inline;
+    padding:0;
+    background:none;
+}
+.sf-dump-public.sf-dump-highlight,
+.sf-dump-protected.sf-dump-highlight,
+.sf-dump-private.sf-dump-highlight,
+.sf-dump-str.sf-dump-highlight,
+.sf-dump-key.sf-dump-highlight {
+    background: rgba(111, 172, 204, 0.3);
+    border: 1px solid #7DA0B1;
+    border-radius: 3px;
+}
+.sf-dump-public.sf-dump-highlight-active,
+.sf-dump-protected.sf-dump-highlight-active,
+.sf-dump-private.sf-dump-highlight-active,
+.sf-dump-str.sf-dump-highlight-active,
+.sf-dump-key.sf-dump-highlight-active {
+    background: rgba(253, 175, 0, 0.4);
+    border: 1px solid #ffa500;
+    border-radius: 3px;
+}
+pre.sf-dump .sf-dump-search-hidden {
+    display: none !important;
+}
+pre.sf-dump .sf-dump-search-wrapper {
+    font-size: 0;
+    white-space: nowrap;
+    margin-bottom: 5px;
+    display: flex;
+    position: -webkit-sticky;
+    position: sticky;
+    top: 5px;
+}
+pre.sf-dump .sf-dump-search-wrapper > * {
+    vertical-align: top;
+    box-sizing: border-box;
+    height: 21px;
+    font-weight: normal;
+    border-radius: 0;
+    background: #FFF;
+    color: #757575;
+    border: 1px solid #BBB;
+}
+pre.sf-dump .sf-dump-search-wrapper > input.sf-dump-search-input {
+    padding: 3px;
+    height: 21px;
+    font-size: 12px;
+    border-right: none;
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+    color: #000;
+    min-width: 15px;
+    width: 100%;
+}
+pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next,
+pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous {
+    background: #F2F2F2;
+    outline: none;
+    border-left: none;
+    font-size: 0;
+    line-height: 0;
+}
+pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next {
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+}
+pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next > svg,
+pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous > svg {
+    pointer-events: none;
+    width: 12px;
+    height: 12px;
+}
+pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-count {
+    display: inline-block;
+    padding: 0 5px;
+    margin: 0;
+    border-left: none;
+    line-height: 21px;
+    font-size: 12px;
+}
+EOHTML
+        );
+
+        foreach ($this->styles as $class => $style) {
+            $line .= 'pre.sf-dump'.('default' === $class ? ', pre.sf-dump' : '').' .sf-dump-'.$class.'{'.$style.'}';
+        }
+        $line .= 'pre.sf-dump .sf-dump-ellipsis-note{'.$this->styles['note'].'}';
+
+        return $this->dumpHeader = preg_replace('/\s+/', ' ', $line).'</style>'.$this->dumpHeader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut)
+    {
+        if ('' === $str && isset($cursor->attr['img-data'], $cursor->attr['content-type'])) {
+            $this->dumpKey($cursor);
+            $this->line .= $this->style('default', $cursor->attr['img-size'] ?? '', []);
+            $this->line .= $cursor->depth >= $this->displayOptions['maxDepth'] ? ' <samp class=sf-dump-compact>' : ' <samp class=sf-dump-expanded>';
+            $this->endValue($cursor);
+            $this->line .= $this->indentPad;
+            $this->line .= sprintf('<img src="data:%s;base64,%s" /></samp>', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data']));
+            $this->endValue($cursor);
+        } else {
+            parent::dumpString($cursor, $str, $bin, $cut);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild)
+    {
+        if (Cursor::HASH_OBJECT === $type) {
+            $cursor->attr['depth'] = $cursor->depth;
+        }
+        parent::enterHash($cursor, $type, $class, false);
+
+        if ($cursor->skipChildren || $cursor->depth >= $this->displayOptions['maxDepth']) {
+            $cursor->skipChildren = false;
+            $eol = ' class=sf-dump-compact>';
+        } else {
+            $this->expandNextHash = false;
+            $eol = ' class=sf-dump-expanded>';
+        }
+
+        if ($hasChild) {
+            $this->line .= '<samp data-depth='.($cursor->depth + 1);
+            if ($cursor->refIndex) {
+                $r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2;
+                $r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex;
+
+                $this->line .= sprintf(' id=%s-ref%s', $this->dumpId, $r);
+            }
+            $this->line .= $eol;
+            $this->dumpLine($cursor->depth);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut)
+    {
+        $this->dumpEllipsis($cursor, $hasChild, $cut);
+        if ($hasChild) {
+            $this->line .= '</samp>';
+        }
+        parent::leaveHash($cursor, $type, $class, $hasChild, 0);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function style(string $style, string $value, array $attr = [])
+    {
+        if ('' === $value) {
+            return '';
+        }
+
+        $v = esc($value);
+
+        if ('ref' === $style) {
+            if (empty($attr['count'])) {
+                return sprintf('<a class=sf-dump-ref>%s</a>', $v);
+            }
+            $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1);
+
+            return sprintf('<a class=sf-dump-ref href=#%s-ref%s title="%d occurrences">%s</a>', $this->dumpId, $r, 1 + $attr['count'], $v);
+        }
+
+        if ('const' === $style && isset($attr['value'])) {
+            $style .= sprintf(' title="%s"', esc(is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
+        } elseif ('public' === $style) {
+            $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
+        } elseif ('str' === $style && 1 < $attr['length']) {
+            $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
+        } elseif ('note' === $style && 0 < ($attr['depth'] ?? 0) && false !== $c = strrpos($value, '\\')) {
+            $style .= ' title=""';
+            $attr += [
+                'ellipsis' => \strlen($value) - $c,
+                'ellipsis-type' => 'note',
+                'ellipsis-tail' => 1,
+            ];
+        } elseif ('protected' === $style) {
+            $style .= ' title="Protected property"';
+        } elseif ('meta' === $style && isset($attr['title'])) {
+            $style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title'])));
+        } elseif ('private' === $style) {
+            $style .= sprintf(' title="Private property defined in class:&#10;`%s`"', esc($this->utf8Encode($attr['class'])));
+        }
+        $map = static::$controlCharsMap;
+
+        if (isset($attr['ellipsis'])) {
+            $class = 'sf-dump-ellipsis';
+            if (isset($attr['ellipsis-type'])) {
+                $class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']);
+            }
+            $label = esc(substr($value, -$attr['ellipsis']));
+            $style = str_replace(' title="', " title=\"$v\n", $style);
+            $v = sprintf('<span class=%s>%s</span>', $class, substr($v, 0, -\strlen($label)));
+
+            if (!empty($attr['ellipsis-tail'])) {
+                $tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail'])));
+                $v .= sprintf('<span class=%s>%s</span>%s', $class, substr($label, 0, $tail), substr($label, $tail));
+            } else {
+                $v .= $label;
+            }
+        }
+
+        $v = "<span class=sf-dump-{$style}>".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) {
+            $s = $b = '<span class="sf-dump-default';
+            $c = $c[$i = 0];
+            if ($ns = "\r" === $c[$i] || "\n" === $c[$i]) {
+                $s .= ' sf-dump-ns';
+            }
+            $s .= '">';
+            do {
+                if (("\r" === $c[$i] || "\n" === $c[$i]) !== $ns) {
+                    $s .= '</span>'.$b;
+                    if ($ns = !$ns) {
+                        $s .= ' sf-dump-ns';
+                    }
+                    $s .= '">';
+                }
+
+                $s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
+            } while (isset($c[++$i]));
+
+            return $s.'</span>';
+        }, $v).'</span>';
+
+        if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) {
+            $attr['href'] = $href;
+        }
+        if (isset($attr['href'])) {
+            $target = isset($attr['file']) ? '' : ' target="_blank"';
+            $v = sprintf('<a href="%s"%s rel="noopener noreferrer">%s</a>', esc($this->utf8Encode($attr['href'])), $target, $v);
+        }
+        if (isset($attr['lang'])) {
+            $v = sprintf('<code class="%s">%s</code>', esc($attr['lang']), $v);
+        }
+
+        return $v;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function dumpLine(int $depth, bool $endOfValue = false)
+    {
+        if (-1 === $this->lastDepth) {
+            $this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
+        }
+        if ($this->headerIsDumped !== ($this->outputStream ?? $this->lineDumper)) {
+            $this->line = $this->getDumpHeader().$this->line;
+        }
+
+        if (-1 === $depth) {
+            $args = ['"'.$this->dumpId.'"'];
+            if ($this->extraDisplayOptions) {
+                $args[] = json_encode($this->extraDisplayOptions, \JSON_FORCE_OBJECT);
+            }
+            // Replace is for BC
+            $this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
+        }
+        $this->lastDepth = $depth;
+
+        $this->line = mb_convert_encoding($this->line, 'HTML-ENTITIES', 'UTF-8');
+
+        if (-1 === $depth) {
+            AbstractDumper::dumpLine(0);
+        }
+        AbstractDumper::dumpLine($depth);
+    }
+
+    private function getSourceLink(string $file, int $line)
+    {
+        $options = $this->extraDisplayOptions + $this->displayOptions;
+
+        if ($fmt = $options['fileLinkFormat']) {
+            return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line);
+        }
+
+        return false;
+    }
+}
+
+function esc(string $str)
+{
+    return htmlspecialchars($str, \ENT_QUOTES, 'UTF-8');
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ServerDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ServerDumper.php
new file mode 100644
index 0000000..94795bf
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ServerDumper.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
+use Symfony\Component\VarDumper\Server\Connection;
+
+/**
+ * ServerDumper forwards serialized Data clones to a server.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+class ServerDumper implements DataDumperInterface
+{
+    private $connection;
+    private $wrappedDumper;
+
+    /**
+     * @param string                     $host             The server host
+     * @param DataDumperInterface|null   $wrappedDumper    A wrapped instance used whenever we failed contacting the server
+     * @param ContextProviderInterface[] $contextProviders Context providers indexed by context name
+     */
+    public function __construct(string $host, DataDumperInterface $wrappedDumper = null, array $contextProviders = [])
+    {
+        $this->connection = new Connection($host, $contextProviders);
+        $this->wrappedDumper = $wrappedDumper;
+    }
+
+    public function getContextProviders(): array
+    {
+        return $this->connection->getContextProviders();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dump(Data $data)
+    {
+        if (!$this->connection->write($data) && $this->wrappedDumper) {
+            $this->wrappedDumper->dump($data);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php
new file mode 100644
index 0000000..122f0d3
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Exception;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ThrowingCasterException extends \Exception
+{
+    /**
+     * @param \Throwable $prev The exception thrown from the caster
+     */
+    public function __construct(\Throwable $prev)
+    {
+        parent::__construct('Unexpected '.\get_class($prev).' thrown from a caster: '.$prev->getMessage(), 0, $prev);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/LICENSE
new file mode 100644
index 0000000..c1f0aac
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014-2021 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/README.md
new file mode 100644
index 0000000..bdac244
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/README.md
@@ -0,0 +1,15 @@
+VarDumper Component
+===================
+
+The VarDumper component provides mechanisms for walking through any arbitrary
+PHP variable. It provides a better `dump()` function that you can use instead
+of `var_dump`.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/var_dumper/introduction.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+   [send Pull Requests](https://github.com/symfony/symfony/pulls)
+   in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/bin/var-dump-server b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/bin/var-dump-server
new file mode 100755
index 0000000..98c813a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/bin/var-dump-server
@@ -0,0 +1,63 @@
+#!/usr/bin/env php
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Starts a dump server to collect and output dumps on a single place with multiple formats support.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Logger\ConsoleLogger;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\VarDumper\Command\ServerDumpCommand;
+use Symfony\Component\VarDumper\Server\DumpServer;
+
+function includeIfExists(string $file): bool
+{
+    return file_exists($file) && include $file;
+}
+
+if (
+    !includeIfExists(__DIR__ . '/../../../../autoload.php') &&
+    !includeIfExists(__DIR__ . '/../../vendor/autoload.php') &&
+    !includeIfExists(__DIR__ . '/../../../../../../vendor/autoload.php')
+) {
+    fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL);
+    exit(1);
+}
+
+if (!class_exists(Application::class)) {
+    fwrite(STDERR, 'You need the "symfony/console" component in order to run the VarDumper server.'.PHP_EOL);
+    exit(1);
+}
+
+$input = new ArgvInput();
+$output = new ConsoleOutput();
+$defaultHost = '127.0.0.1:9912';
+$host = $input->getParameterOption(['--host'], $_SERVER['VAR_DUMPER_SERVER'] ?? $defaultHost, true);
+$logger = interface_exists(LoggerInterface::class) ? new ConsoleLogger($output->getErrorOutput()) : null;
+
+$app = new Application();
+
+$app->getDefinition()->addOption(
+    new InputOption('--host', null, InputOption::VALUE_REQUIRED, 'The address the server should listen to', $defaultHost)
+);
+
+$app->add($command = new ServerDumpCommand(new DumpServer($host, $logger)))
+    ->getApplication()
+    ->setDefaultCommand($command->getName(), true)
+    ->run($input, $output)
+;
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css
new file mode 100644
index 0000000..8f706d6
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css
@@ -0,0 +1,130 @@
+body {
+    display: flex;
+    flex-direction: column-reverse;
+    justify-content: flex-end;
+    max-width: 1140px;
+    margin: auto;
+    padding: 15px;
+    word-wrap: break-word;
+    background-color: #F9F9F9;
+    color: #222;
+    font-family: Helvetica, Arial, sans-serif;
+    font-size: 14px;
+    line-height: 1.4;
+}
+p {
+    margin: 0;
+}
+a {
+    color: #218BC3;
+    text-decoration: none;
+}
+a:hover {
+    text-decoration: underline;
+}
+.text-small {
+    font-size: 12px !important;
+}
+article {
+    margin: 5px;
+    margin-bottom: 10px;
+}
+article > header > .row {
+    display: flex;
+    flex-direction: row;
+    align-items: baseline;
+    margin-bottom: 10px;
+}
+article > header > .row > .col {
+    flex: 1;
+    display: flex;
+    align-items: baseline;
+}
+article > header > .row > h2 {
+    font-size: 14px;
+    color: #222;
+    font-weight: normal;
+    font-family: "Lucida Console", monospace, sans-serif;
+    word-break: break-all;
+    margin: 20px 5px 0 0;
+    user-select: all;
+}
+article > header > .row > h2 > code {
+    white-space: nowrap;
+    user-select: none;
+    color: #cc2255;
+    background-color: #f7f7f9;
+    border: 1px solid #e1e1e8;
+    border-radius: 3px;
+    margin-right: 5px;
+    padding: 0 3px;
+}
+article > header > .row > time.col {
+    flex: 0;
+    text-align: right;
+    white-space: nowrap;
+    color: #999;
+    font-style: italic;
+}
+article > header ul.tags {
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    font-size: 12px;
+}
+article > header ul.tags > li {
+    user-select: all;
+    margin-bottom: 2px;
+}
+article > header ul.tags > li > span.badge {
+    display: inline-block;
+    padding: .25em .4em;
+    margin-right: 5px;
+    border-radius: 4px;
+    background-color: #6c757d3b;
+    color: #524d4d;
+    font-size: 12px;
+    text-align: center;
+    font-weight: 700;
+    line-height: 1;
+    white-space: nowrap;
+    vertical-align: baseline;
+    user-select: none;
+}
+article > section.body {
+    border: 1px solid #d8d8d8;
+    background: #FFF;
+    padding: 10px;
+    border-radius: 3px;
+}
+pre.sf-dump {
+    border-radius: 3px;
+    margin-bottom: 0;
+}
+.hidden {
+    display: none !important;
+}
+.dumped-tag > .sf-dump {
+    display: inline-block;
+    margin: 0;
+    padding: 1px 5px;
+    line-height: 1.4;
+    vertical-align: top;
+    background-color: transparent;
+    user-select: auto;
+}
+.dumped-tag > pre.sf-dump,
+.dumped-tag > .sf-dump-default {
+    color: #CC7832;
+    background: none;
+}
+.dumped-tag > .sf-dump .sf-dump-str { color: #629755; }
+.dumped-tag > .sf-dump .sf-dump-private,
+.dumped-tag > .sf-dump .sf-dump-protected,
+.dumped-tag > .sf-dump .sf-dump-public { color: #262626; }
+.dumped-tag > .sf-dump .sf-dump-note { color: #6897BB; }
+.dumped-tag > .sf-dump .sf-dump-key { color: #789339; }
+.dumped-tag > .sf-dump .sf-dump-ref { color: #6E6E6E; }
+.dumped-tag > .sf-dump .sf-dump-ellipsis { color: #CC7832; max-width: 100em; }
+.dumped-tag > .sf-dump .sf-dump-ellipsis-path { max-width: 5em; }
+.dumped-tag > .sf-dump .sf-dump-ns { user-select: none; }
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/functions/dump.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/functions/dump.php
new file mode 100644
index 0000000..a485d57
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/functions/dump.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Component\VarDumper\VarDumper;
+
+if (!function_exists('dump')) {
+    /**
+     * @author Nicolas Grekas <p@tchwork.com>
+     */
+    function dump($var, ...$moreVars)
+    {
+        VarDumper::dump($var);
+
+        foreach ($moreVars as $v) {
+            VarDumper::dump($v);
+        }
+
+        if (1 < func_num_args()) {
+            return func_get_args();
+        }
+
+        return $var;
+    }
+}
+
+if (!function_exists('dd')) {
+    function dd(...$vars)
+    {
+        foreach ($vars as $v) {
+            VarDumper::dump($v);
+        }
+
+        exit(1);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js
new file mode 100644
index 0000000..63101e5
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js
@@ -0,0 +1,10 @@
+document.addEventListener('DOMContentLoaded', function() {
+  let prev = null;
+  Array.from(document.getElementsByTagName('article')).reverse().forEach(function (article) {
+    const dedupId = article.dataset.dedupId;
+    if (dedupId === prev) {
+      article.getElementsByTagName('header')[0].classList.add('hidden');
+    }
+    prev = dedupId;
+  });
+});
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Server/Connection.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Server/Connection.php
new file mode 100644
index 0000000..55d9214
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Server/Connection.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Server;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
+
+/**
+ * Forwards serialized Data clones to a server.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ */
+class Connection
+{
+    private $host;
+    private $contextProviders;
+    private $socket;
+
+    /**
+     * @param string                     $host             The server host
+     * @param ContextProviderInterface[] $contextProviders Context providers indexed by context name
+     */
+    public function __construct(string $host, array $contextProviders = [])
+    {
+        if (!str_contains($host, '://')) {
+            $host = 'tcp://'.$host;
+        }
+
+        $this->host = $host;
+        $this->contextProviders = $contextProviders;
+    }
+
+    public function getContextProviders(): array
+    {
+        return $this->contextProviders;
+    }
+
+    public function write(Data $data): bool
+    {
+        $socketIsFresh = !$this->socket;
+        if (!$this->socket = $this->socket ?: $this->createSocket()) {
+            return false;
+        }
+
+        $context = ['timestamp' => microtime(true)];
+        foreach ($this->contextProviders as $name => $provider) {
+            $context[$name] = $provider->getContext();
+        }
+        $context = array_filter($context);
+        $encodedPayload = base64_encode(serialize([$data, $context]))."\n";
+
+        set_error_handler([self::class, 'nullErrorHandler']);
+        try {
+            if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) {
+                return true;
+            }
+            if (!$socketIsFresh) {
+                stream_socket_shutdown($this->socket, \STREAM_SHUT_RDWR);
+                fclose($this->socket);
+                $this->socket = $this->createSocket();
+            }
+            if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) {
+                return true;
+            }
+        } finally {
+            restore_error_handler();
+        }
+
+        return false;
+    }
+
+    private static function nullErrorHandler(int $t, string $m)
+    {
+        // no-op
+    }
+
+    private function createSocket()
+    {
+        set_error_handler([self::class, 'nullErrorHandler']);
+        try {
+            return stream_socket_client($this->host, $errno, $errstr, 3, \STREAM_CLIENT_CONNECT | \STREAM_CLIENT_ASYNC_CONNECT);
+        } finally {
+            restore_error_handler();
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Server/DumpServer.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Server/DumpServer.php
new file mode 100644
index 0000000..7cb5bf0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Server/DumpServer.php
@@ -0,0 +1,111 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Server;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * A server collecting Data clones sent by a ServerDumper.
+ *
+ * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
+ *
+ * @final
+ */
+class DumpServer
+{
+    private $host;
+    private $socket;
+    private $logger;
+
+    public function __construct(string $host, LoggerInterface $logger = null)
+    {
+        if (!str_contains($host, '://')) {
+            $host = 'tcp://'.$host;
+        }
+
+        $this->host = $host;
+        $this->logger = $logger;
+    }
+
+    public function start(): void
+    {
+        if (!$this->socket = stream_socket_server($this->host, $errno, $errstr)) {
+            throw new \RuntimeException(sprintf('Server start failed on "%s": ', $this->host).$errstr.' '.$errno);
+        }
+    }
+
+    public function listen(callable $callback): void
+    {
+        if (null === $this->socket) {
+            $this->start();
+        }
+
+        foreach ($this->getMessages() as $clientId => $message) {
+            if ($this->logger) {
+                $this->logger->info('Received a payload from client {clientId}', ['clientId' => $clientId]);
+            }
+
+            $payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]);
+
+            // Impossible to decode the message, give up.
+            if (false === $payload) {
+                if ($this->logger) {
+                    $this->logger->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]);
+                }
+
+                continue;
+            }
+
+            if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) {
+                if ($this->logger) {
+                    $this->logger->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]);
+                }
+
+                continue;
+            }
+
+            [$data, $context] = $payload;
+
+            $callback($data, $context, $clientId);
+        }
+    }
+
+    public function getHost(): string
+    {
+        return $this->host;
+    }
+
+    private function getMessages(): iterable
+    {
+        $sockets = [(int) $this->socket => $this->socket];
+        $write = [];
+
+        while (true) {
+            $read = $sockets;
+            stream_select($read, $write, $write, null);
+
+            foreach ($read as $stream) {
+                if ($this->socket === $stream) {
+                    $stream = stream_socket_accept($this->socket);
+                    $sockets[(int) $stream] = $stream;
+                } elseif (feof($stream)) {
+                    unset($sockets[(int) $stream]);
+                    fclose($stream);
+                } else {
+                    yield (int) $stream => fgets($stream);
+                }
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php
new file mode 100644
index 0000000..33d60c0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Test;
+
+use Symfony\Component\VarDumper\Cloner\VarCloner;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+trait VarDumperTestTrait
+{
+    /**
+     * @internal
+     */
+    private $varDumperConfig = [
+        'casters' => [],
+        'flags' => null,
+    ];
+
+    protected function setUpVarDumper(array $casters, int $flags = null): void
+    {
+        $this->varDumperConfig['casters'] = $casters;
+        $this->varDumperConfig['flags'] = $flags;
+    }
+
+    /**
+     * @after
+     */
+    protected function tearDownVarDumper(): void
+    {
+        $this->varDumperConfig['casters'] = [];
+        $this->varDumperConfig['flags'] = null;
+    }
+
+    public function assertDumpEquals($expected, $data, int $filter = 0, string $message = '')
+    {
+        $this->assertSame($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message);
+    }
+
+    public function assertDumpMatchesFormat($expected, $data, int $filter = 0, string $message = '')
+    {
+        $this->assertStringMatchesFormat($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message);
+    }
+
+    protected function getDump($data, $key = null, int $filter = 0): ?string
+    {
+        if (null === $flags = $this->varDumperConfig['flags']) {
+            $flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0;
+            $flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0;
+            $flags |= getenv('DUMP_COMMA_SEPARATOR') ? CliDumper::DUMP_COMMA_SEPARATOR : 0;
+        }
+
+        $cloner = new VarCloner();
+        $cloner->addCasters($this->varDumperConfig['casters']);
+        $cloner->setMaxItems(-1);
+        $dumper = new CliDumper(null, null, $flags);
+        $dumper->setColors(false);
+        $data = $cloner->cloneVar($data, $filter)->withRefHandles(false);
+        if (null !== $key && null === $data = $data->seek($key)) {
+            return null;
+        }
+
+        return rtrim($dumper->dump($data, true));
+    }
+
+    private function prepareExpectation($expected, int $filter): string
+    {
+        if (!\is_string($expected)) {
+            $expected = $this->getDump($expected, null, $filter);
+        }
+
+        return rtrim($expected);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/VarDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/VarDumper.php
new file mode 100644
index 0000000..b223e06
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/VarDumper.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
+use Symfony\Component\VarDumper\Caster\ReflectionCaster;
+use Symfony\Component\VarDumper\Cloner\VarCloner;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\RequestContextProvider;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
+use Symfony\Component\VarDumper\Dumper\ContextualizedDumper;
+use Symfony\Component\VarDumper\Dumper\HtmlDumper;
+use Symfony\Component\VarDumper\Dumper\ServerDumper;
+
+// Load the global dump() function
+require_once __DIR__.'/Resources/functions/dump.php';
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class VarDumper
+{
+    private static $handler;
+
+    public static function dump($var)
+    {
+        if (null === self::$handler) {
+            self::register();
+        }
+
+        return (self::$handler)($var);
+    }
+
+    public static function setHandler(callable $callable = null)
+    {
+        $prevHandler = self::$handler;
+
+        // Prevent replacing the handler with expected format as soon as the env var was set:
+        if (isset($_SERVER['VAR_DUMPER_FORMAT'])) {
+            return $prevHandler;
+        }
+
+        self::$handler = $callable;
+
+        return $prevHandler;
+    }
+
+    private static function register(): void
+    {
+        $cloner = new VarCloner();
+        $cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);
+
+        $format = $_SERVER['VAR_DUMPER_FORMAT'] ?? null;
+        switch (true) {
+            case 'html' === $format:
+                $dumper = new HtmlDumper();
+                break;
+            case 'cli' === $format:
+                $dumper = new CliDumper();
+                break;
+            case 'server' === $format:
+            case $format && 'tcp' === parse_url($format, \PHP_URL_SCHEME):
+                $host = 'server' === $format ? $_SERVER['VAR_DUMPER_SERVER'] ?? '127.0.0.1:9912' : $format;
+                $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? new CliDumper() : new HtmlDumper();
+                $dumper = new ServerDumper($host, $dumper, self::getDefaultContextProviders());
+                break;
+            default:
+                $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? new CliDumper() : new HtmlDumper();
+        }
+
+        if (!$dumper instanceof ServerDumper) {
+            $dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]);
+        }
+
+        self::$handler = function ($var) use ($cloner, $dumper) {
+            $dumper->dump($cloner->cloneVar($var));
+        };
+    }
+
+    private static function getDefaultContextProviders(): array
+    {
+        $contextProviders = [];
+
+        if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && (class_exists(Request::class))) {
+            $requestStack = new RequestStack();
+            $requestStack->push(Request::createFromGlobals());
+            $contextProviders['request'] = new RequestContextProvider($requestStack);
+        }
+
+        $fileLinkFormatter = class_exists(FileLinkFormatter::class) ? new FileLinkFormatter(null, $requestStack ?? null) : null;
+
+        return $contextProviders + [
+            'cli' => new CliContextProvider(),
+            'source' => new SourceContextProvider(null, null, $fileLinkFormatter),
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/composer.json
new file mode 100644
index 0000000..2d4889d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/var-dumper/composer.json
@@ -0,0 +1,49 @@
+{
+    "name": "symfony/var-dumper",
+    "type": "library",
+    "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+    "keywords": ["dump", "debug"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.2.5",
+        "symfony/polyfill-mbstring": "~1.0",
+        "symfony/polyfill-php80": "^1.16"
+    },
+    "require-dev": {
+        "ext-iconv": "*",
+        "symfony/console": "^4.4|^5.0",
+        "symfony/process": "^4.4|^5.0",
+        "twig/twig": "^2.13|^3.0.4"
+    },
+    "conflict": {
+        "phpunit/phpunit": "<5.4.3",
+        "symfony/console": "<4.4"
+    },
+    "suggest": {
+        "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+        "ext-intl": "To show region name in time zone dump",
+        "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+    },
+    "autoload": {
+        "files": [ "Resources/functions/dump.php" ],
+        "psr-4": { "Symfony\\Component\\VarDumper\\": "" },
+        "exclude-from-classmap": [
+            "/Tests/"
+        ]
+    },
+    "bin": [
+        "Resources/bin/var-dump-server"
+    ],
+    "minimum-stability": "dev"
+}